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.  * @copyright   2005-2011 Laurent Jouanneau
  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.     protected function _createPath(){
  41.         global $gJConfig;
  42.         if (isset($gJConfig->_modulesPathList[$this->module])) {
  43.             $p $gJConfig->_modulesPathList[$this->module];
  44.         else if (isset($gJConfig->_externalModulesPathList[$this->module])) {
  45.             $p $gJConfig->_externalModulesPathList[$this->module];
  46.         else {
  47.             throw new jExceptionSelector('jelix~errors.selector.module.unknown'$this->toString());
  48.         }
  49.         $this->_path = $p.$this->_dirname.$this->subpath.$this->className.$this->_suffix;
  50.  
  51.         if (!file_exists($this->_path|| strpos($this->subpath,'..'!== false // second test for security issues
  52.             throw new jExceptionSelector('jelix~errors.selector.invalid.target'array($this->toString()$this->type));
  53.         }
  54.     }
  55.  
  56. }
  57. /**
  58.  * interface for user url handler
  59.  * @package  jelix
  60.  * @subpackage urls_engine
  61.  * @author      Laurent Jouanneau
  62.  * @copyright   2005-2006 Laurent Jouanneau
  63.  */
  64. interface jIUrlSignificantHandler {
  65.     /**
  66.     * create the jUrlAction corresponding to the given jUrl. Return false if it doesn't correspond
  67.     * @param jUrl $url 
  68.     * @return jUrlAction|false
  69.     */
  70.     public function parse($url);
  71.  
  72.     /**
  73.     * fill the given jurl object depending the jUrlAction object
  74.     * @param jUrlAction $urlact 
  75.     * @param jUrl $url 
  76.     */
  77.     public function create($urlact$url);
  78. }
  79. /**
  80.  * an url engine to parse,analyse and create significant url
  81.  * it needs an urls.xml file in the config directory (see documentation)
  82.  * @package  jelix
  83.  * @subpackage urls_engine
  84.  * @author      Laurent Jouanneau
  85.  * @copyright   2005-2008 Laurent Jouanneau
  86.  */
  87. class significantUrlEngine implements jIUrlEngine {
  88.  
  89.     /**
  90.     * data to create significant url
  91.     * @var array 
  92.     */
  93.     protected $dataCreateUrl = null;
  94.  
  95.     /**
  96.     * data to parse and anaylise significant url, and to determine action, module etc..
  97.     * @var array 
  98.     */
  99.     protected $dataParseUrl =  null;
  100.  
  101.     /**
  102.      * Parse a url from the request
  103.      * @param jRequest $request 
  104.      * @param array  $params            url parameters
  105.      * @return jUrlAction 
  106.      * @since 1.1
  107.      */
  108.     public function parseFromRequest ($request$params{
  109.         global $gJConfig;
  110.  
  111.         if ($gJConfig->urlengine['enableParser']{
  112.  
  113.             $sel new jSelectorUrlCfgSig($gJConfig->urlengine['significantFile']);
  114.             jIncluder::inc($sel);
  115.             $snp  $gJConfig->urlengine['urlScriptIdenc'];
  116.             $file JELIX_APP_TEMP_PATH.'compiled/urlsig/'.$sel->file.'.'.$snp.'.entrypoint.php';
  117.             if (file_exists($file)) {
  118.                 require($file);
  119.                 $this->dataCreateUrl = $GLOBALS['SIGNIFICANT_CREATEURL']// fourni via le jIncluder ligne 99
  120.                 $this->dataParseUrl = $GLOBALS['SIGNIFICANT_PARSEURL'][$snp];
  121.                 return $this->_parse($request->urlScript$request->urlPathInfo$params);
  122.             }
  123.         }
  124.  
  125.         $urlact new jUrlAction($params);
  126.         return $urlact;
  127.     }
  128.  
  129.     /**
  130.     * Parse some url components
  131.     * @param string $scriptNamePath    /path/index.php
  132.     * @param string $pathinfo          the path info part of the url (part between script name and query)
  133.     * @param array  $params            url parameters (query part e.g. $_REQUEST)
  134.     * @return jUrlAction 
  135.     */
  136.     public function parse($scriptNamePath$pathinfo$params){
  137.         global $gJConfig;
  138.  
  139.         if ($gJConfig->urlengine['enableParser']{
  140.  
  141.             $sel new jSelectorUrlCfgSig($gJConfig->urlengine['significantFile']);
  142.             jIncluder::inc($sel);
  143.             $basepath $gJConfig->urlengine['basePath'];
  144.             if (strpos($scriptNamePath$basepath=== 0{
  145.                 $snp substr($scriptNamePath,strlen($basepath));
  146.             }
  147.             else {
  148.                 $snp $scriptNamePath;
  149.             }
  150.             $pos strrpos($snp$gJConfig->urlengine['entrypointExtension']);
  151.             if ($pos !== false{
  152.                 $snp substr($snp,0,$pos);
  153.             }
  154.             $snp rawurlencode($snp);
  155.             $file JELIX_APP_TEMP_PATH.'compiled/urlsig/'.$sel->file.'.'.$snp.'.entrypoint.php';
  156.             if (file_exists($file)) {
  157.                 require($file);
  158.                 $this->dataCreateUrl = $GLOBALS['SIGNIFICANT_CREATEURL']// fourni via le jIncluder ligne 127
  159.                 $this->dataParseUrl = $GLOBALS['SIGNIFICANT_PARSEURL'][$snp];
  160.                 return $this->_parse($scriptNamePath$pathinfo$params);
  161.             }
  162.         }
  163.         $urlact new jUrlAction($params);
  164.         return $urlact;
  165.     }
  166.  
  167.     /**
  168.     *
  169.     * @param string $scriptNamePath    /path/index.php
  170.     * @param string $pathinfo          the path info part of the url (part between script name and query)
  171.     * @param array  $params            url parameters (query part e.g. $_REQUEST)
  172.     * @return jUrlAction 
  173.     */
  174.     protected function _parse($scriptNamePath$pathinfo$params){
  175.         global $gJConfig;
  176.  
  177.         $urlact null;
  178.         $isDefault false;
  179.         $url new jUrl($scriptNamePath$params$pathinfo);
  180.  
  181.         foreach ($this->dataParseUrl as $k=>$infoparsing{
  182.             // the first element indicates if the entry point is a default entry point or not
  183.             if ($k==0{
  184.                 $isDefault $infoparsing;
  185.                 continue;
  186.             }
  187.  
  188.             if (count($infoparsing6{
  189.                 list($module$action$reg$selectorHandler$secondariesActions$infoparsing;
  190.                 $url2 clone $url;
  191.                 if ($reg != ''{
  192.                     if (preg_match($reg$pathinfo$m))
  193.                         $url2->pathInfo = isset($m[1])?$m[1]:'/';
  194.                     else
  195.                         continue;
  196.                 }
  197.                 $s new jSelectorUrlHandler($selectorHandler);
  198.                 include_once($s->getPath());
  199.                 $c $s->className.'UrlsHandler';
  200.                 $handler new $c();
  201.  
  202.                 $url2->params['module'$module;
  203.  
  204.                 // if the action parameter exists in the current url
  205.                 // and if it is one of secondaries actions, then we keep it
  206.                 // else we take the action indicated in the url mapping
  207.                 if ($secondariesActions && isset($params['action'])) {
  208.                     if (strpos($params['action']':'=== false{
  209.                         $params['action''default:'.$params['action'];
  210.                     }
  211.                     if (in_array($params['action']$secondariesActions))
  212.                         // action peut avoir été écrasé par une itération précédente
  213.                         $url2->params['action'$params['action'];
  214.                     else
  215.                         $url2->params['action'$action;
  216.                 }
  217.                 else {
  218.                     $url2->params['action'$action;
  219.                 }
  220.                 // appel au handler
  221.                 if ($urlact $handler->parse($url2)) {
  222.                     break;
  223.                 }
  224.             }
  225.             elseif (preg_match ($infoparsing[2]$pathinfo$matches)) {
  226.  
  227.                 /* we have this array
  228.                 array( 0=>'module', 1=>'action', 2=>'regexp_pathinfo',
  229.                 3=>array('year','month'), // list of dynamic value included in the url,
  230.                                       // alphabetical ascendant order
  231.                 4=>array(true, false),    // list of boolean which indicates for each
  232.                                       // dynamic value, if it is an escaped value or not
  233.                 5=>array('bla'=>'whatIWant' ), // list of static values
  234.                 6=>false or array('secondaries','actions')
  235.                 */
  236.                 list($module$action$reg$dynamicValues$escapes$staticValues$secondariesActions$infoparsing;
  237.                 if (isset($params['module']&& $params['module'!== $module)
  238.                     continue;
  239.  
  240.                 if ($module != '')
  241.                     $params['module'$module;
  242.  
  243.                 // if the action parameter exists in the current url
  244.                 // and if it is one of secondaries actions, then we keep it
  245.                 // else we take the action indicated in the url mapping
  246.                 if ($secondariesActions && isset($params['action']) ) {
  247.                     if (strpos($params['action']':'=== false{
  248.                         $params['action''default:'.$params['action'];
  249.                     }
  250.                     if (!in_array($params['action']$secondariesActions&& $action !=''{
  251.                         $params['action'$action;
  252.                     }
  253.                 }
  254.                 else {
  255.                     if ($action !='')
  256.                         $params['action'$action;
  257.                 }
  258.  
  259.                 // let's merge static parameters
  260.                 if ($staticValues{
  261.                     $params array_merge ($params$staticValues);
  262.                 }
  263.  
  264.                 // now let's read dynamic parameters
  265.                 if (count($matches)) {
  266.                     array_shift($matches);
  267.                     foreach ($dynamicValues as $k=>$name){
  268.                         if (isset($matches[$k])) {
  269.                             if ($escapes[$k]{
  270.                                 $params[$namejUrl::unescape($matches[$k]);
  271.                             }
  272.                             else {
  273.                                 $params[$name$matches[$k];
  274.                             }
  275.                         }
  276.                     }
  277.                 }
  278.                 $urlact new jUrlAction($params);
  279.                 break;
  280.             }
  281.         }
  282.         if (!$urlact{
  283.             if ($isDefault && $pathinfo == ''{
  284.                 // if we didn't find the url in the mapping, and if this is the default
  285.                 // entry point, then we do anything
  286.                 $urlact new jUrlAction($params);
  287.             }
  288.             else {
  289.                 try {
  290.                     $urlact jUrl::get($gJConfig->urlengine['notfoundAct']array()jUrl::JURLACTION);
  291.                 }
  292.                 catch (Exception $e{
  293.                     $urlact new jUrlAction(array('module'=>'jelix''action'=>'error:notfound'));
  294.                 }
  295.             }
  296.         }
  297.         return $urlact;
  298.     }
  299.  
  300.     /**
  301.     * Create a jurl object with the given action data
  302.     * @param jUrlAction $url  information about the action
  303.     * @return jUrl the url correspondant to the action
  304.     * @author      Laurent Jouanneau
  305.     * @copyright   2005 CopixTeam, 2005-2006 Laurent Jouanneau
  306.     *    very few lines of code are copyrighted by CopixTeam, written by Laurent Jouanneau
  307.     *    and released under GNU Lesser General Public Licence,
  308.     *    in an experimental version of Copix Framework v2.3dev20050901,
  309.     *    http://www.copix.org.
  310.     */
  311.     public function create($urlact{
  312.  
  313.         if ($this->dataCreateUrl == null{
  314.             $sel new jSelectorUrlCfgSig($GLOBALS['gJConfig']->urlengine['significantFile']);
  315.             jIncluder::inc($sel);
  316.             $this->dataCreateUrl = $GLOBALS['SIGNIFICANT_CREATEURL'];
  317.         }
  318.  
  319.         $url new jUrl(''$urlact->params'');
  320.  
  321.         $module $url->getParam('module'jContext::get());
  322.         $action $url->getParam('action');
  323.  
  324.         // let's try to retrieve informations corresponding
  325.         // to the given action. this informations will allow us to build
  326.         // the url
  327.         $id $module.'~'.$action.'@'.$urlact->requestType;
  328.         $urlinfo null;
  329.         if (isset ($this->dataCreateUrl [$id])) {
  330.             $urlinfo $this->dataCreateUrl[$id];
  331.             $url->delParam('module');
  332.             $url->delParam('action');
  333.         }
  334.         else {
  335.             $id $module.'~*@'.$urlact->requestType;
  336.             if (isset ($this->dataCreateUrl[$id])) {
  337.                 $urlinfo $this->dataCreateUrl[$id];
  338.                 if ($urlinfo[0!= || $urlinfo[3=== true)
  339.                     $url->delParam('module');
  340.             }
  341.             else {
  342.                 $id '@'.$urlact->requestType;
  343.                 if (isset ($this->dataCreateUrl [$id])) {
  344.                     $urlinfo $this->dataCreateUrl[$id];
  345.                 }
  346.                 else {
  347.                     throw new Exception("Significant url engine doesn't find corresponding url to this action :".$module.'~'.$action.'@'.$urlact->requestType);
  348.                 }
  349.             }
  350.         }
  351.         /*
  352.         urlinfo =
  353.           or array(0,'entrypoint', https true/false, 'handler selector', 'basepathinfo')
  354.           or array(1,'entrypoint', https true/false,
  355.                   array('year','month',), // list of dynamic values included in the url
  356.                   array(true, false..), // list of boolean which indicates for each
  357.                                         // dynamic value, if it is an escaped value or not
  358.                   "/news/%1/%2/", // the url
  359.                   true/false, // false : this is a secondary action
  360.                   array('bla'=>'whatIWant' ) // list of static values
  361.                   )
  362.           or array(2,'entrypoint', https true/false), // for the patterns "@request"
  363.           or array(3,'entrypoint', https true/false), // for the patterns "module~@request"
  364.           or array(4, array(1,...), array(1,...)...)
  365.         */
  366.         if ($urlinfo[0== 4{
  367.             // an action is mapped to several urls
  368.             // so it isn't finished. Let's find building information
  369.             // into the array
  370.             $l count($urlinfo);
  371.             $urlinfofound null;
  372.             for ($i=1$i $l$i++{
  373.                 $ok true;
  374.                 // verify that given static parameters of the action correspond
  375.                 // to those defined for this url
  376.                 foreach ($urlinfo[$i][7as $n=>$v{
  377.                     if ($url->getParam($n,''!= $v{
  378.                         $ok false;
  379.                         break;
  380.                     }
  381.                 }
  382.                 if ($ok{
  383.                     // static parameters correspond: we found our informations
  384.                     $urlinfofound $urlinfo[$i];
  385.                     break;
  386.                 }
  387.             }
  388.             if ($urlinfofound !== null{
  389.                 $urlinfo $urlinfofound;
  390.             }
  391.             else {
  392.                 $urlinfo $urlinfo[1];
  393.             }
  394.         }
  395.  
  396.         // at this step, we have informations to build the url
  397.  
  398.         $url->scriptName $GLOBALS['gJConfig']->urlengine['basePath'].$urlinfo[1];
  399.         if ($urlinfo[2])
  400.             $url->scriptName $GLOBALS['gJCoord']->request->getServerURI(true).$url->scriptName;
  401.  
  402.         if ($urlinfo[1&& !$GLOBALS['gJConfig']->urlengine['multiview']{
  403.             $url->scriptName .= $GLOBALS['gJConfig']->urlengine['entrypointExtension'];
  404.         }
  405.  
  406.         // pour certains types de requete, les paramètres ne sont pas dans l'url
  407.         // donc on les supprime
  408.         // c'est un peu crade de faire ça en dur ici, mais ce serait lourdingue
  409.         // de charger la classe request pour savoir si on peut supprimer ou pas
  410.         if (in_array($urlact->requestTypearray('xmlrpc','jsonrpc','soap'))) {
  411.             $url->clearParam();
  412.             return $url;
  413.         }
  414.  
  415.         if ($urlinfo[0== 0{
  416.             $s new jSelectorUrlHandler($urlinfo[3]);
  417.             $c $s->resource.'UrlsHandler';
  418.             $handler new $c();
  419.             $handler->create($urlact$url);
  420.             if ($urlinfo[4!= ''{
  421.                 $url->pathInfo $urlinfo[4].$url->pathInfo;
  422.             }
  423.         }
  424.         elseif($urlinfo[0== 1{
  425.             $pi $urlinfo[5];
  426.             foreach ($urlinfo[3as $k=>$param){
  427.                 if ($urlinfo[4][$k]{
  428.                     $pi str_replace(':'.$paramjUrl::escape($url->getParam($param,''),true)$pi);
  429.                 }
  430.                 else {
  431.                     $pi str_replace(':'.$paramurlencode($url->getParam($param,''))$pi);
  432.                 }
  433.                 $url->delParam($param);
  434.             }
  435.             $url->pathInfo $pi;
  436.             if ($urlinfo[6])
  437.                 $url->setParam('action',$action);
  438.             // removed parameters corresponding to static values
  439.             foreach ($urlinfo[7as $name=>$value{
  440.                 $url->delParam($name);
  441.             }
  442.         }
  443.         elseif ($urlinfo[0== 3{
  444.             if ($urlinfo[3]{
  445.                 $url->delParam('module');
  446.             }
  447.         }
  448.  
  449.         return $url;
  450.     }
  451. }

Documentation generated on Thu, 19 Sep 2013 00:09:21 +0200 by phpDocumentor 1.4.3