Page MenuHomePhabricator
Paste P8463

detect-template-ambiguity.php
ActivePublic

Authored by tstarling on May 1 2019, 2:10 AM.
Tags
None
Referenced Files
F28878894: raw.txt
May 1 2019, 2:31 AM
F28878595: raw.txt
May 1 2019, 2:10 AM
Subscribers
None
<?php
class Templates {
private $treesByLength = [];
public function findConflict( $node, $parts, $index = 0 ) {
if ( $index >= count( $parts ) ) {
// If we reached the leaf node then a conflict is detected
return '';
}
$part = $parts[$index];
$result = false;
if ( $part === '*' ) {
foreach ( $node as $key => $childNode ) {
$result = $this->findConflict( $childNode, $parts, $index + 1 );
if ( $result !== false ) {
$result = "$key/$result";
}
}
} else {
if ( isset( $node[$part] ) ) {
$result = $this->findConflict( $node[$part], $parts, $index + 1 );
if ( $result !== false ) {
$result = "$part/$result";
}
}
if ( $result === false && isset( $node['*'] ) ) {
$result = $this->findConflict( $node['*'], $parts, $index + 1 );
if ( $result !== false ) {
$result = "*/$result";
}
}
}
return $result;
}
public function add( $template ) {
$parts = explode( '/', $template );
$length = count( $parts );
if ( !isset( $this->treesByLength[$length] ) ) {
$this->treesByLength[$length] = [];
}
$tree =& $this->treesByLength[$length];
$conflict = $this->findConflict( $tree, $parts );
if ( $conflict !== false ) {
echo "Found conflict in template $template with existing template $conflict\n";
return false;
}
foreach ( $parts as $index => $part ) {
if ( !isset( $tree[$part] ) ) {
$tree[$part] = [];
}
$tree =& $tree[$part];
}
}
private function convertTreeToRoutes( $tree ) {
if ( $tree === [] ) {
return [ '' ];
}
$routes = [];
foreach ( $tree as $key => $node ) {
$childRoutes = $this->convertTreeToRoutes( $node );
foreach ( $childRoutes as $route ) {
$routes[] = "$key/$route";
}
}
return $routes;
}
public function getRouteList() {
$routes = [];
foreach ( $this->treesByLength as $tree ) {
$routes = array_merge( $routes, $this->convertTreeToRoutes( $tree ) );
}
return $routes;
}
}
$templates = new Templates;
while ( false !== ( $line = fgets( STDIN ) ) ) {
$templates->add( trim( $line ) );
}
print "\nCompiled route list:\n";
print implode( "\n", $templates->getRouteList() ) . "\n";