3
* Copyright (c) 2008 Zivios, LLC.
5
* This file is part of Zivios.
7
* Zivios is free software: you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation, either version 3 of the License, or
10
* (at your option) any later version.
12
* Zivios is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with Zivios. If not, see <http://www.gnu.org/licenses/>.
21
* @copyright Copyright (c) 2008 Zivios, LLC. (http://www.zivios.org)
22
* @license http://www.zivios.org/legal/license
23
* @version $Id: Block.php 908 2008-08-25 11:03:00Z fkhan $
28
class Ecl_Parser_Block extends Ecl_Parser_Element
35
public function __construct(Ecl_Parser_DTD $dtd)
37
parent::__construct($dtd);
38
$this->elements = array();
43
public function getElements()
45
return $this->elements;
48
public function getElement($name)
50
return $this->elements[$name];
53
public function removeElement($name)
55
array_splice($this->elements,$name,1);
58
public function setMainBlock()
61
$this->name = "MAINBLOCK";
64
public function addParameter($name,$value) {
65
$parameter = new Ecl_Parser_Parameter($this->dtd);
66
$parameter->setId($name);
67
$parameter->setValue($value);
68
$this->elements[$parameter->name] = $parameter;
72
public function addPlugin(Ecl_Parser_Element $element) {
73
$this->elements[get_class($element)] = $element;
76
public function delete(Ecl_Parser_Element $element) {
77
if ($element instanceof Ecl_Parser_Parameter ) {
78
$indextodelete = $element->name;
79
// delete from array directly
81
$indextodelete = get_class($element);
82
// element is a plugin, delete the correct index
84
// TODO: Actual deletion!!!.
87
public function isBlockStart($string)
89
$string = trim($string);
90
Ecl_Log::debug("Searching for block at line : $string*");
92
$blockstart = $this->dtd->blockdstart;
93
$blockend = $this->dtd->blockdend;
94
$scopestart = $this->dtd->blockscopestart;
95
if (($blockstart != "") && ($scopestart != "")) {
96
$match = preg_match("/^\$blockstart+[a-z0-9._-]+\$blockend\s+$scopestart/",$string);
98
Ecl_Log::debug("Block found at $string");
101
} else if (($blockstart != "")) {
102
Ecl_Log::debug("Only blockstart available... using");
103
$match = preg_match("/^$blockstart+[a-z0-9._-]+$blockend/",$string);
105
Ecl_Log::debug("Block found at $string");
110
Ecl_Log::debug("Null blockstart, going for scope start");
111
$match = preg_match("/^\w+\s+$scopestart/",$string);
113
Ecl_Log::debug("Block found at $string");
119
public function getName()
124
public function isBlockEnd($string)
126
/** two ways this is a end block are :
127
* 1. another block starts
128
* 2. Scope terminator encountered
130
$scopeend = $this->dtd->blockscopeend;
131
$newblock = $this->isBlockStart($string);
134
} else if ($scopeend != "") {
135
$match = preg_match("/^$scopeend$/",trim($string));
137
Ecl_Log::debug("Block ended at $string");
146
public function seekBlockStart(&$filepointer)
148
/** Block seeking may have two modes, in mode 1
149
* if the block delimiter is defined it should seek [block]
150
* otherwise it should try seeking block { }.
151
* However the { can be on a different line. Hence it must try to seek
153
* Cool regex match can find the [block] using a single command.
156
if ($this->dtd->singleblock) {
163
public function isParameter($string) {
164
$string=trim($string);
165
$override = $this->dtd->paramoverride;
166
if ($override != null) {
167
Ecl_Log::debug("override plugin $override called");
168
$plugin = new $override($this->dtd);
169
return $plugin->canParse($string);
171
$equal = $this->dtd->equalsign;
172
$match = preg_match("/$equal/",$string);
174
Ecl_Log::debug ("$string contains a Parameter");
179
public function isComment($string) {
180
$string = trim($string);
181
$comment = $this->dtd->comment;
182
$match = preg_match("/^$comment/",$string);
184
Ecl_Log::debug ("$string contains a Comment");
190
private function extractBlockName($string)
192
$string = trim($string);
193
if ($this->dtd->blockscopestart != null) {
194
$param = explode($this->dtd->blockscopestart,$string,2);
195
$string = trim($param[0]);
197
// now we just need to strip the [ and ] from block name
198
if ($this->dtd->blockdstart != null) {
199
$length = strlen($string);
201
$blockname = trim(substr($string,1,$last));
204
$blockname = $string;
206
Ecl_Log::debug("Block name $blockname extracted");
213
public function parse(&$filepointer,$str)
215
/** it is assumed that the file pointer is correctly positioned inside this function
216
* when execution starts. this would assume its a block and expect the first
217
* string to be a block unless marked as MAIN BLOCK
219
$singleblock = $this->dtd->singleblock;
221
if (!$this->mainblock) {
222
$this->name = $this->extractBlockName($str);
225
$nameblock = $this->name;
226
Ecl_Log::debug("In block $nameblock Parsing start");
229
while (!feof($filepointer)) {
230
if ($lastseenline == "") {
231
$str = fgets($filepointer);
232
Ecl_Log::debug("Getting new line : $str");
235
Ecl_Log::debug("Reusing Last Token : $str");
236
$str = $lastseenline;
240
Ecl_Log::debug("in block $nameblock Parsing : $str");
241
//first try probing plugins
242
$class = $this->dtd->getPluginByMatchingPreg($str);
243
if ($this->isComment($str)) {
244
$lastseenline=$this->newComment($filepointer,$str);
247
else if ($class != null) {
248
Ecl_Log::debug("Block found class $class for handling $str");
249
if (array_key_exists($class,$this->elements)) {
250
$lastseenline = $this->elements[$class]->parse($filepointer,$str);
251
Ecl_Log::debug("updating existing element $class");
253
$element = new $class($this->dtd);
254
$lastseenline = $element->parse($filepointer,$str);
255
$this->elements[$class] = $element;
256
Ecl_Log::debug("adding New element : $class");
259
else if ($this->isParameter($str)) {
260
$lastseenline = $this->newParameter($filepointer,$str);
262
else if (!$singleblock && $this->isBlockStart($str)) {
263
if (!$this->mainblock) {
264
Ecl_Log::debug("End of block : ".$this->name);
268
Ecl_Log::debug("Adding new Block : $str");
269
$block = new Ecl_Parser_Block($this->dtd);
270
$lastseenline= $block->parse($filepointer,$str);
271
$name = $block->getName();
272
Ecl_Log::debug("Parsed block $name completed");
273
$this->elements["BLOCK_$name"] = $block;
276
else if (!$singleblock && $this->isBlockEnd($str) && !$this->mainblock) {
284
Ecl_Log::Debug("Lastseenline was : $lastseenline");
289
private function newParameter(&$filepointer,$str) {
290
$override = $this->dtd->paramoverride;
291
if ($override != null) {
292
Ecl_Log::debug("Using override parameter class $override for $str");
293
$plugin = new $override($this->dtd);
294
$last = $plugin->parse($filepointer,$str);
295
$this->elements[$plugin->getName()] = $plugin;
299
$param = new Ecl_Parser_Parameter($this->dtd);
300
$last = $param->parse($filepointer,$str);
301
Ecl_Log::debug("Inserting parameter : *".$param->name."* into elements");
302
$this->elements[$param->name] = $param;
306
private function newComment(&$filepointer,$str) {
307
$comment = new Ecl_Parser_Comment($this->dtd);
308
$last = $comment->parse($filepointer,$str);
309
Ecl_Log::debug("Inserting Comments : $str");
310
$this->elements[] = $comment;
313
public function getBlock($name)
315
return $this->elements["BLOCK_$name"];
318
public function render()
321
$blockstart = $this->dtd->blockdstart;
322
$blockend = $this->dtd->blockdend;
323
$scopestart = $this->dtd->blockscopestart;
324
$scopeend = $this->dtd->blockscopeend;
325
if ($this->mainblock) {
327
foreach ($this->elements as $element) {
328
$out.= $element->render();
331
$out .= "$blockstart".$this->name."$blockend $scopestart\n";
332
foreach ($this->elements as $element) {
333
$out.= $element->render();
335
$out .= "$scopeend\n";