Exemplo n.º 1
0
 /**
  * Constructor
  *
  * @param string $id The context ID
  * @param Tree $tree Current node of the tree
  */
 protected function __construct($id, Tree $tree)
 {
     $wcSteps = array();
     $lastWcSeg = $lastWcKey = $segment = $wild = 0;
     $lastFragEnd = -1;
     $invalid = $tree->handler() === null ? true : false;
     $wcs = $tree->wildcards();
     $this->tree = $tree;
     $this->id = (string) $id;
     if ($invalid && isset($wcs[0]) && $tree->startPosition() != $wcs[0]->startPosition()) {
         $lastWcKey = $wild;
         $lastWcSeg = $segment;
         $wcSteps[$lastWcKey][$lastWcSeg] = array(Consts::CONTEXT_ID => '', Consts::CONTEXT_TYPE => Consts::CONTEXT_TYPE_WILDCARD, Consts::CONTEXT_START => $tree->startPosition(), Consts::CONTEXT_END => $wcs[0]->startPosition(), Consts::CONTEXT_CONTEXT => null);
         ++$segment;
     }
     // See if there is anything in the wildcard
     foreach ($wcs as $wildKey => $wc) {
         $wcStart = $wc->startPosition();
         // Combine the invalid tag fragment, make array smaller
         if ($invalid && isset($wcSteps[$lastWcKey][$lastWcSeg])) {
             if ($wcSteps[$lastWcKey][$lastWcSeg][Consts::CONTEXT_END] === $wcStart) {
                 $wcStart = $wcSteps[$lastWcKey][$lastWcSeg][Consts::CONTEXT_START];
                 unset($wcSteps[$lastWcKey][$lastWcSeg]);
             } elseif ($lastFragEnd !== -1) {
                 $wcStart = $lastFragEnd;
             }
         }
         $lastWcSeg = $segment;
         $lastWcKey = $wildKey;
         $wcEnd = $wc->endPosition();
         $wcSteps[$lastWcKey][$lastWcSeg] = array(Consts::CONTEXT_ID => '', Consts::CONTEXT_TYPE => Consts::CONTEXT_TYPE_WILDCARD, Consts::CONTEXT_START => $wcStart, Consts::CONTEXT_END => -1, Consts::CONTEXT_CONTEXT => null);
         $tempChilds = $wc->childs();
         // Is there any sub childs or not?
         if (empty($tempChilds)) {
             $wcSteps[$lastWcKey][$lastWcSeg][Consts::CONTEXT_END] = $wcEnd;
             ++$segment;
             continue;
         }
         // Get the start position of first child, it's where the first
         // wildcard ends
         $childStartPos = $tempChilds[0]->startPosition();
         // If the wildcard's end share the same position with child start,
         // remove the wildcard
         if ($wcSteps[$lastWcKey][$lastWcSeg][Consts::CONTEXT_START] === $childStartPos) {
             unset($wcSteps[$lastWcKey][$lastWcSeg]);
         } else {
             $wcSteps[$lastWcKey][$lastWcSeg][Consts::CONTEXT_END] = $childStartPos;
         }
         // Picking sub childs?
         $lastChildEndPos = -1;
         foreach ($tempChilds as $childIdx => $child) {
             $childStartPos = $child->startPosition();
             if ($lastChildEndPos !== $childStartPos && $lastChildEndPos !== -1) {
                 $lastWcSeg = ++$segment;
                 $wcSteps[$lastWcKey][$lastWcSeg] = array(Consts::CONTEXT_ID => '', Consts::CONTEXT_TYPE => Consts::CONTEXT_TYPE_WILDCARD, Consts::CONTEXT_START => $lastChildEndPos, Consts::CONTEXT_END => $childStartPos, Consts::CONTEXT_CONTEXT => null);
             }
             $lastChildEndPos = $child->endPosition() + 1;
             $wcSteps[$lastWcKey][++$segment] = array(Consts::CONTEXT_ID => $this->id . '/' . (string) $wildKey . '/' . (string) $childIdx, Consts::CONTEXT_TYPE => Consts::CONTEXT_TYPE_CHILD, Consts::CONTEXT_START => $childStartPos, Consts::CONTEXT_END => $lastChildEndPos, Consts::CONTEXT_CONTEXT => null);
             $lastFragEnd = $lastChildEndPos;
         }
         // No need to create wildcard for empty tail
         if ($lastChildEndPos >= $wcEnd) {
             ++$segment;
             continue;
         }
         $lastWcSeg = ++$segment;
         $wcSteps[$lastWcKey][$lastWcSeg] = array(Consts::CONTEXT_ID => '', Consts::CONTEXT_TYPE => Consts::CONTEXT_TYPE_WILDCARD, Consts::CONTEXT_START => $lastChildEndPos, Consts::CONTEXT_END => $wcEnd, Consts::CONTEXT_CONTEXT => null);
         $lastFragEnd = $wcEnd;
         ++$segment;
     }
     // Sort a little, make the step index continuous
     foreach ($wcSteps as $wcKey => $wcVal) {
         if (empty($wcVal)) {
             $this->steps[$wcKey] = array();
             continue;
         }
         foreach ($wcVal as $step) {
             $this->steps[$wcKey][] = $step;
         }
     }
 }