/** * Invoke an extended resource from a caller context * * @param Next\Components\Object $caller * Caller Object * * @param string $method * Callable resource name * * @param array $args * Calling Arguments * * @return mixed|boolean * Return what extended method returns. * * If invoking process fail, false will returned. * * @throws Next\Components\Debug\Exception * Called resource is not known as an extended method */ public function call(Object $caller, $method, array $args = array()) { $caller = $caller->getClass()->getName(); if (array_key_exists($caller, $this->callables)) { $offset = ArrayUtils::search($this->callables[$caller], $method); if ($offset != -1) { try { $reflector = new \ReflectionMethod($this->callables[$caller][$offset][0], $method); return $reflector->invokeArgs($this->callables[$caller][$offset][0], $args); } catch (\ReflectionException $e) { return FALSE; } } } // Unknown Method throw \Next\Components\Debug\Exception::wrongUse('Method <strong>%s</strong> could not be matched against any methods in extended Context', array($method)); }
/** * Parse one or more Routes, recursively * * @param string|array $routes * Route(s) to be parsed * * @param string $controller * Controller to whom belongs the Route(s) * * @param string $method * Method to whom belongs the Route(s) * * @throws Next\Tools\RoutesGenerator\RoutesGeneratorException * Route has less than 2 Components (a Request Method and a Route) * * @throws Next\Tools\RoutesGenerator\RoutesGeneratorException * Routes defined as single slash (usually for homepages) DO have * arguments (hierarchy concept) * * @throws Next\Tools\RoutesGenerator\RoutesGeneratorException * There is another Route with exactly the same definition, including * the Request Method */ private function parseRoutes($routes, $controller, $method, $basepath) { if (is_array($routes)) { foreach ($routes as $route) { $this->parseRoutes($route, $controller, $method, $basepath); } } else { // Listing Route Components $components = explode(',', $routes); if (count($components) < 2) { throw RoutesGeneratorException::invalidRouteStructure(array($routes, basename($controller), $method)); } // Shifting Request Method $requestMethod = trim(array_shift($components)); // ... and URI Route $URI = trim(array_shift($components)); // If we still have some components, all them will be treated as Route Params $params = array(); if (count($components) > 0) { $params = array_map('trim', $components); } // Parsing, fixing and complementing them /** * @internal * If defined URI is NOT a single slash, no trailing slash for it * But add a RegExp Border instead */ if ($URI != '/') { // Prepending Routes Basepath if present if (empty($basepath)) { $URI = sprintf('%s\\b', trim($URI, '/')); } else { $URI = sprintf('%s/%s\\b', trim($basepath, '/'), trim($URI, '/')); } /** * @internal * If we have a well designed structure, let's add RegExp Delim Captures Token too * * Routes pointing to a single slash do not have this token due hierarchical logic * These kind of Routes cannot even have any params, except the one reserved for Localization */ $URI .= self::DELIM_CAPTURE_TOKEN; } else { // Let's ensure single slash Routes have no params if (!empty($params)) { throw RoutesGeneratorException::malformedRoute(array($URI, basename($controller), $method)); } } // Adding an Always Optional Parameter for Localization $params[] = self::LOCALE_PARAM; // Let's parse Required and Optional Params $required = $this->parseParams($params, self::REQUIRED_PARAMS_TOKEN); $optional = $this->parseParams($params, self::OPTIONAL_PARAMS_TOKEN); // Searching for Duplicates $offset = ArrayUtils::search($this->results, $URI, 'route'); // We found one... if ($offset != -1) { // ... let's compare with the Request Method if ($this->results[$offset]['requestMethod'] == $requestMethod) { // Yeah! We have a Duplicate throw RoutesGeneratorException::duplicatedRoute(array($requestMethod, $URI, basename($controller), $method)); } } // Preparing Parsed Route to be recorded $this->results[] = array('requestMethod' => $requestMethod, 'route' => $URI, 'params' => array('required' => $required, 'optional' => $optional), 'class' => $controller, 'method' => $method); } }
/** * Get Context Options * * @param string|optional $option * Desired Context Option * * @param string|optional $wrapper * Optional Context Option Wrapper * * @return array|boolean * * If <strong>$option</strong> is NOT null and we can't find a match * option FALSE is returned. Otherwise the desired option value * will. * * If <strong>$option</strong> argument IS null, all the options defined will be * returned * * <strong>$wrapper</strong> argument, if set, can restrict the search and thus avoid a * value to be found */ public function getOptions($option = NULL, $wrapper = NULL) { if (!is_null($option)) { // Looking for the array key where the option COULD be $key = ArrayUtils::search($this->options, $option, $wrapper); // If it exists, let's return it if ($key != -1 && isset($this->options[$key][$option])) { return $this->options[$key][$option]; } return FALSE; } return $this->options; }