Page 1 of 1

Xtemplate preg_replace question

Posted: Wed Apr 04, 2007 6:07 pm
by errors
Hello,

I'm getting an error with XTemplate class from:

http://sourceforge.net/project/showfile ... _id=319432


the error message is:

preg_replace() [<a href='function.preg-replace'>function.preg-replace</a>]: Unknown
modifier '|'

the function that causes the error:

Code: Select all

function parse ($bname) {

		if (isset($this->preparsed_blocks[$bname])) {

			$copy = $this->preparsed_blocks[$bname];

		} elseif (isset($this->blocks[$bname])) {

			$copy = $this->blocks[$bname];

		} elseif ($this->_ignore_missing_blocks) {
			// ------------------------------------------------------
			// NW : 17 Oct 2002. Added default of ignore_missing_blocks
			//      to allow for generalised processing where some
			//      blocks may be removed from the HTML without the
			//      processing code needing to be altered.
			// ------------------------------------------------------
			// JRC: 3/1/2003 added set error to ignore missing functionality
			$this->_set_error("parse: blockname [$bname] does not exist");
			return;

		} else {

			$this->_set_error("parse: blockname [$bname] does not exist");
		}

		/* from there we should have no more {FILE } directives */
		if (!isset($copy)) {
			die('Block: ' . $bname);
		}

		$copy = preg_replace($this->filevar_delim_nl, '', $copy);

		$var_array = array();

		/* find & replace variables+blocks */
		preg_match_all("/" . $this->tag_start_delim . "([A-Za-z0-9\._]+? ?#?.*?)" . $this->tag_end_delim. "/", $copy, $var_array);
		$var_array = $var_array[1];

		foreach ($var_array as $k => $v) {

			// Are there any comments in the tags {tag#a comment for documenting the template}
			$any_comments = explode('#', $v);
			$v = rtrim($any_comments[0]);

			if (sizeof($any_comments) > 1) {

				$comments = $any_comments[1];
			} else {

				$comments = '';
			}

			$sub = explode('.', $v);

			if ($sub[0] == '_BLOCK_') {

				unset($sub[0]);

				$bname2 = implode('.', $sub);

				// trinary operator eliminates assign error in E_ALL reporting
				$var = isset($this->parsed_blocks[$bname2]) ? $this->parsed_blocks[$bname2] : null;
				$nul = (!isset($this->_null_block[$bname2])) ? $this->_null_block[''] : $this->_null_block[$bname2];

				if ($var == '') {

					if ($nul == '') {
						// -----------------------------------------------------------
						// Removed requriement for blocks to be at the start of string
						// -----------------------------------------------------------
						//                      $copy=preg_replace("/^\s*\{".$v."\}\s*\n*/m","",$copy);
						// Now blocks don't need to be at the beginning of a line,
						//$copy=preg_replace("/\s*" . $this->tag_start_delim . $v . $this->tag_end_delim . "\s*\n*/m","",$copy);
					$copy = preg_replace("/" . $this->tag_start_delim . $v . $this->tag_end_delim . "/m", '', $copy);

					} else {

						$copy = preg_replace("/" . $this->tag_start_delim . $v . $this->tag_end_delim . "/", "$nul", $copy);
					}
				} else {

					$var = trim($var);
					// SF Bug no. 810773 - thanks anonymous
					$var = str_replace('\\', '\\\\', $var);
					// Ensure dollars in strings are not evaluated reported by SadGeezer 31/3/04
					$var = str_replace('$', '\\$', $var);
					// Replaced str_replaces with preg_quote
					//$var = preg_quote($var);
					$var = str_replace('\\|', '|', $var);
					$copy = preg_replace("|" . $this->tag_start_delim . $v . $this->tag_end_delim . "|", "$var", $copy);
				}
			} else {

				$var = $this->vars;

				foreach ($sub as $v1) {

					// NW 4 Oct 2002 - Added isset and is_array check to avoid NOTICE messages
					// JC 17 Oct 2002 - Changed EMPTY to stlen=0
					//                if (empty($var[$v1])) { // this line would think that zeros(0) were empty - which is not true
					if (!isset($var[$v1]) || (!is_array($var[$v1]) && strlen($var[$v1]) == 0)) {

						// Check for constant, when variable not assigned
						if (defined($v1)) {

							$var[$v1] = constant($v1);

						} else {

							$var[$v1] = null;
						}
					}

					$var = $var[$v1];
				}

				$nul = (!isset($this->_null_string[$v])) ? ($this->_null_string[""]) : ($this->_null_string[$v]);
				$var = (!isset($var)) ? $nul : $var;

				if ($var == '') {
					// -----------------------------------------------------------
					// Removed requriement for blocks to be at the start of string
					// -----------------------------------------------------------
					//                    $copy=preg_replace("|^\s*\{".$v." ?#?".$comments."\}\s*\n|m","",$copy);
					$copy=preg_replace("|\s*" . $this->tag_start_delim . $v . " ?#?" . $comments . $this->tag_end_delim . "\s*\n|m", '', $copy);
				}

				$var = trim($var);
				// SF Bug no. 810773 - thanks anonymous
				$var = str_replace('\\', '\\\\', $var);
				// Ensure dollars in strings are not evaluated reported by SadGeezer 31/3/04
				$var = str_replace('$', '\\$', $var);
				// Replace str_replaces with preg_quote
				//$var = preg_quote($var);
				$var = str_replace('\\|', '|', $var);
				$copy=preg_replace("|" . $this->tag_start_delim . $v . " ?#?" . $comments . $this->tag_end_delim . "|", "$var", $copy);
			}
		}

		if (isset($this->parsed_blocks[$bname])) {
			$this->parsed_blocks[$bname] .= $copy;
		} else {
			$this->parsed_blocks[$bname] = $copy;
		}

		/* reset sub-blocks */
		if ($this->_autoreset && (!empty($this->sub_blocks[$bname]))) {

			reset($this->sub_blocks[$bname]);

			foreach ($this->sub_blocks[$bname] as $k => $v) {
				$this->reset($v);
			}
		}
	}

the error references this line:

Code: Select all

$copy=preg_replace("|\s*" . $this->tag_start_delim . $v . " ?#?" . $comments . $this->tag_end_delim . "\s*\n|m", '', $copy);
thanks in advance for you help!!

Posted: Wed Apr 04, 2007 11:32 pm
by feyd
The code should probably be using preg_quote(). It's nearly impossible to tell you how to fix your code if we can't see the pattern it's blowing up on. One thing I notice is the use of a metacharacter for start and end delimiters. Generally that's not a good idea.