繁体中文
设为首页
加入收藏
当前位置:PHP技术首页 >> PHP基础 >> class.rFastTemplate.php(二)

class.rFastTemplate.php(二)

2004-12-15 08:00:00  作者:  来源:互联网  浏览次数:0  文字大小:【】【】【
简介:// // Description // Recursive internal parse routine. This will recursively parse a // template containing dynamic inferior templates. Each of these // inferior templates gets their ow...
关键字:rFastTemplate class php

//

// Description

// Recursive internal parse routine. This will recursively parse a

// template containing dynamic inferior templates. Each of these

// inferior templates gets their own entry in the TEMPLATE array.

//

function &parse_internal_1 ($tag, $rest = '') {

$debug = $this->DEBUGALL || $this->DEBUG['parse_internal_1'];

if (empty($tag)) {

$this->error ("parse_internal_1: empty tag invalid", true);

}

if ($debug)

$this->logwrite ("parse_internal_1 (tag=$tag, rest=$rest)");

while (!empty($rest)) {

if ($debug)

$this->logwrite ('parse_internal_1: REGEX_DYNBEG search: rest => ' . $rest);

if (preg_match ($this->REGEX_DYNBEG, $rest, $dynbeg)) {

// Found match, now split into two pieces and search the second

// half for the matching END. The string which goes into the

// next element includes the HTML comment which forms the BEGIN

// block.

if ($debug)

$this->logwrite ('parse_internal_1: match beg => ' . $dynbeg[1]);

$pos = strpos ($rest, $dynbeg[1]);

// See if the text on either side of the BEGIN comment is only

// whitespace. If so, we delete the entire line.

$okay = false;

for ($offbeg = $pos - 1; $offbeg >= 0; $offbeg--) {

$c = $rest{$offbeg};

if ($c == "\n") {

$okay = true;

$offbeg++;

break;

}

if (($c != ' ') && ($c != "\t")) {

$offbeg = $pos;

break;

}

}

if (! $okay) {

$offend = $pos + strlen($dynbeg[1]);

} else {

$l = strlen ($rest);

for ($offend = $pos + strlen($dynbeg[1]); $offend < $l; $offend++) {

$c = $rest{$offend};

if ($c == "\n") {

$offend++;

break;

}

if (($c != ' ') && ($c != "\t")) {

$offend = $pos + strlen($dynbeg[1]);

break;

}

}

}

// This includes the contents of the REGEX_DYNBEG in the output

// $part[] = substr ($rest, 0, $pos);

// This preserves whitespace on the END block line(s).

// $part[] = substr ($rest, 0, $pos+strlen($dynbeg[1]));

// $rest = substr ($rest, $pos+strlen($dynbeg[1]));

// Catch case where BEGIN block is at position 0.

if ($offbeg > 0)

$part[] = substr ($rest, 0, $offbeg);

$rest = substr ($rest, $offend);

$sub = '';

if ($debug)

$this->logwrite ("parse_internal_1: found at pos = $pos");

// Okay, here we are actually NOT interested in just the next

// END block. We are only interested in the next END block that

// matches this BEGIN block. This is not the most efficient

// because we really could do this in one pass through the

// string just marking BEGIN and END blocks. But the recursion

// makes for a simple algorithm (if there was a reverse

// preg...).

$found = false;

while (preg_match ($this->REGEX_DYNEND, $rest, $dynend)) {

if ($debug)

$this->logwrite ('parse_internal_1: REGEX_DYNEND search: rest => ' . $rest);

if ($debug)

$this->logwrite ('parse_internal_1: match beg => ' . $dynend[1]);

$pos = strpos ($rest, $dynend[1]);

if ($dynbeg[2] == $dynend[2]) {

$found = true;

// See if the text on either side of the END comment is

// only whitespace. If so, we delete the entire line.

$okay = false;

for ($offbeg = $pos - 1; $offbeg >= 0; $offbeg--) {

$c = $rest{$offbeg};

if ($c == "\n") {

$offbeg++;

$okay = true;

break;

}

if (($c != ' ') && ($c != "\t")) {

$offbeg = $pos;

break;

}

}

if (! $okay) {

$offend = $pos + strlen($dynend[1]);

} else {

$l = strlen ($rest);

for ($offend = $pos + strlen($dynend[1]); $offend < $l; $offend++) {

$c = $rest{$offend};

if ($c == "\n") {

$offend++;

break;

}

if (($c != ' ') && ($c != "\t")) {

$offend = $pos + strlen($dynend[1]);

break;

}

}

}

// if ($debug)

// $this->logwrite ("parse_internal_1: DYNAMIC BEGIN: (pos,len,beg,end) => ($pos, " . strlen($dynbeg[1]) . ", $offbeg, $offend)

// This includes the contents of the REGEX_DYNEND in the output

// $rest = substr ($rest, $pos);

// This preserves whitespace on the END block line(s).

// $rest = substr ($rest, $pos+strlen($dynend[1]));

// $sub .= substr ($rest, 0, $pos);

$sub .= substr ($rest, 0, $offbeg);

$rest = substr ($rest, $offend);

// Already loaded templates will not be reloaded. The

// 'clear' test was actually hiding a bug in the clear()

// logic....

if (false && isset($this->TEMPLATE[$dynend[2]]['clear'])

&& $this->TEMPLATE[$dynend[2]]['clear']) {

$this->TEMPLATE[$dynend[2]]['string'] = '';

$this->TEMPLATE[$dynend[2]]['result'] = '';

$this->TEMPLATE[$dynend[2]]['part'] =

$this->parse_internal_1 ($dynend[2], ' ');

} else if (!isset($this->TEMPLATE[$dynend[2]]['loaded'])

|| !$this->TEMPLATE[$dynend[2]]['loaded']) {

// Omit pathological case of empty dynamic template.

if (strlen($sub) > 0) {

$this->TEMPLATE[$dynend[2]]['string'] = $sub;

$this->TEMPLATE[$dynend[2]]['part'] =

$this->parse_internal_1 ($dynend[2], $sub);

$this->TEMPLATE[$dynend[2]]['part']['parent'] = $tag;

}

}

$this->TEMPLATE[$dynend[2]]['loaded'] = true;

$part[] = &$this->TEMPLATE[$dynend[2]];

$this->TEMPLATE[$dynend[2]]['tag'] = $dynend[2];

break;

} else {

$sub .= substr ($rest, 0, $pos+strlen($dynend[1]));

$rest = substr ($rest, $pos+strlen($dynend[1]));

if ($debug)

$this->logwrite ("parse_internal_1: $dynbeg[2] != $dynend[2]");

}

}

if (!$found) {

$this->error ("malformed dynamic template, missing END
\n" .

"$dynbeg[1]
\n", true);

}

} else {

// Although it would appear to make sense to check that we don't

// have a dangling END block, we will, in fact, ALWAYS appear to

// have a dangling END block. We stuff the BEGIN string in the

// part before the inferior template and the END string in the

// part after the inferior template. So for this test to work,

// we would need to look just past the final match.

if (preg_match ($this->REGEX_DYNEND, $rest, $dynend)) {

// $this->error ("malformed dynamic template, dangling END
\n" .

// "$dynend[1]
\n", 1);

}

$part[] = $rest;

$rest = '';

}

}

return $part;

}

//

// Description

// Parse the template. If $tag is actually an array, we iterate over

// the array elements. If it is a simple string tag, we may still

// recursively parse the template if it contains dynamic templates and

// we are configured to automatically load those as well.

//

function parse_internal ($tag) {

$debug = $this->DEBUGALL || $this->DEBUG['parse_internal'];

$append = false;

if ($debug)

$this->logwrite ("parse_internal (tag=$tag)");

// If we are handed an array of tags, iterate over all of them. This

// is really a holdover from the way class.FastTemplate.php3 worked;

// I think subst() already pulls that array apart for us, so this

// should not be necessary unless someone calls the internal member

// function directly.

if (gettype($tag) == 'array') {

reset ($tag);

foreach ($tag as $t) {

$this->parse_internal ($t);

}

} else {

// Load the file if it hasn't already been loaded. It might be

// nice to put in some logic that reloads the file if it has

// changed since we last loaded it, but that probably gets way too

// complicated and only makes sense if we start keeping it floating

// around between page loads as a persistent variable.

if (!isset($this->TEMPLATE[$tag]['loaded'])) {

if ($this->TEMPLATE[$tag]['dynamic']) {

// Template was declared via define_dynamic().

if ($this->TEMPLATE[$tag]['parent'])

$tag = $this->TEMPLATE[$tag]['parent'];

else {

// Try to find a non-dynamic template with the same file.

// This would have been defined via define(array(), true)

reset ($this->TEMPLATE);

foreach (array_keys($this->TEMPLATE) as $ptag) {

if ($debug)

$this->logwrite ("parse_internal: looking for non-dynamic parent, $ptag");

if (!$this->TEMPLATE[$ptag]['dynamic']

&& ($this->TEMPLATE[$ptag]['file'] == $this->TEMPLATE[$tag]['file'])) {

$tag = $ptag;

break;

}

}

}

}

$this->TEMPLATE[$tag]['string'] = &$this->load($this->TEMPLATE[$tag]['file']);

$this->TEMPLATE[$tag]['loaded'] = 1;

}

// If we are supposed to automatically detect dynamic templates and the dynamic

// flag is not set, scan the template for dynamic sections. Dynamic sections

// markers have a very rigid syntax as HTML comments....

if ($this->DYNAMIC) {

$this->TEMPLATE[$tag]['tag'] = $tag;

if (!isset($this->TEMPLATE[$tag]['parsed'])

|| !$this->TEMPLATE[$tag]['parsed']) {

$this->TEMPLATE[$tag]['part'] = $this->parse_internal_1 ($tag, $this->TEMPLATE[$tag]['string']);

$this->TEMPLATE[$tag]['parsed'] = true;

}

}

}

}

//

// Description

// class.FastTemplate.php3 compatible interface.

//

// Notes

// I prefer the name `subst' to `parse' since during this phase we are

// really doing variable substitution into the template. However, at

// some point we have to load and parse the template and `subst' will

// do that as well...

//

function parse ($handle, $tag, $autoload = true) {

return $this->subst ($handle, $tag, $autoload);

}

// 未完待续

责任编辑:admin
相关文章