/**
  * Checks whether $routeValues contains elements which correspond to this Dynamic Route Part.
  * If a corresponding element is found in $routeValues, this element is removed from the array.
  *
  * @param array $routeValues An array with key/value pairs to be resolved by Dynamic Route Parts.
  * @return boolean TRUE if current Route Part could be resolved, otherwise FALSE
  */
 public final function resolve(array &$routeValues)
 {
     $this->value = NULL;
     if ($this->name === NULL || $this->name === '') {
         return FALSE;
     }
     $valueToResolve = $this->findValueToResolve($routeValues);
     if (!$this->resolveValue($valueToResolve)) {
         return FALSE;
     }
     $routeValues = Arrays::unsetValueByPath($routeValues, $this->name);
     return TRUE;
 }
 /**
  * Merges specified arguments with arguments from request.
  *
  * If $this->request is no sub request, request arguments will only be merged if $this->addQueryString is set.
  * Otherwise all request arguments except for the ones prefixed with the current request argument namespace will
  * be merged. Additionally special arguments (PackageKey, SubpackageKey, ControllerName & Action) are merged.
  *
  * The argument provided through the $arguments parameter always overrule the request
  * arguments.
  *
  * The request hierarchy is structured as follows:
  * root (HTTP) > main (Action) > sub (Action) > sub sub (Action)
  *
  * @param array $arguments
  * @return array
  */
 protected function mergeArgumentsWithRequestArguments(array $arguments)
 {
     if ($this->request !== $this->request->getMainRequest()) {
         $subRequest = $this->request;
         while ($subRequest instanceof \TYPO3\Flow\Mvc\ActionRequest) {
             $requestArguments = (array) $subRequest->getArguments();
             // Reset arguments for the request that is bound to this UriBuilder instance
             if ($subRequest === $this->request) {
                 if ($this->addQueryString === false) {
                     $requestArguments = array();
                 } else {
                     foreach ($this->argumentsToBeExcludedFromQueryString as $argumentToBeExcluded) {
                         unset($requestArguments[$argumentToBeExcluded]);
                     }
                 }
             } else {
                 // Remove all arguments of the current sub request if it's namespaced
                 if ($this->request->getArgumentNamespace() !== '') {
                     $requestNamespace = $this->getRequestNamespacePath($this->request);
                     if ($this->addQueryString === false) {
                         $requestArguments = Arrays::unsetValueByPath($requestArguments, $requestNamespace);
                     } else {
                         foreach ($this->argumentsToBeExcludedFromQueryString as $argumentToBeExcluded) {
                             $requestArguments = Arrays::unsetValueByPath($requestArguments, $requestNamespace . '.' . $argumentToBeExcluded);
                         }
                     }
                 }
             }
             // Merge special arguments (package, subpackage, controller & action) from main request
             $requestPackageKey = $subRequest->getControllerPackageKey();
             if (!empty($requestPackageKey)) {
                 $requestArguments['@package'] = $requestPackageKey;
             }
             $requestSubpackageKey = $subRequest->getControllerSubpackageKey();
             if (!empty($requestSubpackageKey)) {
                 $requestArguments['@subpackage'] = $requestSubpackageKey;
             }
             $requestControllerName = $subRequest->getControllerName();
             if (!empty($requestControllerName)) {
                 $requestArguments['@controller'] = $requestControllerName;
             }
             $requestActionName = $subRequest->getControllerActionName();
             if (!empty($requestActionName)) {
                 $requestArguments['@action'] = $requestActionName;
             }
             if (count($requestArguments) > 0) {
                 $requestArguments = $this->addNamespaceToArguments($requestArguments, $subRequest);
                 $arguments = Arrays::arrayMergeRecursiveOverrule($requestArguments, $arguments);
             }
             $subRequest = $subRequest->getParentRequest();
         }
     } elseif ($this->addQueryString === true) {
         $requestArguments = $this->request->getArguments();
         foreach ($this->argumentsToBeExcludedFromQueryString as $argumentToBeExcluded) {
             unset($requestArguments[$argumentToBeExcluded]);
         }
         if ($requestArguments !== array()) {
             $arguments = Arrays::arrayMergeRecursiveOverrule($requestArguments, $arguments);
         }
     }
     return $arguments;
 }
 /**
  * @test
  * @expectedException \InvalidArgumentException
  */
 public function unsetValueByPathThrowsExceptionIfPathIsNoArrayOrString()
 {
     $array = array('Foo' => array('Bar' => array('Baz' => array(2 => 'the value'))));
     \TYPO3\Flow\Utility\Arrays::unsetValueByPath($array, NULL);
 }
 /**
  * @test
  * @expectedException \InvalidArgumentException
  */
 public function unsetValueByPathThrowsExceptionIfPathIsNoArrayOrString()
 {
     $array = array('Foo' => array('Bar' => array('Baz' => array(2 => 'the value'))));
     Arrays::unsetValueByPath($array, null);
 }
 /**
  * Checks whether $routeValues can be resolved to a corresponding uri.
  * If all Route Parts can resolve one or more of the $routeValues, TRUE is
  * returned and $this->matchingURI contains the generated URI (excluding
  * protocol and host).
  *
  * @param array $routeValues An array containing key/value pairs to be resolved to uri segments
  * @return boolean TRUE if this Route corresponds to the given $routeValues, otherwise FALSE
  * @throws InvalidRoutePartValueException
  * @see getMatchingUri()
  */
 public function resolves(array $routeValues)
 {
     $this->resolvedUriPath = null;
     if ($this->uriPattern === null) {
         return false;
     }
     if (!$this->isParsed) {
         $this->parse();
     }
     $resolvedUriPath = '';
     $remainingDefaults = $this->defaults;
     $requireOptionalRouteParts = false;
     $matchingOptionalUriPortion = '';
     /** @var $routePart RoutePartInterface */
     foreach ($this->routeParts as $routePart) {
         if (!$routePart->resolve($routeValues)) {
             if (!$routePart->hasDefaultValue()) {
                 return false;
             }
         }
         if ($routePart->getName() !== null) {
             $remainingDefaults = Arrays::unsetValueByPath($remainingDefaults, $routePart->getName());
         }
         $routePartValue = null;
         if ($routePart->hasValue()) {
             $routePartValue = $routePart->getValue();
             if (!is_string($routePartValue)) {
                 throw new InvalidRoutePartValueException('RoutePart::getValue() must return a string after calling RoutePart::resolve(), got ' . (is_object($routePartValue) ? get_class($routePartValue) : gettype($routePartValue)) . ' for RoutePart "' . get_class($routePart) . '" in Route "' . $this->getName() . '".');
             }
         }
         $routePartDefaultValue = $routePart->getDefaultValue();
         if ($routePartDefaultValue !== null && !is_string($routePartDefaultValue)) {
             throw new InvalidRoutePartValueException('RoutePart::getDefaultValue() must return a string, got ' . (is_object($routePartDefaultValue) ? get_class($routePartDefaultValue) : gettype($routePartDefaultValue)) . ' for RoutePart "' . get_class($routePart) . '" in Route "' . $this->getName() . '".');
         }
         if (!$routePart->isOptional()) {
             $resolvedUriPath .= $routePart->hasValue() ? $routePartValue : $routePartDefaultValue;
             $requireOptionalRouteParts = false;
             continue;
         }
         if ($routePart->hasValue() && strtolower($routePartValue) !== strtolower($routePartDefaultValue)) {
             $matchingOptionalUriPortion .= $routePartValue;
             $requireOptionalRouteParts = true;
         } else {
             $matchingOptionalUriPortion .= $routePartDefaultValue;
         }
         if ($requireOptionalRouteParts) {
             $resolvedUriPath .= $matchingOptionalUriPortion;
             $matchingOptionalUriPortion = '';
         }
     }
     if ($this->compareAndRemoveMatchingDefaultValues($remainingDefaults, $routeValues) !== true) {
         return false;
     }
     if (isset($routeValues['@format']) && $routeValues['@format'] === '') {
         unset($routeValues['@format']);
     }
     // add query string
     if (count($routeValues) > 0) {
         $routeValues = Arrays::removeEmptyElementsRecursively($routeValues);
         $routeValues = $this->persistenceManager->convertObjectsToIdentityArrays($routeValues);
         if (!$this->appendExceedingArguments) {
             $internalArguments = $this->extractInternalArguments($routeValues);
             if ($routeValues !== array()) {
                 return false;
             }
             $routeValues = $internalArguments;
         }
         $queryString = http_build_query($routeValues, null, '&');
         if ($queryString !== '') {
             $resolvedUriPath .= strpos($resolvedUriPath, '?') !== false ? '&' . $queryString : '?' . $queryString;
         }
     }
     $this->resolvedUriPath = $resolvedUriPath;
     return true;
 }
 /**
  * Checks whether $routeValues contains elements which correspond to this Dynamic Route Part.
  * If a corresponding element is found in $routeValues, this element is removed from the array.
  *
  * @param array $routeValues An array with key/value pairs to be resolved by Dynamic Route Parts.
  * @return boolean TRUE if current Route Part could be resolved, otherwise FALSE
  */
 public final function resolve(array &$routeValues)
 {
     $this->value = null;
     if ($this->name === null || $this->name === '') {
         return false;
     }
     $valueToResolve = $this->findValueToResolve($routeValues);
     if (!$this->resolveValue($valueToResolve)) {
         return false;
     }
     $routeValues = Arrays::unsetValueByPath($routeValues, $this->name);
     return true;
 }
 /**
  * @param NodeInterface $node
  * @return void
  */
 public function refreshCacheIfNecessary(NodeInterface $node)
 {
     if ($node->getNodeType()->isOfType('Nezaniel.SystemNodes:SystemNode')) {
         $currentPath = [];
         $recursiveIterator = function (array $items) use(&$recursiveIterator, &$currentPath, $node) {
             foreach ($items as $key => $entry) {
                 $currentPath[] = $key;
                 if (is_array($entry)) {
                     $recursiveIterator($entry);
                 } elseif ($entry === $node->getIdentifier()) {
                     $this->systemNodeIdentifiers = Arrays::unsetValueByPath($this->systemNodeIdentifiers, $currentPath);
                 }
                 array_pop($currentPath);
             }
         };
         $recursiveIterator($this->systemNodeIdentifiers);
         $this->initializeSystemNode($node);
         $this->cache->set('systemNodeIdentifiers', $this->systemNodeIdentifiers);
     }
 }