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

Documentation generated on Wed, 07 Sep 2011 13:48:28 +0200 by phpDocumentor 1.4.3