value) associated with the route * @param string $ampersand the token separating name-value pairs in the URL. * @return mixed the constructed URL. False if this rule does not apply. */ public function createUrl($manager, $route, $params, $ampersand) { if (!isset($params[$this->nodeVar])) return false; /** @var $node Node */ $node = Node::model()->findByPk($params[$this->nodeVar]); if (empty($node)) return false; if (!isset($this->rules[$node->data_type])) return false; foreach ($this->rules[$node->data_type] as $k => $v) { if (is_string($k) && is_string($v)) { $rule = new CUrlRule($v, $k); $this->rules[$node->data_type][$k] = $rule; } else { $rule = $v; } $newParams = $params; unset($newParams[$this->langVar]); unset($newParams[$this->nodeVar]); $url = $rule->createUrl($manager, $route, $newParams, $ampersand); if ($url !== false) { $path = "/{$node->link}"; for ($t = $node; $t->node_id != null; $t = $t->node) { $path = "/{$t->node->link}{$path}"; } return "{$params[$this->langVar]}{$path}/{$url}"; } } return false; } /** * Parses a URL based on this rule. * @param CUrlManager $manager the URL manager * @param CHttpRequest $request the request object * @param string $pathInfo path info part of the URL (URL suffix is already removed based on {@link CUrlManager::urlSuffix}) * @param string $rawPathInfo path info that contains the potential URL suffix * @return mixed the route that consists of the controller ID and action ID. False if this rule does not apply. */ public function parseUrl($manager, $request, $pathInfo, $rawPathInfo) { //$rawPathInfo = $request->getPathInfo(); //$pathInfo = $rawPathInfo; preg_match("#^{$this->langExpression}#", $pathInfo, $langMatches); if (0 == count($langMatches)) return false; $lang = $langMatches[0]; //subtract lang prefix $pathInfo = substr($pathInfo, strlen($lang) + 1); //subtract at least one node link $nodes = array(); /** @var $node Node|null */ while (true) { preg_match('#^([^\/]+)#', $pathInfo, $matches); if (0 == count($matches)) break; $link = $matches[0]; $nodeCriteria = new CDbCriteria(); $nodeCriteria->compare('link', $link); if (!empty($node)) { $nodeCriteria->compare('node_id', $node->id); } else { $nodeCriteria->addCondition('node_id is null'); } $node = Node::model()->find($nodeCriteria); if (empty($node)) break; $nodes[] = $node; if (strlen($link) == strlen($pathInfo)) { $pathInfo = ''; break; } if ($pathInfo[strlen($link)] == '/') { $pathInfo = substr($pathInfo, strlen($link) + 1); } else { $pathInfo = substr($pathInfo, strlen($link)); } } if (0 == count($nodes)) return false; // no matching nodes $node = end($nodes); if (!isset($this->rules[$node->data_type])) return false; //no rules for type //parse rest foreach ($this->rules[$node->data_type] as $k => $v) { if (is_string($k) && is_string($v)) { $rule = new CUrlRule($v, $k); $this->rules[$node->data_type][$k] = $rule; } else { $rule = $v; } $route = $rule->parseUrl($manager, $request, $pathInfo, $pathInfo); if ($route !== false) { $_GET[$this->langVar] = $lang; $_GET[$this->nodeVar] = $node->id; return $route; } } return false; } }