private static function route($priority) { $uri = implode('/', segments()); foreach (self::$slugs as $key => $routes) { $key = str_replace('%s', '([a-z0-9\\-]+)', str_replace('%d', '([0-9]+)', str_replace('/', '\\/', $key))); if (preg_match('/^' . $key . '(\\/|$)/is', $uri, $matches)) { array_pop($matches); array_shift($matches); foreach ($routes as &$route) { if ($route->get_priority() == $priority) { $arguments = preg_replace('/^' . $key . '(\\/|$)/is', '', $uri); $arguments = explode("?", $arguments); $arguments = array_filter(explode("/", array_shift($arguments))); $arguments = array_merge($matches, $arguments); // Check if the class that will handle the content actually contains the requested function. if (!method_exists($route->get_classname(), $route->get_function())) { continue; } // Check if we're not calling said function with too few parameters. $reflector = new ReflectionClass($route->get_classname()); if (count($arguments) < $reflector->getMethod($route->get_function())->getNumberOfRequiredParameters()) { continue; } // Check if this function might want variable number of parameters. $collapse_parameters = false; $parameters = $reflector->getMethod($route->get_function())->getParameters(); if (count($parameters) && end($parameters)->name == 'parameters') { $collapse_parameters = true; } if (count($arguments) > count($parameters) && $collapse_parameters && $priority == ROUTE_DEFAULT) { $route->set_priority(ROUTE_LATE); continue; } // Check if we're not calling said function with too many parameters. if (count($arguments) > count($parameters) && !$collapse_parameters) { continue; } // Check if we're not calling a static function. if ($reflector->getMethod($route->get_function())->isStatic()) { continue; } // Save old segments should we need it again later self::$urlsegments = self::$segments; // Set the segments to those that matched our content self::$segments = array(); self::$segments[0] = strtolower($route->get_contentname()); self::$segments[1] = strtolower($route->get_function()); self::$segments = array_merge(self::$segments, $arguments); // Set the current route self::$current_route = $route; // Check database if needed (only do this when there's no admin panel) if (!Config::admin_enabled()) { $site = current_site(); if (self::is_fw4() && !$site->live) { FW4_Structure::check_structure(); } } // Fire the controller View_Loader::get_instance()->set_path(CONTENTPATH . self::$content_prefix . self::$segments[0]); $page = self::$content_pages[strtolower($route->get_classname())]; if ($collapse_parameters) { $non_optional = array_splice($arguments, 0, count($parameters) - 1); $arguments = array_merge($non_optional, array(array_diff($arguments, array('index')))); } try { $result = call_user_func_array(array($page, $route->get_function()), $arguments); } catch (RowNotFoundException $e) { $result = false; } // If the controller returns false, reset the segments and continue matching if ($result === false) { self::$segments = self::$urlsegments; continue; } return true; } } } } return false; }
private static function expand_DOM_node($node, $parent = false) { $types = FW4_Type_Manager::get_instance(); $toexpand = array(); $toreplace = array(); $slugnodes = array(); if (Config::admin_enabled() && ($node->nodeName == 'object' || $node->nodeName == 'page')) { $creator = $node->ownerDocument->createElement('creator'); $creator->setAttribute('name', 'created_by_user'); $node->appendChild($creator); $editor = $node->ownerDocument->createElement('editor'); $editor->setAttribute('name', 'edited_by_user'); $node->appendChild($editor); $create_date = $node->ownerDocument->createElement('timedate'); $create_date->setAttribute('name', 'created_at_date'); $node->appendChild($create_date); $edit_date = $node->ownerDocument->createElement('timedate'); $edit_date->setAttribute('name', 'edited_at_date'); $node->appendChild($edit_date); } if ($parent && $parent->nodeName != 'structure') { $node->setAttribute('parent_type', $parent->nodeName); $node->setAttribute('parent_name', $parent->getAttribute('name')); $node->setAttribute('stack', $parent->getAttribute('stack') . '>' . $node->getAttribute('name')); $node->setAttribute('path', $parent->getAttribute('path') . '>' . $node->getAttribute('name')); } else { $node->setAttribute('stack', $node->getAttribute('name')); $node->setAttribute('path', $node->getAttribute('name')); } foreach ($node->childNodes as $child) { if ($child->nodeName == 'object' || $child->nodeName == 'page') { $toexpand[] = $child; } else { if ($type_obj = $types->get_type($child->nodeName)) { $toreplace[] = $child; } else { if ($child->nodeName == 'slug') { $slugnodes[] = $child; } } } } foreach ($toexpand as $child) { $node->replaceChild(self::expand_DOM_node($child, $node), $child); } foreach ($toreplace as $child) { $typename = $child->nodeName; $type_obj = $types->get_type($typename); $xml = new SimpleXMLElement($type_obj->get_structure(simplexml_import_dom($child), simplexml_import_dom($node))); $node->removeChild($child); foreach ($xml->children() as $newchild) { $newchild = dom_import_simplexml($newchild); $newchild->setAttribute('type_name', $typename); $newchild = $node->ownerDocument->importNode($newchild, true); $node->appendChild(self::expand_DOM_node($newchild, $node)); } } foreach ($slugnodes as $child) { if (!$child->hasAttribute('format') && $child->hasAttribute('source')) { $child->setAttribute('format', '[' . $child->getAttribute('source') . ']'); } preg_match_all('/\\[([a-z0-9\\_]+)\\]/is', strval($child->getAttribute('format')), $matches, PREG_SET_ORDER); $name = $child->hasAttribute('name') ? strval($child->getAttribute('name')) : 'slug'; $translatable = false; $slug_fields = array(); foreach ($matches as $match) { $source = false; foreach ($node->childNodes as $objchild) { if ($objchild->nodeName != '#text' && strval($objchild->getAttribute('name')) == $match[1] && $objchild->hasAttribute('translatable')) { $child->setAttribute('translatable', 'translatable'); } } } } if ($node->hasAttribute("archived") && ($node->nodeName == 'object' || $node->nodeName == 'page')) { $archive = $node->cloneNode(true); $toremove = array(); foreach ($archive->childNodes as $child) { if ($child->nodeName == 'object' || $child->nodeName == 'page') { $toremove[] = $child; } } foreach ($toremove as $child) { $archive->removeChild($child); } $archive->setAttribute('name', '_versions'); $archive->removeAttribute('order'); $newnode = $node->ownerDocument->createElement('object'); foreach ($archive->childNodes as $child) { $child = $archive->ownerDocument->importNode($child->cloneNode(true), true); $newnode->appendChild($child); } foreach ($archive->attributes as $attrName => $attrNode) { $newnode->setAttribute($attrName, $attrNode->textContent); } $node->appendChild($newnode); } return $node; }