public function compile($aSelector)
 {
     global $gJCoord;
     $sourceFile = $aSelector->getPath();
     $cachefile = $aSelector->getCompiledFilePath();
     // lecture du fichier xml
     $xml = simplexml_load_file($sourceFile);
     if (!$xml) {
         return false;
     }
     /*
             <urls>
              <classicentrypoint name="index" default="true">
                 <url pathinfo="/test/:mois/:annee" module="" action="">
                       <param name="mois" escape="true" regexp="\d{4}"/>
                       <param name="annee" escape="false" />
                       <static name="bla" value="cequejeveux" />
                 </url>
                 <url handler="" module="" action=""  />
              </classicentrypoint>
             </urls>
      génère dans un fichier propre à chaque entrypoint :
         $PARSE_URL = array($isDefault , $infoparser,$infoparser... )
         où
                 $isDefault : indique si c'est un point d'entrée par défaut, et donc si le parser ne trouve rien,
                                 si il ignore ou fait une erreur
         $infoparser = array('module','action','selecteur handler')
                 ou
                 $infoparser = array( 'module','action', 'regexp_pathinfo',
                    array('annee','mois'), // tableau des valeurs dynamiques, classées par ordre croissant
                    array(true, false), // tableau des valeurs escapes
                    array('bla'=>'cequejeveux' ) // tableau des valeurs statiques
                 )
     
      génère dans un fichier commun à tous :
         $CREATE_URL = array(
                    'news~show@classic' =>
                       array(0,'entrypoint', https true/false, 'selecteur handler')
                       ou
                       array(1,'entrypoint', https true/false,
                             array('annee','mois','jour','id','titre'), // liste des paramètres de l'url à prendre en compte
                             array(true, false..), // valeur des escapes
                             "/news/%1/%2/%3/%4-%5", // forme de l'url
                             array('bla'=>'cequejeveux' ) // tableau des valeurs statiques, pour comparer 
                                                          quand il y a plusieurs urls vers la même action
                             )
                        quand il y a plusieurs urls vers la même action, il y a plutôt un tableau contenant
                         plusieurs tableaux du type précédent
                         array( 4, array(1,...), array(1,...)...)
               ou
                       array(2,'entrypoint', https true/false); pour les clés du type "@request"
                       array(3,'entrypoint', https true/false);  pour les clés du type  "module~@request"
     */
     $typeparam = array('string' => '([^\\/]+)', 'char' => '([^\\/])', 'letter' => '(\\w)', 'number' => '(\\d+)', 'int' => '(\\d+)', 'integer' => '(\\d+)', 'digit' => '(\\d)', 'date' => '([0-2]\\d{3}\\-(?:0[1-9]|1[0-2])\\-(?:[0-2][1-9]|3[0-1]))', 'year' => '([0-2]\\d{3})', 'month' => '(0[1-9]|1[0-2])', 'day' => '([0-2][1-9]|[1-2]0|3[0-1])');
     $createUrlInfos = array();
     $createUrlContent = "<?php \n";
     $defaultEntrypoints = array();
     foreach ($xml->children() as $name => $tag) {
         if (!preg_match("/^(.*)entrypoint\$/", $name, $m)) {
             //TODO : erreur
             continue;
         }
         $requestType = $m[1];
         $entryPoint = (string) $tag['name'];
         $isDefault = isset($tag['default']) ? (string) $tag['default'] == 'true' : false;
         $isHttps = isset($tag['https']) ? (string) $tag['https'] == 'true' : false;
         $generatedentrypoint = $entryPoint;
         if (isset($tag['noentrypoint']) && (string) $tag['noentrypoint'] == 'true') {
             $generatedentrypoint = '';
         }
         $parseInfos = array($isDefault);
         // si c'est le point d'entrée par défaut pour le type de requet indiqué
         // alors on indique une regle supplementaire que matcherons
         // toutes les urls qui ne correspondent pas aux autres rêgles
         if ($isDefault) {
             $createUrlInfos['@' . $requestType] = array(2, $entryPoint, $isHttps);
         }
         $parseContent = "<?php \n";
         foreach ($tag->url as $url) {
             $module = (string) $url['module'];
             if (isset($url['https'])) {
                 $urlhttps = (string) $url['https'] == 'true';
             } else {
                 $urlhttps = $isHttps;
             }
             if (isset($url['noentrypoint']) && (string) $url['noentrypoint'] == 'true') {
                 $urlep = '';
             } else {
                 $urlep = $generatedentrypoint;
             }
             // dans le cas d'un point d'entrée qui n'est pas celui par défaut pour le type de requete indiqué
             // si il y a juste un module indiqué alors on sait que toutes les actions
             // concernant ce module passeront par ce point d'entrée.
             if (!$isDefault && !isset($url['action']) && !isset($url['handler'])) {
                 $parseInfos[] = array($module, '', '/.*/', array(), array(), array(), false);
                 $createUrlInfos[$module . '~*@' . $requestType] = array(3, $urlep, $urlhttps);
                 continue;
             }
             $action = (string) $url['action'];
             if (strpos($action, ':') === false) {
                 $action = 'default:' . $action;
             }
             if (isset($url['actionoverride'])) {
                 $actionOverride = preg_split("/[\\s,]+/", (string) $url['actionoverride']);
                 foreach ($actionOverride as &$each) {
                     if (strpos($each, ':') === false) {
                         $each = 'default:' . $each;
                     }
                 }
             } else {
                 $actionOverride = false;
             }
             // si il y a un handler indiqué, on sait alors que pour le module et action indiqué
             // il faut passer par cette classe handler pour le parsing et la creation de l'url
             if (isset($url['handler'])) {
                 $class = (string) $url['handler'];
                 // il faut absolument un nom de module dans le selecteur, car lors de l'analyse de l'url
                 // dans le request, il n'y a pas de module connu dans le context (normal...)
                 $p = strpos($class, '~');
                 if ($p === false) {
                     $selclass = $module . '~' . $class;
                 } elseif ($p == 0) {
                     $selclass = $module . $class;
                 } else {
                     $selclass = $class;
                 }
                 $s = new jSelectorUrlHandler($selclass);
                 if (!isset($url['action'])) {
                     $action = '*';
                 }
                 $createUrlContent .= "include_once('" . $s->getPath() . "');\n";
                 $parseInfos[] = array($module, $action, $selclass, $actionOverride);
                 $createUrlInfos[$module . '~' . $action . '@' . $requestType] = array(0, $urlep, $urlhttps, $selclass);
                 if ($actionOverride) {
                     foreach ($actionOverride as $ao) {
                         $createUrlInfos[$module . '~' . $ao . '@' . $requestType] = array(0, $urlep, $urlhttps, $selclass);
                     }
                 }
                 continue;
             }
             $listparam = array();
             $escapes = array();
             if (isset($url['pathinfo'])) {
                 $path = (string) $url['pathinfo'];
                 $regexppath = $path;
                 if (preg_match_all("/\\:([a-zA-Z_]+)/", $path, $m, PREG_PATTERN_ORDER)) {
                     $listparam = $m[1];
                     foreach ($url->param as $var) {
                         $nom = (string) $var['name'];
                         $k = array_search($nom, $listparam);
                         if ($k === false) {
                             // TODO error
                             continue;
                         }
                         if (isset($var['escape'])) {
                             $escapes[$k] = (string) $var['escape'] == 'true';
                         } else {
                             $escapes[$k] = false;
                         }
                         if (isset($var['type'])) {
                             if (isset($typeparam[(string) $var['type']])) {
                                 $regexp = $typeparam[(string) $var['type']];
                             } else {
                                 $regexp = '([^\\/]+)';
                             }
                         } else {
                             if (isset($var['regexp'])) {
                                 $regexp = '(' . (string) $var['regexp'] . ')';
                             } else {
                                 $regexp = '([^\\/]+)';
                             }
                         }
                         $regexppath = str_replace(':' . $nom, $regexp, $regexppath);
                     }
                     foreach ($listparam as $k => $name) {
                         if (isset($escapes[$k])) {
                             continue;
                         }
                         $escapes[$k] = false;
                         $regexppath = str_replace(':' . $name, '([^\\/]+)', $regexppath);
                     }
                 }
             } else {
                 $regexppath = '.*';
                 $path = '';
             }
             if (isset($url['optionalTrailingSlash']) && $url['optionalTrailingSlash'] == 'true') {
                 if (substr($regexppath, -1) == '/') {
                     $regexppath .= '?';
                 } else {
                     $regexppath .= '\\/?';
                 }
             }
             $liststatics = array();
             foreach ($url->static as $var) {
                 $liststatics[(string) $var['name']] = (string) $var['value'];
             }
             $parseInfos[] = array($module, $action, '!^' . $regexppath . '$!', $listparam, $escapes, $liststatics, $actionOverride);
             $cuisel = $module . '~' . $action . '@' . $requestType;
             $arr = array(1, $urlep, $urlhttps, $listparam, $escapes, $path, false, $liststatics);
             if (isset($createUrlInfos[$cuisel])) {
                 if ($createUrlInfos[$cuisel][0] == 4) {
                     $createUrlInfos[$cuisel][] = $arr;
                 } else {
                     $createUrlInfos[$cuisel] = array(4, $createUrlInfos[$cuisel], $arr);
                 }
             } else {
                 $createUrlInfos[$cuisel] = $arr;
             }
             if ($actionOverride) {
                 foreach ($actionOverride as $ao) {
                     $cuisel = $module . '~' . $ao . '@' . $requestType;
                     $arr = array(1, $urlep, $urlhttps, $listparam, $escapes, $path, true, $liststatics);
                     if (isset($createUrlInfos[$cuisel])) {
                         if ($createUrlInfos[$cuisel][0] == 4) {
                             $createUrlInfos[$cuisel][] = $arr;
                         } else {
                             $createUrlInfos[$cuisel] = array(4, $createUrlInfos[$cuisel], $arr);
                         }
                     } else {
                         $createUrlInfos[$cuisel] = $arr;
                     }
                 }
             }
         }
         $parseContent .= '$GLOBALS[\'SIGNIFICANT_PARSEURL\'][\'' . rawurlencode($entryPoint) . '\'] = ' . var_export($parseInfos, true) . ";\n?>";
         jFile::write(JELIX_APP_TEMP_PATH . 'compiled/urlsig/' . $aSelector->file . '.' . rawurlencode($entryPoint) . '.entrypoint.php', $parseContent);
     }
     $createUrlContent .= '$GLOBALS[\'SIGNIFICANT_CREATEURL\'] =' . var_export($createUrlInfos, true) . ";\n?>";
     jFile::write(JELIX_APP_TEMP_PATH . 'compiled/urlsig/' . $aSelector->file . '.creationinfos.php', $createUrlContent);
     return true;
 }
Esempio n. 2
0
 /**
  *
  * @param string $scriptNamePath    /path/index.php
  * @param string $pathinfo          the path info part of the url (part between script name and query)
  * @param array  $params            url parameters (query part e.g. $_REQUEST)
  * @param boolean $isHttps          says if the given url is asked with https or not
  * @return jUrlAction
  */
 protected function _parse($scriptNamePath, $pathinfo, $params, $isHttps)
 {
     $urlact = null;
     $isDefault = false;
     $url = new jUrl($scriptNamePath, $params, $pathinfo);
     foreach ($this->dataParseUrl as $k => $infoparsing) {
         // the first element indicates if the entry point is a default entry point or not
         if ($k == 0) {
             $isDefault = $infoparsing;
             continue;
         }
         if (count($infoparsing) < 7) {
             // an handler will parse the request URI
             list($module, $action, $reg, $selectorHandler, $secondariesActions, $needHttps) = $infoparsing;
             $url2 = clone $url;
             if ($reg != '') {
                 if (preg_match($reg, $pathinfo, $m)) {
                     $url2->pathInfo = isset($m[1]) ? $m[1] : '/';
                 } else {
                     continue;
                 }
             }
             $s = new jSelectorUrlHandler($selectorHandler);
             include_once $s->getPath();
             $c = $s->className . 'UrlsHandler';
             $handler = new $c();
             $url2->params['module'] = $module;
             // if the action parameter exists in the current url
             // and if it is one of secondaries actions, then we keep it
             // else we take the action indicated in the url mapping
             if ($secondariesActions && isset($params['action'])) {
                 if (strpos($params['action'], ':') === false) {
                     $params['action'] = 'default:' . $params['action'];
                 }
                 if (in_array($params['action'], $secondariesActions)) {
                     // action peut avoir été écrasé par une itération précédente
                     $url2->params['action'] = $params['action'];
                 } else {
                     $url2->params['action'] = $action;
                 }
             } else {
                 $url2->params['action'] = $action;
             }
             // appel au handler
             if ($urlact = $handler->parse($url2)) {
                 break;
             }
         } elseif (preg_match($infoparsing[2], $pathinfo, $matches)) {
             /* we have this array
                             array( 0=>'module', 1=>'action', 2=>'regexp_pathinfo',
                             3=>array('year','month'), // list of dynamic value included in the url,
                                                   // alphabetical ascendant order
                             4=>array(0, 1..), // list of integer which indicates for each
                                             // dynamic value: 0: urlencode, 1:urlencode except '/', 2:escape, 4: lang, 8: locale
             
                             5=>array('bla'=>'whatIWant' ), // list of static values
                             6=>false or array('secondaries','actions')
                             */
             list($module, $action, $reg, $dynamicValues, $escapes, $staticValues, $secondariesActions, $needHttps) = $infoparsing;
             if (isset($params['module']) && $params['module'] !== $module) {
                 continue;
             }
             if ($module != '') {
                 $params['module'] = $module;
             }
             // if the action parameter exists in the current url
             // and if it is one of secondaries actions, then we keep it
             // else we take the action indicated in the url mapping
             if ($secondariesActions && isset($params['action'])) {
                 if (strpos($params['action'], ':') === false) {
                     $params['action'] = 'default:' . $params['action'];
                 }
                 if (!in_array($params['action'], $secondariesActions) && $action != '') {
                     $params['action'] = $action;
                 }
             } else {
                 if ($action != '') {
                     $params['action'] = $action;
                 }
             }
             // let's merge static parameters
             if ($staticValues) {
                 foreach ($staticValues as $n => $v) {
                     if (!empty($v) && $v[0] == '$') {
                         // special statique value
                         $typeStatic = $v[1];
                         $v = substr($v, 2);
                         if ($typeStatic == 'l') {
                             jApp::config()->locale = jLocale::langToLocale($v);
                         } else {
                             if ($typeStatic == 'L') {
                                 jApp::config()->locale = $v;
                             }
                         }
                     }
                     $params[$n] = $v;
                 }
             }
             // now let's read dynamic parameters
             if (count($matches)) {
                 array_shift($matches);
                 foreach ($dynamicValues as $k => $name) {
                     if (isset($matches[$k])) {
                         if ($escapes[$k] & 2) {
                             $params[$name] = jUrl::unescape($matches[$k]);
                         } else {
                             $params[$name] = $matches[$k];
                             if ($escapes[$k] & 4) {
                                 $v = $matches[$k];
                                 if (preg_match('/^\\w{2,3}$/', $v, $m)) {
                                     jApp::config()->locale = jLocale::langToLocale($v);
                                 } else {
                                     jApp::config()->locale = $v;
                                     $params[$name] = substr($v, 0, strpos('_'));
                                 }
                             } else {
                                 if ($escapes[$k] & 8) {
                                     $v = $matches[$k];
                                     if (preg_match('/^\\w{2,3}$/', $v, $m)) {
                                         jApp::config()->locale = $params[$name] = jLocale::langToLocale($v);
                                     } else {
                                         jApp::config()->locale = $v;
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             $urlact = new jUrlAction($params);
             break;
         }
     }
     if (!$urlact) {
         if ($isDefault && $pathinfo == '') {
             // if we didn't find the url in the mapping, and if this is the default
             // entry point, then we do anything
             $urlact = new jUrlAction($params);
         } else {
             try {
                 $urlact = jUrl::get(jApp::config()->urlengine['notfoundAct'], array(), jUrl::JURLACTION);
             } catch (Exception $e) {
                 $urlact = new jUrlAction(array('module' => 'jelix', 'action' => 'error:notfound'));
             }
         }
     } else {
         if ($needHttps && !$isHttps) {
             // the url is declared for HTTPS, but the request does not come from HTTPS
             // -> 404 not found
             $urlact = new jUrlAction(array('module' => 'jelix', 'action' => 'error:notfound'));
         }
     }
     return $urlact;
 }
 /**
  * @param significantUrlInfoParsing $u
  * @param simpleXmlElement $url
  */
 protected function newHandler($u, $url, $pathinfo = '')
 {
     $class = (string) $url['handler'];
     // we must have a module name in the selector, because, during the parsing of
     // the url in the request process, we are not still in a module context
     $p = strpos($class, '~');
     if ($p === false) {
         $selclass = $u->module . '~' . $class;
     } elseif ($p == 0) {
         $selclass = $u->module . $class;
     } else {
         $selclass = $class;
     }
     $s = new jSelectorUrlHandler($selclass);
     if (!isset($url['action'])) {
         $u->action = '*';
     }
     $regexp = '';
     if (isset($url['pathinfo'])) {
         $pathinfo .= '/' . trim((string) $url['pathinfo'], '/');
     }
     if ($pathinfo != '/') {
         $regexp = '!^' . preg_quote($pathinfo, '!') . '(/.*)?$!';
     }
     $this->createUrlContentInc .= "include_once('" . $s->getPath() . "');\n";
     $this->parseInfos[] = array($u->module, $u->action, $regexp, $selclass, $u->actionOverride, $this->checkHttps && $u->isHttps);
     $this->createUrlInfos[$u->getFullSel()] = array(0, $u->entryPointUrl, $u->isHttps, $selclass, $pathinfo);
     if ($u->actionOverride) {
         foreach ($u->actionOverride as $ao) {
             $u->action = $ao;
             $this->createUrlInfos[$u->getFullSel()] = array(0, $u->entryPointUrl, $u->isHttps, $selclass, $pathinfo);
         }
     }
 }
Esempio n. 4
0
 protected function _parse($scriptNamePath, $pathinfo, $params, $isHttps)
 {
     $urlact = null;
     $isDefault = false;
     $url = new jUrl($scriptNamePath, $params, $pathinfo);
     foreach ($this->dataParseUrl as $k => $infoparsing) {
         if ($k == 0) {
             $isDefault = $infoparsing;
             continue;
         }
         if (count($infoparsing) < 7) {
             list($module, $action, $reg, $selectorHandler, $secondariesActions, $needHttps) = $infoparsing;
             $url2 = clone $url;
             if ($reg != '') {
                 if (preg_match($reg, $pathinfo, $m)) {
                     $url2->pathInfo = isset($m[1]) ? $m[1] : '/';
                 } else {
                     continue;
                 }
             }
             $s = new jSelectorUrlHandler($selectorHandler);
             include_once $s->getPath();
             $c = $s->className . 'UrlsHandler';
             $handler = new $c();
             $url2->params['module'] = $module;
             if ($secondariesActions && isset($params['action'])) {
                 if (strpos($params['action'], ':') === false) {
                     $params['action'] = 'default:' . $params['action'];
                 }
                 if (in_array($params['action'], $secondariesActions)) {
                     $url2->params['action'] = $params['action'];
                 } else {
                     $url2->params['action'] = $action;
                 }
             } else {
                 $url2->params['action'] = $action;
             }
             if ($urlact = $handler->parse($url2)) {
                 break;
             }
         } elseif (preg_match($infoparsing[2], $pathinfo, $matches)) {
             list($module, $action, $reg, $dynamicValues, $escapes, $staticValues, $secondariesActions, $needHttps) = $infoparsing;
             if (isset($params['module']) && $params['module'] !== $module) {
                 continue;
             }
             if ($module != '') {
                 $params['module'] = $module;
             }
             if ($secondariesActions && isset($params['action'])) {
                 if (strpos($params['action'], ':') === false) {
                     $params['action'] = 'default:' . $params['action'];
                 }
                 if (!in_array($params['action'], $secondariesActions) && $action != '') {
                     $params['action'] = $action;
                 }
             } else {
                 if ($action != '') {
                     $params['action'] = $action;
                 }
             }
             if ($staticValues) {
                 foreach ($staticValues as $n => $v) {
                     if ($v[0] == '$') {
                         $typeStatic = $v[1];
                         $v = substr($v, 2);
                         if ($typeStatic == 'l') {
                             jApp::config()->locale = jLocale::langToLocale($v);
                         } else {
                             if ($typeStatic == 'L') {
                                 jApp::config()->locale = $v;
                             }
                         }
                     }
                     $params[$n] = $v;
                 }
             }
             if (count($matches)) {
                 array_shift($matches);
                 foreach ($dynamicValues as $k => $name) {
                     if (isset($matches[$k])) {
                         if ($escapes[$k] & 2) {
                             $params[$name] = jUrl::unescape($matches[$k]);
                         } else {
                             $params[$name] = $matches[$k];
                             if ($escapes[$k] & 4) {
                                 $v = $matches[$k];
                                 if (preg_match('/^\\w{2,3}$/', $v, $m)) {
                                     jApp::config()->locale = jLocale::langToLocale($v);
                                 } else {
                                     jApp::config()->locale = $v;
                                     $params[$name] = substr($v, 0, strpos('_'));
                                 }
                             } else {
                                 if ($escapes[$k] & 8) {
                                     $v = $matches[$k];
                                     if (preg_match('/^\\w{2,3}$/', $v, $m)) {
                                         jApp::config()->locale = $params[$name] = jLocale::langToLocale($v);
                                     } else {
                                         jApp::config()->locale = $v;
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             $urlact = new jUrlAction($params);
             break;
         }
     }
     if (!$urlact) {
         if ($isDefault && $pathinfo == '') {
             $urlact = new jUrlAction($params);
         } else {
             try {
                 $urlact = jUrl::get(jApp::config()->urlengine['notfoundAct'], array(), jUrl::JURLACTION);
             } catch (Exception $e) {
                 $urlact = new jUrlAction(array('module' => 'jelix', 'action' => 'error:notfound'));
             }
         }
     } else {
         if ($needHttps && !$isHttps) {
             $urlact = new jUrlAction(array('module' => 'jelix', 'action' => 'error:notfound'));
         }
     }
     return $urlact;
 }