Source for file jSignificantUrlsCompiler.class.php

Documentation is available at jSignificantUrlsCompiler.class.php

  1. <?php
  2. /**
  3. * @package     jelix
  4. * @subpackage  urls_engine
  5. * @author      Laurent Jouanneau
  6. * @contributor Thibault PIRONT < nuKs >
  7. * @copyright   2005-2008 Laurent Jouanneau
  8. * @copyright   2007 Thibault PIRONT
  9. * @link        http://www.jelix.org
  10. * @licence     GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html
  11. */
  12.  
  13. /**
  14. * Compiler for significant url engine
  15. * @package  jelix
  16. * @subpackage urls_engine
  17. */
  18. class jSignificantUrlsCompiler implements jISimpleCompiler{
  19.  
  20.     public function compile($aSelector){
  21.         global $gJCoord;
  22.  
  23.         $sourceFile = $aSelector->getPath();
  24.         $cachefile = $aSelector->getCompiledFilePath();
  25.  
  26.  
  27.         // lecture du fichier xml
  28.         $xml = simplexml_load_file ( $sourceFile);
  29.         if(!$xml){
  30.            return false;
  31.         }
  32.         /*
  33.         <urls>
  34.          <classicentrypoint name="index" default="true">
  35.             <url pathinfo="/test/:mois/:annee" module="" action="">
  36.                   <param name="mois" escape="true" regexp="\d{4}"/>
  37.                   <param name="annee" escape="false" />
  38.                   <static name="bla" value="cequejeveux" />
  39.             </url>
  40.             <url handler="" module="" action=""  />
  41.          </classicentrypoint>
  42.         </urls>
  43.  
  44.          génère dans un fichier propre à chaque entrypoint :
  45.  
  46.             $PARSE_URL = array($isDefault , $infoparser,$infoparser... )
  47.  
  48.             où
  49.             $isDefault : indique si c'est un point d'entrée par défaut, et donc si le parser ne trouve rien,
  50.                             si il ignore ou fait une erreur
  51.  
  52.             $infoparser = array('module','action','selecteur handler')
  53.             ou
  54.             $infoparser = array( 'module','action', 'regexp_pathinfo',
  55.                array('annee','mois'), // tableau des valeurs dynamiques, classées par ordre croissant
  56.                array(true, false), // tableau des valeurs escapes
  57.                array('bla'=>'cequejeveux' ) // tableau des valeurs statiques
  58.             )
  59.  
  60.  
  61.          génère dans un fichier commun à tous :
  62.  
  63.             $CREATE_URL = array(
  64.                'news~show@classic' =>
  65.                   array(0,'entrypoint', https true/false, 'selecteur handler')
  66.                   ou
  67.                   array(1,'entrypoint', https true/false,
  68.                         array('annee','mois','jour','id','titre'), // liste des paramètres de l'url à prendre en compte
  69.                         array(true, false..), // valeur des escapes
  70.                         "/news/%1/%2/%3/%4-%5", // forme de l'url
  71.                         array('bla'=>'cequejeveux' ) // tableau des valeurs statiques, pour comparer 
  72.                                                      quand il y a plusieurs urls vers la même action
  73.                         )
  74.                    quand il y a plusieurs urls vers la même action, il y a plutôt un tableau contenant
  75.                     plusieurs tableaux du type précédent
  76.                     array( 4, array(1,...), array(1,...)...)
  77.  
  78.                   ou
  79.                   array(2,'entrypoint', https true/false); pour les clés du type "@request"
  80.                   array(3,'entrypoint', https true/false);  pour les clés du type  "module~@request"
  81.  
  82.         */
  83.         $typeparam = array('string'=>'([^\/]+)','char'=>'([^\/])', 'letter'=>'(\w)',
  84.            'number'=>'(\d+)', 'int'=>'(\d+)', 'integer'=>'(\d+)', 'digit'=>'(\d)',
  85.            'date'=>'([0-2]\d{3}\-(?:0[1-9]|1[0-2])\-(?:[0-2][1-9]|3[0-1]))', 
  86.             'year'=>'([0-2]\d{3})', 'month'=>'(0[1-9]|1[0-2])', 'day'=>'([0-2][1-9]|[1-2]0|3[0-1])'
  87.            );
  88.         $createUrlInfos=array();
  89.         $createUrlContent="<?php \n";
  90.         $defaultEntrypoints=array();
  91.  
  92.         foreach($xml->children() as $name=>$tag){
  93.            if(!preg_match("/^(.*)entrypoint$/", $name,$m)){
  94.                //TODO : erreur
  95.                continue;
  96.            }
  97.            $requestType= $m[1];
  98.            $entryPoint = (string)$tag['name'];
  99.            $isDefault =  (isset($tag['default']) ? (((string)$tag['default']) == 'true'):false);
  100.            $isHttps = (isset($tag['https']) ? (((string)$tag['https']) == 'true'):false);
  101.            $generatedentrypoint =$entryPoint;
  102.            if(isset($tag['noentrypoint']) && (string)$tag['noentrypoint'] == 'true')
  103.                 $generatedentrypoint = '';
  104.            $parseInfos = array($isDefault);
  105.  
  106.            // si c'est le point d'entrée par défaut pour le type de requet indiqué
  107.            // alors on indique une regle supplementaire que matcherons
  108.            // toutes les urls qui ne correspondent pas aux autres rêgles
  109.            if($isDefault){
  110.              $createUrlInfos['@'.$requestType]=array(2,$entryPoint, $isHttps);
  111.            }
  112.  
  113.            $parseContent = "<?php \n";
  114.            foreach($tag->url as $url){
  115.                $module = (string)$url['module'];
  116.                if(isset($url['https'])){
  117.                    $urlhttps=(((string)$url['https']) == 'true');
  118.                }else{
  119.                    $urlhttps=$isHttps;
  120.                }
  121.                if(isset($url['noentrypoint']) && ((string)$url['noentrypoint']) == 'true'){
  122.                    $urlep='';
  123.                }else{
  124.                    $urlep=$generatedentrypoint;
  125.                }
  126.                // dans le cas d'un point d'entrée qui n'est pas celui par défaut pour le type de requete indiqué
  127.                // si il y a juste un module indiqué alors on sait que toutes les actions
  128.                // concernant ce module passeront par ce point d'entrée.
  129.                if(!$isDefault && !isset($url['action']) && !isset($url['handler'])){
  130.                  $parseInfos[]=array($module, '', '/.*/', array(), array(), array(), false );
  131.                  $createUrlInfos[$module.'~*@'.$requestType] = array(3,$urlep, $urlhttps);
  132.                  continue;
  133.                }
  134.  
  135.                $action = (string)$url['action'];
  136.  
  137.                if (strpos($action, ':') === false) {
  138.                   $action = 'default:'.$action;
  139.                }
  140.  
  141.                if(isset($url['actionoverride'])){
  142.                   $actionOverride = preg_split("/[\s,]+/", (string)$url['actionoverride']);
  143.                   foreach ($actionOverride as &$each) {
  144.                      if (strpos($each, ':') === false) {
  145.                         $each = 'default:'.$each;
  146.                      }
  147.                   }
  148.                }else{
  149.                   $actionOverride = false;
  150.                }
  151.  
  152.                // si il y a un handler indiqué, on sait alors que pour le module et action indiqué
  153.                // il faut passer par cette classe handler pour le parsing et la creation de l'url
  154.                if(isset($url['handler'])){
  155.                   $class = (string)$url['handler'];
  156.                   // il faut absolument un nom de module dans le selecteur, car lors de l'analyse de l'url
  157.                   // dans le request, il n'y a pas de module connu dans le context (normal...)
  158.                   $p= strpos($class,'~');
  159.                   if($p === false)
  160.                     $selclass = $module.'~'.$class;
  161.                   elseif( $p == 0)
  162.                     $selclass = $module.$class;
  163.                   else
  164.                     $selclass = $class;
  165.                   $s= new jSelectorUrlHandler($selclass);
  166.                   if(!isset($url['action'])) {
  167.                     $action = '*';
  168.                   }
  169.                   $createUrlContent.="include_once('".$s->getPath()."');\n";
  170.                   $parseInfos[]=array($module, $action, $selclass, $actionOverride );
  171.                   $createUrlInfos[$module.'~'.$action.'@'.$requestType] = array(0,$urlep, $urlhttps, $selclass);
  172.                   if($actionOverride){
  173.                      foreach($actionOverride as $ao){
  174.                         $createUrlInfos[$module.'~'.$ao.'@'.$requestType] = array(0,$urlep,$urlhttps, $selclass);
  175.                      }
  176.                   }
  177.                   continue;
  178.                }
  179.  
  180.                $listparam=array();
  181.                $escapes = array();
  182.                if(isset($url['pathinfo'])){
  183.                   $path = (string)$url['pathinfo'];
  184.                   $regexppath = $path;
  185.  
  186.                   if(preg_match_all("/\:([a-zA-Z_]+)/",$path,$m, PREG_PATTERN_ORDER)){
  187.                       $listparam=$m[1];
  188.  
  189.                       foreach($url->param as $var){
  190.  
  191.                         $nom = (string) $var['name'];
  192.                         $k = array_search($nom, $listparam);
  193.                         if($k === false){
  194.                           // TODO error
  195.                           continue;
  196.                         }
  197.  
  198.                         if (isset ($var['escape'])){
  199.                             $escapes[$k] = (((string)$var['escape']) == 'true');
  200.                         }else{
  201.                             $escapes[$k] = false;
  202.                         }
  203.  
  204.                         if(isset($var['type'])){
  205.                            if(isset($typeparam[(string)$var['type']]))
  206.                               $regexp = $typeparam[(string)$var['type']];
  207.                            else
  208.                               $regexp = '([^\/]+)';
  209.                         }else if (isset ($var['regexp'])){
  210.                             $regexp = '('.(string)$var['regexp'].')';
  211.                         }else{
  212.                             $regexp = '([^\/]+)';
  213.                         }
  214.  
  215.                         $regexppath = str_replace(':'.$nom, $regexp, $regexppath);
  216.                       }
  217.  
  218.                       foreach($listparam as $k=>$name){
  219.                         if(isset($escapes[$k])){
  220.                            continue;
  221.                         }
  222.                         $escapes[$k] = false;
  223.                         $regexppath = str_replace(':'.$name, '([^\/]+)', $regexppath);
  224.                       }
  225.                   }
  226.                }else{
  227.                  $regexppath='.*';
  228.                  $path='';
  229.                }
  230.                if(isset($url['optionalTrailingSlash']) && $url['optionalTrailingSlash'] == 'true'){
  231.                     if(substr($regexppath, -1) == '/'){
  232.                         $regexppath.='?';
  233.                     }else{
  234.                         $regexppath.='\/?';
  235.                     }
  236.                }
  237.  
  238.                $liststatics = array();
  239.                foreach($url->static as $var){
  240.                   $liststatics[(string)$var['name']] =(string)$var['value'];
  241.                }
  242.                $parseInfos[]=array($module, $action, '!^'.$regexppath.'$!', $listparam, $escapes, $liststatics, $actionOverride );
  243.                $cuisel = $module.'~'.$action.'@'.$requestType;
  244.                $arr = array(1,$urlep, $urlhttps, $listparam, $escapes,$path, false, $liststatics);
  245.                if(isset($createUrlInfos[$cuisel])){
  246.                     if($createUrlInfos[$cuisel][0] == 4){
  247.                         $createUrlInfos[$cuisel][] = $arr;
  248.                     }else{
  249.                         $createUrlInfos[$cuisel] = array( 4, $createUrlInfos[$cuisel] , $arr);
  250.                     }
  251.                }else{
  252.                    $createUrlInfos[$cuisel] = $arr;
  253.                }
  254.                if($actionOverride){
  255.                   foreach($actionOverride as $ao){
  256.                      $cuisel = $module.'~'.$ao.'@'.$requestType;
  257.                      $arr = array(1,$urlep, $urlhttps, $listparam, $escapes,$path, true, $liststatics);
  258.                      if(isset($createUrlInfos[$cuisel])){
  259.                         if($createUrlInfos[$cuisel][0] == 4){
  260.                             $createUrlInfos[$cuisel][] = $arr;
  261.                         }else{
  262.                             $createUrlInfos[$cuisel] = array( 4, $createUrlInfos[$cuisel] , $arr);
  263.                         }
  264.                      }else{
  265.                         $createUrlInfos[$cuisel] = $arr;
  266.                      }
  267.                   }
  268.                }
  269.            }
  270.  
  271.            $parseContent.='$GLOBALS[\'SIGNIFICANT_PARSEURL\'][\''.rawurlencode($entryPoint).'\'] = '.var_export($parseInfos, true).";\n?>";
  272.  
  273.            jFile::write(JELIX_APP_TEMP_PATH.'compiled/urlsig/'.$aSelector->file.'.'.rawurlencode($entryPoint).'.entrypoint.php',$parseContent);
  274.         }
  275.         $createUrlContent .='$GLOBALS[\'SIGNIFICANT_CREATEURL\'] ='.var_export($createUrlInfos, true).";\n?>";
  276.         jFile::write(JELIX_APP_TEMP_PATH.'compiled/urlsig/'.$aSelector->file.'.creationinfos.php',$createUrlContent);
  277.         return true;
  278.     }
  279.  
  280. }

Documentation generated on Thu, 22 Mar 2012 22:17:16 +0100 by phpDocumentor 1.4.3