/** * Renvoie toutes les routes du dictionnaire. * * @return array */ public function routes($mNodes = [], $mDefaultValue = null, &$bExist = true) { $bExist = true; if (!$this->_aRoutes) { $aRoutes = $this->_getAllValues(AbstractRouting::ROUTE); if ($aRoutes) { if (isset($aRoutes[0][0]) && !isset($aRoutes[1])) { $aRoutes = $aRoutes[0]; } } $this->_aRoutes = $aRoutes; } if (!$this->_aRoutes) { $bExist = false; return $mDefaultValue; } if ($mNodes) { $aNodes = self::_nodesToArray($mNodes); $aResult = []; foreach ($this->_aRoutes as $aRoute) { $mTmp = $aRoute; foreach ($aNodes as $sNode) { if (is_array($mTmp)) { $mTmp = self::_getAllValuesFromArray($mTmp, $sNode, $mDefaultValue); if (in_array($sNode, $this->getUniqueValueParams()) || is_numeric($sNode)) { if (is_array($mTmp) && count($mTmp) === 1 && isset($mTmp[0])) { $mTmp = $mTmp[0]; } } else { if (is_array($mTmp) && !ArrayHelper::isAssociative($mTmp) && !isset($mTmp[1]) && isset($mTmp[0]) && is_array($mTmp[0]) && !ArrayHelper::isAssociative($mTmp[0])) { $mTmp = $mTmp[0]; } } } } $aResult[] = $mTmp ?: $mDefaultValue; } if (!$aResult) { return $mDefaultValue; } return $aResult; } return $this->_aRoutes; }
/** * Stocke les paramètres capturés dynamiquement et liés à la route induite par la portion d'URI $cRoutePathType. * * @param array $aParams Liste des paramètres capturés. * @param const $cRoutePathType Portion d'URI sur laquelle porte la route. */ protected function _storeCapturedVars($aParams, $cRoutePathType) { $aRoute = $this->_aDefinitions[$cRoutePathType]; if (isset($aRoute[AbstractRouting::PARAM][AbstractRouting::PARAM_MATCH])) { $aAllComputedParams = $aRoute[AbstractRouting::PARAM][AbstractRouting::PARAM_MATCH]; foreach ($aAllComputedParams as &$aComputedParams) { if (ArrayHelper::isAssociative($aComputedParams)) { $aComputedParams = [$aComputedParams]; } } foreach ($aParams as $sName => $sValue) { if (is_numeric($sName)) { continue; } $aComputedParam = $aAllComputedParams[$sName]; foreach ($aComputedParam as $aCParam) { $sParamValue = $sValue; if (isset($aCParam[AbstractRouting::PARAM_TYPE], $aCParam[AbstractRouting::PARAM_NAME])) { if (isset($aCParam[AbstractRouting::PARAM_VALUE][$sValue])) { $sParamValue = $aCParam[AbstractRouting::PARAM_VALUE][$sValue]; } $this->_aParams[$aCParam[AbstractRouting::PARAM_TYPE]][$aCParam[AbstractRouting::PARAM_NAME]] = $sParamValue; } } } } }
protected function _updateUriComponents($cUriPathType) { // Définition du type de chemin de l'uri $aDefinition = $this->_getDefinitions($cUriPathType); // Si aucune base d'url réécrite n'a été définie dans la configuration if (!isset($aDefinition[self::REWRITE])) { throw new UnderflowException("La section [" . self::REWRITE . "] doit être renseignée pour la route d'ID \"" . $this->_getRouteIds()[$cUriPathType] . "\"."); } // Récupération de la liste des valeurs des paramètres précisées par le développeur $aInputParams = $this->_aConf[self::_PARAM][$cUriPathType] ?: self::$_aDefaultConf[self::_PARAM][$cUriPathType]; // Si la définition ne comprend de section de paramètres matchables if (!isset($aDefinition[self::PARAM][self::PARAM_MATCH])) { // on retourne directement l'url rewritée telle quelle $this->_setFinalUriComponent($aDefinition[self::REWRITE], $cUriPathType); return; } if (!is_array($aDefinition[self::PARAM][self::PARAM_MATCH])) { throw new UnexpectedValueException("La section [" . self::PARAM . "][" . self::PARAM_MATCH . "] de la définition " . "de {$cUriPathType} est invalide. Elle doit être de type tableau."); } // Liste des propriétés de chaque paramètre défini dans les définitions comme à utiliser pour le rewriting $aDefinitionParams = []; // Pour chaque paramètre matchable foreach ($aDefinition[self::PARAM][self::PARAM_MATCH] as $iIndex => $aConfParam) { // Si sa valeur est un tableau associatif $bAssociativeMatch = ArrayHelper::isAssociative($aConfParam); if ($bAssociativeMatch) { // On la met dans un tableau indexé $aConfParam = [$aConfParam]; } // Pour chaque sous-paramètre matchable foreach ($aConfParam as $iSubIndex => $aSubConfParam) { if (!isset($aSubConfParam[self::PARAM_NAME])) { throw new UnderflowException("Le champ [" . self::PARAM . "][" . self::PARAM_MATCH . "][{$iIndex}]" . (!$bAssociativeMatch ? "[{$iSubIndex}]" : '') . "[" . self::PARAM_NAME . "] pour la route d'ID \"" . ".{$this->_getRouteIds}()[{$cUriPathType}]." . "\"."); } $sConfParamName = $aSubConfParam[self::PARAM_NAME]; // S'il n'est pas précisé que le sous-paramètre est à exclure du rewriting if (!isset($aSubConfParam[self::PARAM_REWRITE_USE]) || $aSubConfParam[self::PARAM_REWRITE_USE]) { // On stocke les propriétés du sous-paramètres pour les utiliser dans le rewriting // Si ce paramètre à déjà des propriétés définies if (isset($aDefinitionParams[$sConfParamName])) { // on regarde lequel des deux est obligatoire pour le rewriting $bOldParamPriority = isset($aDefinitionParams[$sConfParamName][self::PARAM_REWRITE_PRIORITY]) ? $aDefinitionParams[$sConfParamName][self::PARAM_REWRITE_PRIORITY] : 0; $bNewParamPriority = isset($aSubConfParam[self::PARAM_REWRITE_PRIORITY]) ? $aSubConfParam[self::PARAM_REWRITE_PRIORITY] : 0; // Si la nouvelle propriété à une valeur de priorité supérieure ou égale à l'ancienne if ($bOldParamPriority <= $bNewParamPriority) { // Si la nouvelle valeur est obligatoire if (!isset($aSubConfParam[self::PARAM_REWRITE_MANDATORY]) || $aSubConfParam[self::PARAM_REWRITE_MANDATORY] || isset($aInputParams[$sConfParamName]) || isset($aDefinitionParams[$sConfParamName][self::PARAM_REWRITE_MANDATORY]) && $aDefinitionParams[$sPlaceholderName][self::PARAM_REWRITE_MANDATORY]) { // On remplace l'ancienne valeur par la nouvelle $aDefinitionParams[$sConfParamName] = $aSubConfParam; } } } else { $aDefinitionParams[$sConfParamName] = $aSubConfParam; } } } } // Liste des remplacements à effectuer dans l'url à réécrire $aReplacements = []; // Pour chaque paramètre défini dans les définitions comme à utiliser pour le rewriting foreach ($aDefinitionParams as $aDefProperties) { // Si le développeur n'a pas fourni de valeur pour ce paramètre if (!isset($aInputParams[$aDefProperties[self::PARAM_NAME]])) { // Si ce paramètre est obligatoire if (!isset($aDefProperties[self::PARAM_REWRITE_MANDATORY]) || $aDefProperties[self::PARAM_REWRITE_MANDATORY]) { throw new UnderflowException("Le paramètre \"" . $aDefProperties[self::PARAM_NAME] . "\" doit être renseigné pour la route d'ID \"" . $this->_getRouteIds()[$cUriPathType] . "\"."); } else { continue; } } // Si le paramètre n'a pas de propriété VALUE sous forme de tableau if (!is_array($aDefProperties) || !isset($aDefProperties[self::PARAM_VALUE]) || !is_array($aDefProperties[self::PARAM_VALUE])) { // On stocke directement la valeur fournie par le développeur $sInputValue = $aInputParams[$aDefProperties[self::PARAM_NAME]]; } else { if (!in_array($aInputParams[$aDefProperties[self::PARAM_NAME]], $aDefProperties[self::PARAM_VALUE]) && isset($aDefProperties[self::PARAM_REWRITE_DEFAULT_VALUE])) { // C'est cette valeur par défaut qu'on stocke $sInputValue = array_search($aDefProperties[self::PARAM_REWRITE_DEFAULT_VALUE], $aDefProperties[self::PARAM_VALUE]); } else { // On stocke la valeur associée à la valeur fournie par le développeur $sInputValue = array_search($aInputParams[$aDefProperties[self::PARAM_NAME]], $aDefProperties[self::PARAM_VALUE]); } } $sPlaceholderName = isset($aDefProperties[self::PARAM_REWRITE_PLACEHOLDER]) ? $aDefProperties[self::PARAM_REWRITE_PLACEHOLDER] : $aDefProperties[self::PARAM_NAME]; $aReplacements[$sPlaceholderName] = $sInputValue; } // On procède au remplacement des placeholder de l'url réécrite par le valeurs fournies par le développeur $sRewritedUrl = $aDefinition[self::REWRITE]; foreach ($aReplacements as $sPlaceholder => $sValue) { $iNbReplacements = 0; $sRewritedUrl = str_replace('{{' . $sPlaceholder . '}}', $sValue, $sRewritedUrl, $iNbReplacements); // S'il y a eu au moins un remplacement de réalisé if ($iNbReplacements) { // on supprime des paramètres GET une éventuelle variable ayant le même nom, // stockée précedemment en GET par une autre route $this->_removeGetParam($sPlaceholder); } } // On stocke le composant réécrit de l'url $this->_setFinalUriComponent($sRewritedUrl, $cUriPathType); // Récupération de tous les paramètres qui, à première vue, n'ont pas été utilisés pour des remplacements $aGetParams = array_diff_key($aInputParams, $aReplacements); // Pour chacun de ces paramètres GET foreach ($aGetParams as $sGetName => $sGetValue) { // On vérifie s'il n'a effectivement pas été utilisé pour un remplacement, via à une propriété PLACEHOLDER différente de son nom if (isset($aDefinitionParams[$sGetName][self::PARAM_REWRITE_PLACEHOLDER]) && !isset($aGetParams[$aDefinitionParams[$sGetName][self::PARAM_REWRITE_PLACEHOLDER]])) { // Ensemble des propriétés de paramètre GET $aGetDef = $aDefinitionParams[$sGetName]; // Si le paramètre GET a une propriété VALUE sous forme de tableau, possédant une valeur par défaut, // et que la valeur du paramètre n'est pas présente dans le tableau $bGetParamNotUsed = isset($aGetDef[self::PARAM_VALUE]) && is_array($aGetDef[self::PARAM_VALUE]) && isset($aGetDef[self::PARAM_REWRITE_DEFAULT_VALUE]) && !in_array($sGetValue, $aGetDef[self::PARAM_VALUE]); // Si le paramètre a été utilisé pour une réécriture if (!$bGetParamNotUsed) { // on supprime le paramètre unset($aGetParams[$sGetName]); } } } // On enregistre les paramètres non utilisés $this->_setGetParams($aGetParams, $cUriPathType); }
protected static function _isValidParamValueDetail(array $aRouteDefinition) { $bValid = true; $aParamValueDetailExist = [AbstractRouting::PARAM_MATCH => isset($aRouteDefinition[AbstractRouting::PARAM][AbstractRouting::PARAM_MATCH]), AbstractRouting::PARAM_DEFAULT => isset($aRouteDefinition[AbstractRouting::PARAM][AbstractRouting::PARAM_DEFAULT])]; foreach ($aParamValueDetailExist as $sParamName => $bExists) { if ($bExists) { $aParamValueDetails = $aRouteDefinition[AbstractRouting::PARAM][$sParamName]; // On harmonise les détails uniques avec les détails en liste // pour ça, on passe tous les détails uniques en liste. if (ArrayHelper::isAssociative($aParamValueDetails)) { $aParamValueDetails = [$aParamValueDetails]; } foreach ($aParamValueDetails as $mKey => $mParamValueDetailValue) { if (is_array($mParamValueDetailValue)) { // Dans le cas des paramètres par défaut if ($sParamName === AbstractRouting::PARAM_DEFAULT) { // Si l'une des clés du tableau est un mot réservé if (array_intersect(self::$_aReservedKeywords, array_keys($mParamValueDetailValue))) { // Alors la clé AbstractRouting::PARAM_NAME doit être obligatoirement définie if (!isset($mParamValueDetailValue[AbstractRouting::PARAM_NAME])) { self::_recordInvalid($aRouteDefinition, "La propriété [" . AbstractRouting::PARAM . "][{$sParamName}][" . AbstractRouting::PARAM_NAME . "]" . " doit être définie."); $bValid = false; break 2; } } } foreach ($mParamValueDetailValue as $sName => $mValue) { switch ($sName) { case AbstractRouting::PARAM_NAME: if (!is_string($mValue)) { self::_recordInvalid($aRouteDefinition, "La propriété [" . AbstractRouting::PARAM . "][{$sParamName}][{$sName}]" . " doit être définie en tant que chaîne de caractères."); $bValid = false; break 4; } break; case AbstractRouting::PARAM_TYPE: if (!in_array($mValue, self::$_aValidVarTypes)) { self::_recordInvalid($aRouteDefinition, "La propriété [" . AbstractRouting::PARAM . "][{$sParamName}][{$sName}]" . " doit être égale à l'une des valeurs suivantes : \"" . implode('", "', self::$_aValidVarTypes) . "\"."); $bValid = false; break 4; } break; case AbstractRouting::PARAM_VALUE: if (!is_string($mValue) && !is_array($mValue)) { self::_recordInvalid($aRouteDefinition, "La propriété [" . AbstractRouting::PARAM . "][{$sParamName}][{$sName}]" . " doit être une chaîne de caractères ou un tableau de valeurs."); $bValid = false; break 4; } elseif (is_array($mValue) && ArrayHelper::isMulti($mValue)) { self::_recordInvalid($aRouteDefinition, "La propriété [" . AbstractRouting::PARAM . "][{$sParamName}][{$sName}]" . " ne peut pas être un tableau multidimensionnel."); $bValid = false; break 4; } } } } } } } return $bValid; }