Source for file significant.urls.php

Documentation is available at significant.urls.php

  1. <?php
  2. /**
  3.  * @package     jelix
  4.  * @subpackage  urls_engine
  5.  * @author      Laurent Jouanneau
  6.  * @contributor
  7.  * @link        http://www.jelix.org
  8.  * @licence     GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html
  9.  */
  10.  
  11. /**
  12.  * a specific selector for the xml files which contains the configuration of the engine
  13.  * @package  jelix
  14.  * @subpackage urls_engine
  15.  * @author      Laurent Jouanneau
  16.  * @copyright   2005-2006 Laurent Jouanneau
  17.  */
  18. class jSelectorUrlCfgSig extends jSelectorCfg {
  19.     public $type = 'urlcfgsig';
  20.  
  21.     public function getCompiler(){
  22.         require_once(dirname(__FILE__).'/jSignificantUrlsCompiler.class.php');
  23.         $o new jSignificantUrlsCompiler();
  24.         return $o;
  25.     }
  26.     public function getCompiledFilePath ()return JELIX_APP_TEMP_PATH.'compiled/urlsig/'.$this->file.'.creationinfos.php';}
  27. }
  28.  
  29. /**
  30.  * a specific selector for user url handler
  31.  * @package  jelix
  32.  * @subpackage urls_engine
  33.  * @author      Laurent Jouanneau
  34.  * @copyright   2005-2006 Laurent Jouanneau
  35.  */
  36. class jSelectorUrlHandler extends jSelectorClass {
  37.     public $type = 'urlhandler';
  38.     protected $_suffix = '.urlhandler.php';
  39. }
  40.  
  41. /**
  42.  * interface for user url handler
  43.  * @package  jelix
  44.  * @subpackage urls_engine
  45.  * @author      Laurent Jouanneau
  46.  * @copyright   2005-2006 Laurent Jouanneau
  47.  */
  48. interface jIUrlSignificantHandler {
  49.     /**
  50.     * create the jUrlAction corresponding to the given jUrl. Return false if it doesn't correspond
  51.     * @param jUrl 
  52.     * @return jUrlAction|false
  53.     */
  54.     public function parse($url);
  55.  
  56.     /**
  57.     * fill the given jurl object depending the jUrlAction object
  58.     * @param jUrlAction $urlact 
  59.     * @param jUrl $url 
  60.     */
  61.     public function create($urlact$url);
  62. }
  63.  
  64. /**
  65.  * an url engine to parse,analyse and create significant url
  66.  * it needs an urls.xml file in the config directory (see documentation)
  67.  * @package  jelix
  68.  * @subpackage urls_engine
  69.  * @author      Laurent Jouanneau
  70.  * @copyright   2005-2008 Laurent Jouanneau
  71.  */
  72. class significantUrlEngine implements jIUrlEngine {
  73.  
  74.     /**
  75.     * data to create significant url
  76.     * @var array 
  77.     */
  78.     protected $dataCreateUrl = null;
  79.  
  80.     /**
  81.     * data to parse and anaylise significant url, and to determine action, module etc..
  82.     * @var array 
  83.     */
  84.     protected $dataParseUrl =  null;
  85.  
  86.     /**
  87.      * Parse a url from the request
  88.      * @param jRequest $request 
  89.      * @param array  $params            url parameters
  90.      * @return jUrlAction 
  91.      * @since 1.1
  92.      */
  93.     public function parseFromRequest($request$params){
  94.         global $gJConfig;
  95.  
  96.         if ($gJConfig->urlengine['enableParser']){
  97.  
  98.             $sel new jSelectorUrlCfgSig($gJConfig->urlengine['significantFile']);
  99.             jIncluder::inc($sel);
  100.             $snp $gJConfig->urlengine['urlScriptIdenc'];
  101.             $file=JELIX_APP_TEMP_PATH.'compiled/urlsig/'.$sel->file.'.'.$snp.'.entrypoint.php';
  102.             if(file_exists($file)){
  103.                 require($file);
  104.                 $this->dataCreateUrl = $GLOBALS['SIGNIFICANT_CREATEURL']// fourni via le jIncluder ligne 99
  105.                 $this->dataParseUrl = $GLOBALS['SIGNIFICANT_PARSEURL'][$snp];
  106.                 return $this->_parse($request->urlScript$request->urlPathInfo$params);
  107.             }
  108.         }
  109.  
  110.         $urlact new jUrlAction($params);
  111.         return $urlact;
  112.     }
  113.  
  114.     /**
  115.     * Parse some url components
  116.     * @param string $scriptNamePath    /path/index.php
  117.     * @param string $pathinfo          the path info part of the url (part between script name and query)
  118.     * @param array  $params            url parameters (query part e.g. $_REQUEST)
  119.     * @return jUrlAction 
  120.     */
  121.     public function parse($scriptNamePath$pathinfo$params){
  122.         global $gJConfig;
  123.  
  124.         if ($gJConfig->urlengine['enableParser']){
  125.  
  126.             $sel new jSelectorUrlCfgSig($gJConfig->urlengine['significantFile']);
  127.             jIncluder::inc($sel);
  128.             $basepath $gJConfig->urlengine['basePath'];
  129.             if(strpos($scriptNamePath$basepath=== 0){
  130.                 $snp substr($scriptNamePath,strlen($basepath));
  131.             }else{
  132.                 $snp $scriptNamePath;
  133.             }
  134.             $pos strrpos($snp,$gJConfig->urlengine['entrypointExtension']);
  135.             if($pos !== false){
  136.                 $snp substr($snp,0,$pos);
  137.             }
  138.             $snp rawurlencode($snp);
  139.             $file=JELIX_APP_TEMP_PATH.'compiled/urlsig/'.$sel->file.'.'.$snp.'.entrypoint.php';
  140.             if(file_exists($file)){
  141.                 require($file);
  142.                 $this->dataCreateUrl = $GLOBALS['SIGNIFICANT_CREATEURL']// fourni via le jIncluder ligne 127
  143.                 $this->dataParseUrl = $GLOBALS['SIGNIFICANT_PARSEURL'][$snp];
  144.                 return $this->_parse($scriptNamePath$pathinfo$params);
  145.             }
  146.         }
  147.         $urlact new jUrlAction($params);
  148.         return $urlact;
  149.     }
  150.  
  151.     /**
  152.     *
  153.     * @param string $scriptNamePath    /path/index.php
  154.     * @param string $pathinfo          the path info part of the url (part between script name and query)
  155.     * @param array  $params            url parameters (query part e.g. $_REQUEST)
  156.     * @return jUrlAction 
  157.     */
  158.     protected function _parse($scriptNamePath$pathinfo$params){
  159.         global $gJConfig;
  160.  
  161.         /*if(substr($pathinfo,-1) == '/' && $pathinfo != '/'){
  162.                 $pathinfo = substr($pathinfo,0,-1);
  163.         }*/
  164.  
  165.         $urlact null;
  166.         $isDefault false;
  167.         $url new jUrl($scriptNamePath$params$pathinfo);
  168.  
  169.         foreach($this->dataParseUrl as $k=>$infoparsing){
  170.             // le premier paramètre indique si le point d'entré actuelle est un point d'entré par défaut ou non
  171.             if($k==0){
  172.                 $isDefault=$infoparsing;
  173.                 continue;
  174.             }
  175.  
  176.             if(count($infoparsing5){
  177.                 // on a un tableau du style
  178.                 // array( 0=> 'module', 1=>'action', 2=>'selecteur handler', 3=>array('actions','secondaires'))
  179.                 $s new jSelectorUrlHandler($infoparsing[2]);
  180.                 $c =$s->className.'UrlsHandler';
  181.                 $handler =new $c();
  182.  
  183.                 $url->params['module']=$infoparsing[0];
  184.  
  185.                 // si une action est présente dans l'url actuelle
  186.                 // et qu'elle fait partie des actions secondaires, alors on la laisse
  187.                 // sinon on prend celle indiquée dans la conf
  188.                 if ($infoparsing[3&& isset($params['action'])) {
  189.                     if(strpos($params['action']':'=== false{
  190.                         $params['action''default:'.$params['action'];
  191.                     }
  192.                     if(in_array($params['action']$infoparsing[3]))
  193.                         $url->params['action']=$params['action']// action peut avoir été écrasé par une itération précédente
  194.                     else
  195.                         $url->params['action']=$infoparsing[1];
  196.                 }else{
  197.                     $url->params['action']=$infoparsing[1];
  198.                 }
  199.                 // appel au handler
  200.                 if($urlact $handler->parse($url)){
  201.                     break;
  202.                 }
  203.             }else{
  204.                 /* on a un tableau du style
  205.                 array( 0=>'module', 1=>'action', 2=>'regexp_pathinfo',
  206.                 3=>array('annee','mois'), // tableau des valeurs dynamiques, classées par ordre croissant
  207.                 4=>array(true, false), // tableau des valeurs escapes
  208.                 5=>array('bla'=>'cequejeveux' ) // tableau des valeurs statiques
  209.                 6=>false ou array('act','act'...) // autres actions secondaires autorisées
  210.                 */
  211.                 if(preg_match ($infoparsing[2]$pathinfo$matches)){
  212.                     if($infoparsing[0!='')
  213.                         $params['module']=$infoparsing[0];
  214.  
  215.                     // si une action est présente dans l'url actuelle
  216.                     // et qu'elle fait partie des actions secondaires, alors on la laisse
  217.                     // sinon on prend celle indiquée dans la conf
  218.  
  219.                     if($infoparsing[6&& isset($params['action']) ) {
  220.                         if(strpos($params['action']':'=== false{
  221.                             $params['action''default:'.$params['action'];
  222.                         }
  223.                         if(!in_array($params['action']$infoparsing[6]&& $infoparsing[1!=''{
  224.                             $params['action']=$infoparsing[1];
  225.                         }
  226.  
  227.                     else {
  228.                         if($infoparsing[1!='')
  229.                             $params['action']=$infoparsing[1];
  230.                     }
  231.  
  232.                     // on fusionne les parametres statiques
  233.                     if ($infoparsing[5]{
  234.                         $params array_merge ($params$infoparsing[5]);
  235.                     }
  236.  
  237.                     if(count($matches)){
  238.                         array_shift($matches);
  239.                         foreach($infoparsing[3as $k=>$name){
  240.                             if(isset($matches[$k])){
  241.                                 if($infoparsing[4][$k]){
  242.                                     $params[$namejUrl::unescape($matches[$k]);
  243.                                 }else{
  244.                                     $params[$name$matches[$k];
  245.                                 }
  246.                             }
  247.                         }
  248.                     }
  249.                     $urlact new jUrlAction($params);
  250.                     break;
  251.                 }
  252.             }
  253.         }
  254.         if(!$urlact{
  255.             if($isDefault && $pathinfo == ''){
  256.                // si on n'a pas trouvé de correspondance, mais que c'est l'entry point
  257.                // par defaut pour le type de request courant, alors on laisse passer..
  258.                $urlact new jUrlAction($params);
  259.             else {
  260.                try{
  261.                    $urlact jUrl::get($gJConfig->urlengine['notfoundAct'],array(),jUrl::JURLACTION);
  262.                }catch(Exception $e){
  263.                    $urlact new jUrlAction(array('module'=>'jelix''action'=>'error:notfound'));
  264.                }
  265.             }
  266.         }
  267.         return $urlact;
  268.     }
  269.  
  270.  
  271.     /**
  272.     * Create a jurl object with the given action data
  273.     * @param jUrlAction $url  information about the action
  274.     * @return jUrl the url correspondant to the action
  275.     * @author      Laurent Jouanneau
  276.     * @copyright   2005 CopixTeam, 2005-2006 Laurent Jouanneau
  277.     *    very few lines of code are copyrighted by CopixTeam, written by Laurent Jouanneau
  278.     *    and released under GNU Lesser General Public Licence,
  279.     *    in an experimental version of Copix Framework v2.3dev20050901,
  280.     *    http://www.copix.org.
  281.     */
  282.     public function create$urlact){
  283.  
  284.         if($this->dataCreateUrl == null){
  285.             $sel new jSelectorUrlCfgSig($GLOBALS['gJConfig']->urlengine['significantFile']);
  286.             jIncluder::inc($sel);
  287.             $this->dataCreateUrl = $GLOBALS['SIGNIFICANT_CREATEURL'];
  288.         }
  289.  
  290.         /*
  291.         a) recupere module~action@request -> obtient les infos pour la creation de l'url
  292.         b) récupère un à un les parametres indiqués dans params à partir de jUrl
  293.         c) remplace la valeur récupérée dans le result et supprime le paramètre de l'url
  294.         d) remplace scriptname de jUrl par le resultat
  295.         */
  296.  
  297.         $url new jUrl('',$urlact->params,'');
  298.  
  299.         $module $url->getParam('module'jContext::get());
  300.         $action $url->getParam('action');
  301.  
  302.         $id $module.'~'.$action.'@'.$urlact->requestType;
  303.         $urlinfo null;
  304.         if (isset ($this->dataCreateUrl [$id])){
  305.             $urlinfo $this->dataCreateUrl[$id];
  306.             $url->delParam('module');
  307.             $url->delParam('action');
  308.         }else{
  309.             $id $module.'~*@'.$urlact->requestType;
  310.             if (isset ($this->dataCreateUrl [$id])){
  311.                 $urlinfo $this->dataCreateUrl[$id];
  312.                 $url->delParam('module');
  313.             }else{
  314.                 $id '@'.$urlact->requestType;
  315.                 if (isset ($this->dataCreateUrl [$id])){
  316.                     $urlinfo $this->dataCreateUrl[$id];
  317.                 }else{
  318.                     throw new Exception("Significant url engine doesn't find corresponding url to this action :".$module.'~'.$action.'@'.$urlact->requestType);
  319.                 }
  320.             }
  321.         }
  322.         /*
  323.         urlinfo =
  324.             array(0,'entrypoint', https true/false,'selecteur handler')
  325.             ou
  326.             array(1,'entrypoint', https true/false, 
  327.                     array('annee','mois','jour','id','titre'), // liste des paramètres de l'url à prendre en compte
  328.                     array(true, false..), // valeur des escapes
  329.                     "/news/%1/%2/%3/%4-%5", // forme de l'url
  330.                     false, //indique si  c'est une action surchargeante
  331.                     )
  332.             ou
  333.             array(2,'entrypoint', https true/false,); pour les clés du type "@request"
  334.             array(3,'entrypoint', https true/false); pour les clés du type "module~@request"
  335.             array(4, array(1,..), array(1,..)...);
  336.         */
  337.         if($urlinfo[0]==4){
  338.             $l count($urlinfo);
  339.             $urlinfofound null;
  340.             for($i=1$i $l$i++){
  341.                 $ok true;
  342.                 foreach($urlinfo[$i][7as $n=>$v){
  343.                     if($url->getParam($n,''!= $v){
  344.                         $ok false;
  345.                         break;
  346.                     }
  347.                 }
  348.                 if($ok){
  349.                     $urlinfofound $urlinfo[$i];
  350.                     break;
  351.                 }
  352.             }
  353.             if($urlinfofound !== null){
  354.                 $urlinfo $urlinfofound;
  355.             }else{
  356.                 $urlinfo $urlinfo[1];
  357.             }
  358.         }
  359.  
  360.         $url->scriptName $GLOBALS['gJConfig']->urlengine['basePath'].$urlinfo[1];
  361.         if($urlinfo[2])
  362.             $url->scriptName 'https://'.$_SERVER['HTTP_HOST'].$url->scriptName;
  363.  
  364.         if($urlinfo[1&& !$GLOBALS['gJConfig']->urlengine['multiview']){
  365.             $url->scriptName.=$GLOBALS['gJConfig']->urlengine['entrypointExtension'];
  366.         }
  367.         // pour certains types de requete, les paramètres ne sont pas dans l'url
  368.         // donc on les supprime
  369.         // c'est un peu crade de faire ça en dur ici, mais ce serait lourdingue
  370.         // de charger la classe request pour savoir si on peut supprimer ou pas
  371.         if(in_array($urlact->requestType ,array('xmlrpc','jsonrpc','soap'))){
  372.             $url->clearParam();
  373.             return $url;
  374.         }
  375.  
  376.         if($urlinfo[0]==0){
  377.             $s new jSelectorUrlHandler($urlinfo[3]);
  378.             $c =$s->resource.'UrlsHandler';
  379.             $handler =new $c();
  380.             $handler->create($urlact$url);
  381.         }elseif($urlinfo[0]==1){
  382.             $pi $urlinfo[5];
  383.             foreach ($urlinfo[3as $k=>$param){
  384.                 if($urlinfo[4][$k]){
  385.                     $pi=str_replace(':'.$paramjUrl::escape($url->getParam($param,''),true)$pi);
  386.                 }else{
  387.                     $pi=str_replace(':'.$paramurlencode($url->getParam($param,''))$pi);
  388.                 }
  389.                 $url->delParam($param);
  390.             }
  391.             $url->pathInfo $pi;
  392.             if($urlinfo[6])
  393.                 $url->setParam('action',$action);
  394.             // removed parameters corresponding to static values
  395.             foreach($urlinfo[7as $name=>$value){
  396.                 $url->delParam($name);
  397.             }
  398.         }elseif($urlinfo[0]==3){
  399.             $url->delParam('module');
  400.         }
  401.  
  402.         return $url;
  403.     }
  404. }

Documentation generated on Thu, 22 Mar 2012 22:18:06 +0100 by phpDocumentor 1.4.3