protected function collect_descriptors($files) { $descriptors = []; foreach ($files as $file) { $descriptors = array_merge($descriptors, self::parse_file($file)); } \ICanBoogie\stable_sort($descriptors, function ($v) { return $v->normalized_id; }); return $descriptors; }
/** * Sorts routes according to their type and computed weight. * * Routes and grouped in two groups: static routes and dynamic routes. The difference between * static and dynamic routes is that dynamic routes capture parameters from the path and thus * require a regex to compute the match, whereas static routes only require is simple string * comparison. * * Dynamic routes are ordered according to their weight, which is computed from the number * of static parts before the first capture. The more static parts, the lighter the route is. * * @return array An array with the static routes and dynamic routes. */ private function sort_routes() { if ($this->static !== null) { return [$this->static, $this->dynamic]; } $static = []; $dynamic = []; $weights = []; foreach ($this->routes as $id => $definition) { $pattern = $definition[RouteDefinition::PATTERN]; $first_capture_position = strpos($pattern, ':') ?: strpos($pattern, '<'); if ($first_capture_position === false) { $static[$id] = $definition; } else { $dynamic[$id] = $definition; $weights[$id] = substr_count($pattern, '/', 0, $first_capture_position); } } \ICanBoogie\stable_sort($dynamic, function ($v, $k) use($weights) { return -$weights[$k]; }); $this->static = $static; $this->dynamic = $dynamic; return [$static, $dynamic]; }
/** * Orders the module ids provided according to module inheritance and weight. * * @param array $ids The module ids to order. * @param array $descriptors Module descriptors. * * @return array */ public function order_ids(array $ids, array $descriptors = null) { $ordered = []; $extends_weight = []; if ($descriptors === null) { $descriptors = $this->descriptors; } $count_extends = function ($super_id) use(&$count_extends, &$descriptors) { $i = 0; foreach ($descriptors as $id => $descriptor) { if ($descriptor[Descriptor::INHERITS] !== $super_id) { continue; } $i += 1 + $count_extends($id); } return $i; }; $count_required = function ($required_id) use(&$descriptors, &$extends_weight) { $i = 0; foreach ($descriptors as $id => $descriptor) { if (!in_array($required_id, $descriptor[Descriptor::REQUIRES])) { continue; } $i += 1 + $extends_weight[$id]; } return $i; }; foreach ($ids as $id) { $extends_weight[$id] = $count_extends($id); } foreach ($ids as $id) { $ordered[$id] = -$extends_weight[$id] - $count_required($id) + $descriptors[$id][Descriptor::WEIGHT]; } \ICanBoogie\stable_sort($ordered); return array_keys($ordered); }