protected static function convertPHP(&$head, &$tail, $passthrough)
	{
		// Test whether the attributes must be saved when rendering the head because they're needed
		// when rendering the tail
		$saveAttributes = (bool) preg_match('(\\$node->(?:get|has)Attribute)', $tail);

		// Collect the names of all the attributes so that we can initialize them with a null value
		// to avoid undefined variable notices. We exclude attributes that seem to be in an if block
		// that tests its existence beforehand. This last part is not an accurate process as it
		// would be much more expensive to do it accurately but where it fails the only consequence
		// is we needlessly add the attribute to the list. There is no difference in functionality
		preg_match_all(
			"(\\\$node->getAttribute\\('([^']+)'\\))",
			preg_replace_callback(
				'(if\\(\\$node->hasAttribute\\(([^\\)]+)[^}]+)',
				function ($m)
				{
					return str_replace('$node->getAttribute(' . $m[1] . ')', '', $m[0]);
				},
				$head . $tail
			),
			$matches
		);
		$attrNames = array_unique($matches[1]);

		// Replace the source in $head and $tail
		self::replacePHP($head);
		self::replacePHP($tail);

		if (!$passthrough && strpos($head, '$node->textContent') !== false)
		{
			$head = '$textContent=$this->getQuickTextContent($xml);' . str_replace('$node->textContent', '$textContent', $head);
		}

		if (!empty($attrNames))
		{
			ksort($attrNames);
			$head = "\$attributes+=['" . implode("'=>null,'", $attrNames) . "'=>null];" . $head;
		}

		if ($saveAttributes)
		{
			$head .= '$this->attributes[]=$attributes;';
			$tail  = '$attributes=array_pop($this->attributes);' . $tail;
		}
	}
protected static function convertPHP(&$head, &$tail, $passthrough)
	{
		// Test whether the attributes must be saved when rendering the head because they're needed
		// when rendering the tail
		$saveAttributes = (bool) preg_match('(\\$node->(?:get|has)Attribute)', $tail);

		// Collect the names of all the attributes so that we can initialize them with a null value
		// to avoid undefined variable notices. We exclude attributes that seem to be in an if block
		// that tests its existence beforehand. This last part is not an accurate process as it
		// would be much more expensive to do it accurately but where it fails the only consequence
		// is we needlessly add the attribute to the list. There is no difference in functionality
		preg_match_all(
			"(\\\$node->getAttribute\\('([^']+)'\\))",
			preg_replace_callback(
				'(if\\(\\$node->hasAttribute\\(([^\\)]+)[^}]+)',
				function ($m)
				{
					return str_replace('$node->getAttribute(' . $m[1] . ')', '', $m[0]);
				},
				$head . $tail
			),
			$matches
		);
		$attrNames = array_unique($matches[1]);

		// Replace the source in $head and $tail
		self::replacePHP($head);
		self::replacePHP($tail);

		if (!$passthrough && strpos($head, '$node->textContent') !== false)
		{
			$head = '$textContent=$this->getQuickTextContent($xml);' . str_replace('$node->textContent', '$textContent', $head);
		}

		if (!empty($attrNames))
		{
			ksort($attrNames);
			$head = "\$attributes+=['" . implode("'=>null,'", $attrNames) . "'=>null];" . $head;
		}

		if ($saveAttributes)
		{
			$head .= '$this->attributes[]=$attributes;';
			$tail  = '$attributes=array_pop($this->attributes);' . $tail;
		}
	}
protected static function convertPHP ( & $ head , & $ tail , $ passthrough ) { // Test whether the attributes must be saved when rendering the head because they're needed // when rendering the tail $ saveAttributes = ( bool ) preg_match ( '(\\$node->(?:get|has)Attribute)' , $ tail ) ; // Collect the names of all the attributes so that we can initialize them with a null value // to avoid undefined variable notices. We exclude attributes that seem to be in an if block // that tests its existence beforehand. This last part is not an accurate process as it // would be much more expensive to do it accurately but where it fails the only consequence // is we needlessly add the attribute to the list. There is no difference in functionality preg_match_all ( "(\\\$node->getAttribute\\('([^']+)'\\))" , preg_replace_callback ( '(if\\(\\$node->hasAttribute\\(([^\\)]+)[^}]+)' , function ( $ m ) { return str_replace ( '$node->getAttribute(' . $ m [ 1 ] . ')' , '' , $ m [ 0 ] ) ; } , $ head . $ tail ) , $ matches ) ; $ attrNames = array_unique ( $ matches [ 1 ] ) ; // Replace the source in $head and $tail self :: replacePHP ( $ head ) ; self :: replacePHP ( $ tail ) ; if ( ! $ passthrough && strpos ( $ head , '$node->textContent' ) !== false ) { $ head = '$textContent=$this->getQuickTextContent($xml);' . str_replace ( '$node->textContent' , '$textContent' , $ head ) ; } if ( ! empty ( $ attrNames ) ) { ksort ( $ attrNames ) ; $ head = "\$attributes+=['" . implode ( "'=>null,'" , $ attrNames ) . "'=>null];" . $ head ; } if ( $ saveAttributes ) { $ head .= '$this->attributes[]=$attributes;' ; $ tail = '$attributes=array_pop($this->attributes);' . $ tail ; } }
Convert the two sides of a compiled template to quick rendering

@param  string &$head
@param  string &$tail
@param  bool    $passthrough
@return void
Convert the two sides of a compiled template to quick rendering