Skip to content

Commit

Permalink
XPathConvertor: refactored exportXPath()
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshyPHP committed Mar 2, 2018
1 parent ff67314 commit 8cfcbe3
Showing 1 changed file with 69 additions and 21 deletions.
90 changes: 69 additions & 21 deletions src/Configurator/RendererGenerators/PHP/XPathConvertor.php
Expand Up @@ -436,26 +436,49 @@ protected function math($expr1, $operator, $expr2)
protected function exportXPath($expr)
{
$phpTokens = [];
foreach ($this->tokenizeXPathForExport($expr) as $match)
foreach ($this->tokenizeXPathForExport($expr) as list($type, $content))
{
if (isset($match['literal']))
{
$phpTokens[] = var_export($match['literal'], true);
}
elseif (isset($match['param']))
{
$paramName = ltrim($match['param'], '$');
$phpTokens[] = '$this->getParamAsXPath(' . var_export($paramName, true) . ')';
}
else
{
$phpTokens[] = '$node->getNodePath()';
}
$methodName = 'exportXPath' . ucfirst($type);
$phpTokens[] = $this->$methodName($content);
}

return implode('.', $phpTokens);
}

/**
* Convert a "current()" XPath expression to its PHP source representation
*
* @return string
*/
protected function exportXPathCurrent()
{
return '$node->getNodePath()';
}

/**
* Convert a fragment of an XPath expression to its PHP source representation
*
* @param string $fragment
* @return string
*/
protected function exportXPathFragment($fragment)
{
return var_export($fragment, true);
}

/**
* Convert an XSLT parameter to its PHP source representation
*
* @param string $param Parameter, including the leading $
* @return string
*/
protected function exportXPathParam($param)
{
$paramName = ltrim($param, '$');

return '$this->getParamAsXPath(' . var_export($paramName, true) . ')';
}

/**
* Generate a regexp used to parse XPath expressions
*
Expand Down Expand Up @@ -595,40 +618,65 @@ protected function generateXPathRegexp()
}

/**
* Tokenize an XPath expression for use in PHP
* Match the relevant components of an XPath expression
*
* @param string $expr XPath expression
* @return array
*/
protected function tokenizeXPathForExport($expr)
protected function matchXPathForExport($expr)
{
$tokenExprs = [
'(?<current>\\bcurrent\\(\\))',
'(?<param>\\$\\w+)',
'(?<literal>"[^"]*"|\'[^\']*\'|.)'
'(?<fragment>"[^"]*"|\'[^\']*\'|.)'
];
preg_match_all('(' . implode('|', $tokenExprs) . ')s', $expr, $matches, PREG_SET_ORDER);

// Merge literal tokens
// Merge fragment tokens
$i = 0;
$max = count($matches) - 2;
while ($i <= $max)
{
if (!isset($matches[$i]['literal']))
if (!isset($matches[$i]['fragment']))
{
++$i;
continue;
}

$j = $i;
while (isset($matches[++$j]['literal']))
while (isset($matches[++$j]['fragment']))
{
$matches[$i]['literal'] .= $matches[$j]['literal'];
$matches[$i]['fragment'] .= $matches[$j]['fragment'];
unset($matches[$j]);
}
$i = $j;
}

return array_values($matches);
}

/**
* Tokenize an XPath expression for use in PHP
*
* @param string $expr XPath expression
* @return array
*/
protected function tokenizeXPathForExport($expr)
{
$tokens = [];
foreach ($this->matchXPathForExport($expr) as $match)
{
foreach (array_reverse($match) as $k => $v)
{
// Use the last non-numeric match
if (!is_numeric($k))
{
$tokens[] = [$k, $v];
break;
}
}
}

return $tokens;
}
}

0 comments on commit 8cfcbe3

Please sign in to comment.