[ PHPXref.com ] [ Generated: Sun Jul 20 20:25:42 2008 ] [ SPIP 1.8.3 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/ -> inc-compilo.php3 (source)

   1  <?php
   2  
   3  /***************************************************************************\
   4   *  SPIP, Systeme de publication pour l'internet                           *
   5   *                                                                         *
   6   *  Copyright (c) 2001-2005                                                *
   7   *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
   8   *                                                                         *
   9   *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
  10   *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
  11  \***************************************************************************/
  12  
  13  
  14  //
  15  // Fichier principal du compilateur de squelettes
  16  //
  17  
  18  // Ce fichier ne sera execute qu'une fois
  19  if (defined("_INC_COMPILO")) return;
  20  define("_INC_COMPILO", "1");
  21  
  22  // reperer un code ne calculant rien, meme avec commentaire
  23  define('CODE_MONOTONE', "^(\n//[^\n]*\n)?\(?'([^'])*'\)?$");
  24  
  25  // Definition de la structure $p, et fonctions de recherche et de reservation
  26  // dans l'arborescence des boucles
  27  include_local("inc-compilo-index.php3");  # index ? structure ? pile ?
  28  
  29  // definition des boucles
  30  include_local("inc-boucles.php3");
  31  
  32  // definition des criteres
  33  include_local("inc-criteres.php3");
  34  
  35  // definition des balises
  36  include_local("inc-balises.php3");
  37  
  38  // definition de l'API
  39  include_local("inc-compilo-api.php3");
  40  
  41  # definition des tables
  42  include_ecrire('inc_serialbase.php3');
  43  
  44  // outils pour debugguer le compilateur
  45  #include_local("inc-compilo-debug.php3"); # desactive
  46  
  47  //
  48  // Calculer un <INCLURE()>
  49  //
  50  function calculer_inclure($struct, $descr, &$boucles, $id_boucle) {
  51      $fichier = $struct->texte;
  52  
  53      if (!($path = find_in_path($fichier)))
  54        {
  55          spip_log("ERREUR: <INCLURE($fichier)> impossible");
  56          erreur_squelette(_T('zbug_info_erreur_squelette'),
  57                   "&lt;INCLURE($fichier)&gt; - "
  58                   ._T('fichier_introuvable', array('fichier' => $fichier)));
  59          return "'<!-- Erreur INCLURE(".texte_script($fichier).") -->'";
  60      }
  61  
  62      $l = array();
  63      foreach($struct->param as $val) {
  64          $var = array_shift($val);
  65          $l[] = "\'$var\' => \'' . addslashes(" .
  66              ($val ? calculer_liste($val[0], $descr, $boucles, $id_boucle) :
  67              (($var =='lang') ?
  68               '$GLOBALS["spip_lang"]' :
  69               index_pile($id_boucle, $var, $boucles)))
  70              . ") . '\\'";
  71          }
  72  
  73      return "\n'<".
  74          "?php\n\t\$contexte_inclus = array(" .
  75          join(",\n\t",$l) .
  76          ");" .
  77          "\n\tinclude(\\'$path\\');" .
  78          "\n?'." . "'>'";
  79   }
  80  
  81  //
  82  // calculer_boucle() produit le corps PHP d'une boucle Spip 
  83  // Sauf pour les recursives, ce corps est un Select SQL + While PHP
  84  // remplissant une variable $t0 retournee en valeur
  85  //
  86  function calculer_boucle($id_boucle, &$boucles) {
  87  
  88    $boucle = &$boucles[$id_boucle];
  89    $return = $boucle->return;
  90    $type_boucle = $boucle->type_requete;
  91  
  92    if ($type_boucle == 'boucle') {
  93          $corps = "\n    \$t0 = " . $return . ";";
  94          $init = "";
  95    } else {
  96      $primary = $boucle->primary;
  97      $constant = ereg(CODE_MONOTONE,$return);
  98  
  99      // Cas {1/3} {1,4} {n-2,1}...
 100  
 101      $flag_cpt = $boucle->mode_partie || // pas '$compteur' a cause du cas 0
 102        strpos($return,'compteur_boucle');
 103  
 104      //
 105      // Creer le debut du corps de la boucle :
 106      //
 107      $corps = '';
 108      if ($flag_cpt)
 109          $corps = "\n        \$Numrows['$id_boucle']['compteur_boucle']++;";
 110  
 111      if ($boucle->mode_partie)
 112          $corps .= "
 113          if (\$Numrows['$id_boucle']['compteur_boucle']-1 >= \$debut_boucle
 114          AND \$Numrows['$id_boucle']['compteur_boucle']-1 <= \$fin_boucle) {";
 115      
 116      // Calculer les invalideurs si c'est une boucle non constante
 117  
 118      if ($primary && !$constant)
 119          $corps .= "\n\t\t\$Cache['$primary'][" .
 120            (($primary != 'id_forum')  ? 
 121             index_pile($id_boucle, $primary, $boucles) :
 122             ("calcul_index_forum(" . 
 123          // Retournera 4 [$SP] mais force la demande du champ a MySQL
 124              index_pile($id_boucle, 'id_article', $boucles) . ',' .
 125              index_pile($id_boucle, 'id_breve', $boucles) .  ',' .
 126              index_pile($id_boucle, 'id_rubrique', $boucles) .',' .
 127              index_pile($id_boucle, 'id_syndic', $boucles) .
 128              ")")) .
 129            "] = 1; // invalideurs\n";
 130  
 131      if ($boucle->doublons)
 132          $corps .= "        \$doublons[".$boucle->doublons."] .= ','. " .
 133          index_pile($id_boucle, $primary, $boucles)
 134          . "; // doublons\n";
 135  
 136  
 137      if (count($boucle->separateur))
 138        $code_sep = ("'" . ereg_replace("'","\'",join('',$boucle->separateur)) . "'"); 
 139  
 140      $init = '';
 141      $fin = '';
 142  
 143      // La boucle doit-elle selectionner la langue ?
 144      // -. par defaut, les boucles suivantes le font
 145      // "peut-etre", c'est-a-dire si forcer_lang == false.
 146      // - . a moins d'une demande explicite
 147      if (!$constant && $boucle->lang_select != 'non' &&
 148          (($boucle->lang_select == 'oui')  ||
 149              (
 150              $type_boucle == 'articles'
 151              OR $type_boucle == 'rubriques'
 152              OR $type_boucle == 'hierarchie'
 153              OR $type_boucle == 'breves'
 154              )))
 155        {
 156            $corps .= 
 157            (($boucle->lang_select != 'oui') ? 
 158              "\t\tif (!\$GLOBALS['forcer_lang'])\n\t " : '')
 159            . "\t\t\$GLOBALS['spip_lang'] = (\$x = "
 160            . index_pile($id_boucle, 'lang', $boucles)
 161            . ') ? $x : $old_lang;';
 162          // Memoriser la langue avant la boucle pour la restituer apres
 163            $init .= "\n    \$old_lang = \$GLOBALS['spip_lang'];";
 164            $fin .= "\n    \$GLOBALS['spip_lang'] = \$old_lang;";
 165  
 166        }
 167  
 168      // gestion optimale des separateurs et des boucles constantes
 169      $corps .= 
 170          ((!$boucle->separateur) ? 
 171              (($constant && !$corps) ? $return :
 172                   ("\n\t\t" . '$t0 .= ' . $return . ";")) :
 173           ("\n\t\t\$t1 " .
 174              ((strpos($return, '$t1.') === 0) ? 
 175               (".=" . substr($return,4)) :
 176               ('= ' . $return)) .
 177            ";\n\t\t" .
 178            '$t0 .= (($t1 && $t0) ? ' . $code_sep . " : '') . \$t1;"));
 179       
 180      // Fin de parties
 181      if ($boucle->mode_partie)
 182          $corps .= "\n        }\n";
 183  
 184      // Gestion de la hierarchie (voir inc-boucles.php3)
 185      if ($boucle->hierarchie)
 186          $init .= "\n    ".$boucle->hierarchie;
 187  
 188      // si le corps est une constante, ne pas appeler le serveur N fois!
 189      if (ereg(CODE_MONOTONE,$corps, $r)) {
 190          if (!$r[2]) {
 191              if (!$boucle->numrows)
 192                  return 'return "";';
 193              else
 194                  $corps = "";
 195          } else {
 196              $boucle->numrows = true;
 197              $corps = "\n    ".'for($x=$Numrows["'.$id_boucle.'"]["total"];$x>0;$x--)
 198              $t0 .= ' . $corps .';';
 199          }
 200      } else {
 201  
 202          $corps = '
 203  
 204      // RESULTATS
 205      while ($Pile[$SP] = @spip_abstract_fetch($result,"' .
 206            $boucle->sql_serveur .
 207            '")) {' . 
 208            "\n$corps\n    }\n" .
 209            $fin ;
 210      }
 211  
 212      //
 213      // Requete
 214      //
 215  
 216      if (!$order = $boucle->order
 217      AND !$order = $boucle->default_order)
 218          $order = array();
 219  
 220      $init .= $boucle->hash . 
 221        "\n\n    // REQUETE
 222      \$result = spip_abstract_select(\n\t\tarray(\"". 
 223          # En absence de champ c'est un decompte : 
 224            # prendre la primary pour avoir qqch
 225            # (COUNT incompatible avec le cas general
 226          ($boucle->select ? 
 227           join("\",\n\t\t\"", $boucle->select) :
 228           ($boucle->id_table . "." .
 229           (($p = strpos($primary, ',')) ?
 230            substr($primary, 0, $p) : $primary))) .
 231          '"), # SELECT
 232          array("' .
 233          join('","', array_unique($boucle->from)) .
 234          '"), # FROM
 235          array(' .
 236          (!$boucle->where ? '' : ( '"' . join('",
 237          "', $boucle->where) . '"')) .
 238          "), # WHERE
 239          '".addslashes($boucle->group)."', # GROUP
 240          array(" .
 241            join(', ', $order) .
 242          "), # ORDER
 243          " . (strpos($boucle->limit, 'intval') === false ?
 244              "'".$boucle->limit."'" :
 245              $boucle->limit). ", # LIMIT
 246          '".$boucle->sous_requete."', # sous
 247          '" . (!$boucle->having ? "" : "(COUNT(*)> $boucle->having)")."', # HAVING
 248          '".$boucle->id_table."', # table
 249          '".$boucle->id_boucle."', # boucle
 250          '".$boucle->sql_serveur."'); # serveur";
 251  
 252      $init .= "\n    ".'$t0 = "";
 253      $SP++;';
 254      if ($flag_cpt)
 255          $init .= "\n    \$Numrows['$id_boucle']['compteur_boucle'] = 0;";
 256  
 257      if ($boucle->mode_partie)
 258          $init .= calculer_parties($boucles, $id_boucle);
 259      else if ($boucle->numrows)
 260          $init .= "\n    \$Numrows['" .
 261              $id_boucle .
 262              "']['total'] = @spip_abstract_count(\$result,'" .
 263              $boucle->sql_serveur .
 264              "');";
 265  
 266      //
 267      // Conclusion et retour
 268      //
 269      $corps .= "\n    @spip_abstract_free(\$result,'" .
 270           $boucle->sql_serveur . "');";
 271  
 272    }
 273  
 274    return $init . $corps . 
 275      ## inserer le code d'envoi au debusqueur du resultat de la fonction
 276      (($GLOBALS['var_mode_affiche'] != 'resultat') ? "" : "
 277          boucle_debug_resultat('$id_boucle', 'resultat', \$t0);") .
 278      "\n    return \$t0;";
 279  
 280  
 281  }
 282  
 283  
 284  //
 285  // fonction traitant les criteres {1,n} (analyses dans inc-criteres)
 286  //
 287  ## a deplacer dans inc-criteres ??
 288  function calculer_parties($boucles, $id_boucle) {
 289  
 290      $boucle = &$boucles[$id_boucle];
 291      $partie = $boucle->partie;
 292      $mode_partie = $boucle->mode_partie;
 293      $total_parties = $boucle->total_parties;
 294  
 295      // Notes :
 296      // $debut_boucle et $fin_boucle sont les indices SQL du premier
 297      // et du dernier demandes dans la boucle : 0 pour le premier,
 298      // n-1 pour le dernier ; donc total_boucle = 1 + debut - fin
 299  
 300      // nombre total avant partition
 301      $retour = "\n\n    // Partition\n    " .
 302          '$nombre_boucle = @spip_abstract_count($result,"' .
 303          $boucle->sql_serveur .
 304          '");';
 305  
 306      ereg("([+-/])([+-/])?", $mode_partie, $regs);
 307      list(,$op1,$op2) = $regs;
 308  
 309      // {1/3}
 310      if ($op1 == '/') {
 311          $pmoins1 = is_numeric($partie) ? ($partie-1) : "($partie-1)";
 312          $totpos = is_numeric($total_parties) ? ($total_parties) :
 313            "($total_parties ? $total_parties : 1)";
 314          $retour .= "\n    "
 315            .'$debut_boucle = ceil(($nombre_boucle * '
 316            . $pmoins1 . ')/' . $totpos . ");";
 317          $fin = 'ceil (($nombre_boucle * '
 318              . $partie . ')/' . $totpos . ") - 1";
 319      }
 320  
 321      // {1,x}
 322      elseif ($op1 == '+') {
 323          $retour .= "\n    "
 324              . '$debut_boucle = ' . $partie . ';';
 325      }
 326      // {n-1,x}
 327      elseif ($op1 == '-') {
 328          $retour .= "\n    "
 329              . '$debut_boucle = $nombre_boucle - ' . $partie . ';';
 330      }
 331      // {x,1}
 332      if ($op2 == '+') {
 333          $fin = '$debut_boucle'
 334            . (is_numeric($total_parties) ?
 335               (($total_parties==1) ? "" :(' + ' . ($total_parties-1))):
 336               ('+' . $total_parties . ' - 1'));
 337      }
 338      // {x,n-1}
 339      elseif ($op2 == '-') {
 340          $fin = '$debut_boucle + $nombre_boucle - '
 341            . (is_numeric($total_parties) ? ($total_parties+1) :
 342               ($total_parties . ' - 1'));
 343      }
 344  
 345      // Rabattre $fin_boucle sur le maximum
 346      $retour .= "\n    "
 347          .'$fin_boucle = min(' . $fin . ', $nombre_boucle - 1);';
 348  
 349      // calcul du total boucle final
 350      $retour .= "\n    "
 351          .'$Numrows[\''.$id_boucle.'\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);';
 352  
 353      return $retour;
 354  }
 355  
 356  // Production du code PHP a partir de la sequence livree par le phraseur
 357  // $boucles est passe par reference pour affectation par index_pile.
 358  // Retourne une expression PHP,
 359  // (qui sera argument d'un Return ou la partie droite d'une affectation).
 360  
 361  function calculer_liste($tableau, $descr, &$boucles, $id_boucle='') {
 362      if (!$tableau) return "''";
 363      $codes = compile_cas($tableau, $descr, $boucles, $id_boucle);
 364      $n = count($codes);
 365      if (!$n) return "''";
 366      if ($GLOBALS['var_mode_affiche'] != 'validation')
 367        return
 368          (($n==1) ? $codes[0] : 
 369               "(" . join (" .\n$tab", $codes) . ")");
 370      else return "debug_sequence('$id_boucle', '" .
 371        ($descr['nom']) .
 372        "', " .
 373        intval($descr['niv']) .
 374        ",  array(" .
 375        join(" ,\n$tab", $codes) . "))";
 376  }
 377  
 378  function compile_cas($tableau, $descr, &$boucles, $id_boucle='') {
 379          $codes = array();
 380      // cas de la boucle recursive
 381      if (is_array($id_boucle)) 
 382        $id_boucle = $id_boucle[0];
 383      $type = $boucles[$id_boucle]->type_requete;
 384      $descr['niv']++;
 385      for ($i=0; $i<=$descr['niv']; $i++) $tab .= "\t";
 386  
 387      // chaque commentaire introduit dans le code doit commencer
 388      // par un caractere distinguant le cas, pour exploitation par debug.
 389      foreach ($tableau as $p) {
 390  
 391          switch($p->type) {
 392          // texte seul
 393          case 'texte':
 394              $code = "'".ereg_replace("([\\\\'])", "\\\\1", $p->texte)."'";
 395  
 396              $commentaire= strlen($p->texte) . " signes";
 397              $avant='';
 398              $apres='';
 399              $altern = "''";
 400              break;
 401  
 402          case 'polyglotte':
 403              $code = "";
 404              foreach($p->traductions as $k => $v) {
 405                $code .= ",'" .
 406                  ereg_replace("([\\\\'])", "\\\\1", $k) .
 407                  "' => '" .
 408                  ereg_replace("([\\\\'])", "\\\\1", $v) .
 409                  "'";
 410              }
 411              $code = "multi_trad(array(" .
 412                 substr($code,1) .
 413                "))";
 414              $commentaire= '&';
 415              $avant='';
 416              $apres='';
 417              $altern = "''";
 418              break;
 419  
 420          // inclure
 421          case 'include':
 422              $code = calculer_inclure($p, $descr, $boucles, $id_boucle);
 423              $commentaire = '!' . $p->texte;
 424              $avant='';
 425              $apres='';
 426              $altern = "''";
 427              break;
 428  
 429          // boucle
 430          case 'boucle':
 431              $nom = $p->id_boucle;
 432              $newdescr = $descr;
 433              $newdescr['id_mere'] = $nom;
 434              $newdescr['niv']++;
 435              $code = 'BOUCLE' .
 436                ereg_replace("-","_", $nom) . $descr['nom'] .
 437                '($Cache, $Pile, $doublons, $Numrows, $SP)';
 438              $commentaire= "?$nom";
 439              $avant = calculer_liste($p->avant,
 440                  $newdescr, $boucles, $id_boucle);
 441              $apres = calculer_liste($p->apres,
 442                  $newdescr, $boucles, $id_boucle);
 443              $newdescr['niv']--;
 444              $altern = calculer_liste($p->altern,
 445                  $newdescr, $boucles, $id_boucle);
 446              break;
 447  
 448          case 'idiome':
 449              $p->code = "_T('" . $p->module . ":" .$p->nom_champ . "')";
 450              $p->id_boucle = $id_boucle;
 451              $p->boucles = &$boucles;
 452              $p->statut = 'php'; // ne pas manger les espaces avec trim()
 453              $commentaire = ":";
 454              $code = applique_filtres($p);
 455              $avant='';
 456              $apres='';
 457              $altern = "''";
 458              break;
 459  
 460          case 'champ':
 461  
 462              // cette structure pourrait etre completee des le phrase' (a faire)
 463              $p->id_boucle = $id_boucle;
 464              $p->boucles = &$boucles;
 465              $p->descr = $descr;
 466              $p->statut = 'html';
 467              $p->type_requete = $type;
 468  
 469              $code = calculer_champ($p);
 470              $commentaire = '#' . $p->nom_champ . $p->etoile;
 471              $avant = calculer_liste($p->avant,
 472                  $descr, $boucles, $id_boucle);
 473              $apres = calculer_liste($p->apres,
 474                  $descr, $boucles, $id_boucle);
 475              $altern = "''";
 476              break;
 477  
 478          default: 
 479            erreur_squelette(_T('zbug_info_erreur_squelette'));
 480          } // switch
 481  
 482          if ($avant == "''") $avant = '';
 483          if ($apres == "''") $apres = '';
 484          if ($avant||$apres||($altern!="''"))
 485            {
 486              $t = '$t' . $descr['niv'];
 487              $res = (!$avant ? "" : "$avant . ") . 
 488                $t .
 489                (!$apres ? "" : " . $apres");
 490              $code = "(($t = $code) ?\n\t$tab($res) :\n\t$tab($altern))";
 491            }
 492          if ($code != "''")
 493            $codes[]= (($GLOBALS['var_mode_affiche'] == 'validation') ?
 494                   "array(" . $p->ligne . ", '$commentaire', $code)"
 495                   : (($GLOBALS['var_mode_affiche'] == 'code') ?
 496                  "\n// $commentaire\n$code" :
 497                  $code));
 498      } // foreach
 499      return $codes;
 500  }
 501  
 502  // affichage du code produit
 503  
 504  function code_boucle(&$boucles, $id, $nom)
 505  {
 506      $boucle = &$boucles[$id];
 507  
 508      // Indiquer la boucle en commentaire
 509      $pretty = '';
 510  
 511      if ($boucle->type_requete != 'boucle')
 512        {
 513          // Resynthetiser les criteres
 514          foreach ($boucle->param as $param) {
 515            $s = "";
 516            $sep = "";
 517            foreach ($param as $t) {
 518          if (is_array($t)) { // toujours vrai normalement
 519            $s .= $sep;
 520            $c = $t[0];
 521            if ($c->apres)
 522              $s .= ($c->apres . $c->texte . $c->apres);
 523            else {
 524          // faudrait decompiler aussi les balises...
 525              foreach ($t as $c)
 526                $s .=  ($c->type == 'texte') ? $c->texte : '#...';
 527            }
 528            $sep = ", ";
 529          }
 530            }
 531            $pretty .= ' {' . $s . '}';
 532          }
 533        }
 534  
 535      $pretty = "BOUCLE$id(".strtoupper($boucle->type_requete) . ")" .
 536          ereg_replace("[\r\n]", " ", $pretty);
 537  
 538      return $pretty;    
 539  }
 540  
 541  
 542  // Prend en argument le source d'un squelette, sa grammaire et un nom.
 543  // Retourne une fonction PHP/SQL portant ce nom et calculant une page HTML.
 544  // Pour appeler la fonction produite, lui fournir 2 tableaux de 1 e'le'ment:
 545  // - 1er: element 'cache' => nom (du fichier ou` mettre la page)
 546  // - 2e: element 0 contenant un environnement ('id_article => $id_article, etc)
 547  // Elle retourne alors un tableau de 4 e'le'ments:
 548  // - 'texte' => page HTML, application du squelette a` l'environnement;
 549  // - 'squelette' => le nom du squelette
 550  // - 'process_ins' => 'html' ou 'php' selon la pre'sence de PHP dynamique
 551  // - 'invalideurs' =>  de'pendances de cette page, pour invalider son cache.
 552  // (voir son utilisation, optionnelle, dans invalideur.php)
 553  // En cas d'erreur, elle retourne un tableau des 2 premiers elements seulement
 554  
 555  function calculer_squelette($squelette, $nom, $gram, $sourcefile) {
 556  # 3 variables qui sont en fait des constantes après chargement
 557    global $table_primary, $table_des_tables, $tables_des_serveurs_sql;
 558      // Phraser le squelette, selon sa grammaire
 559      // pour le moment: "html" seul connu (HTML+balises BOUCLE)
 560      $boucles = array();
 561      spip_timer('calcul_skel');
 562  
 563      include_local("inc-$gram-squel.php3");
 564  
 565      $racine = phraser($squelette, '',$boucles, $nom);
 566  
 567      // tableau des informations sur le squelette
 568      $descr = array('nom' => $nom, 'documents' => false, 'sourcefile' => $sourcefile);
 569  
 570      // une boucle documents est conditionnee par tout le reste!
 571      foreach($boucles as $idb => $boucle) {
 572          if (($boucle->type_requete == 'documents') && $boucle->doublons)
 573              { $descr['documents'] = true; break; }
 574      }
 575      // Commencer par reperer les boucles appelees explicitement 
 576      // car elles indexent les arguments de maniere derogatoire
 577      foreach($boucles as $id => $boucle) { 
 578          if ($boucle->type_requete == 'boucle') {
 579              $rec = &$boucles[$boucle->param[0]];
 580              if (!$rec) {
 581                  return array(_T('zbug_info_erreur_squelette'),
 582                          ($boucle->param[0]
 583                          . ' '. _T('zbug_boucle_recursive_undef')));
 584              } else {
 585                  $rec->externe = $id;
 586                  $descr['id_mere'] = $id;
 587                  $boucles[$id]->return =
 588                          calculer_liste(array($rec),
 589                               $descr,
 590                               $boucles,
 591                               $boucle->param);
 592              }
 593          }
 594      }
 595      foreach($boucles as $id => $boucle) { 
 596          $type = $boucle->type_requete;
 597          if ($type != 'boucle') {
 598              $boucles[$id]->id_table = $table_des_tables[$type];
 599              if ($boucles[$id]->id_table) {
 600                  $boucles[$id]->primary = $table_primary[$type];
 601              } else { 
 602                  // table non Spip.
 603                  $boucles[$id]->id_table = $type;
 604                  $serveur = $boucle->sql_serveur;
 605                  $x = &$tables_des_serveurs_sql[$serveur ? $serveur : 'localhost'][$type]['key'];
 606                  $boucles[$id]->primary = ($x["PRIMARY KEY"] ? $x["PRIMARY KEY"] : $x["KEY"]);
 607              }
 608              if ($boucle->param) {
 609                  $res = calculer_criteres($id, $boucles);
 610                  if (is_array($res)) return $res; # erreur
 611              }
 612              $descr['id_mere'] = $id;
 613              $boucles[$id]->return =
 614                calculer_liste($boucle->milieu,
 615                       $descr,
 616                       $boucles,
 617                       $id);
 618              }
 619      }
 620  
 621      // idem pour la racine
 622      $descr['id_mere'] = '';
 623      $corps = calculer_liste($racine, $descr, $boucles);
 624  
 625      // Calcul du corps de toutes les fonctions PHP,
 626      // en particulier les requetes SQL et TOTAL_BOUCLE
 627      // de'terminables seulement maintenant
 628      //  Les 4 premiers parame`tres sont passe's par re'fe'rence
 629      // (les 1er et 3e pour modif, les 2 et 4 pour gain de place)
 630  
 631      foreach($boucles as $id => $boucle) {
 632          // appeler la fonction de definition de la boucle
 633          $f = 'boucle_'.strtoupper($boucle->type_requete);
 634          // si pas de definition perso, definition spip
 635          if (!function_exists($f)) $f = $f.'_dist';
 636          // laquelle a une definition par defaut
 637          if (!function_exists($f)) $f = 'boucle_DEFAUT';
 638          $boucles[$id]->return = 
 639              "function BOUCLE" . ereg_replace("-","_",$id) . $nom .
 640              '(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' .
 641              $f($id, $boucles) .
 642              "\n}\n\n";
 643          if ($GLOBALS['var_mode'] == 'debug')
 644            boucle_debug_compile ($id, $nom, $boucles[$id]->return);
 645  
 646      }
 647  
 648      $code = "";
 649      foreach($boucles as $id => $boucle) {
 650          $code .= "\n//\n// <BOUCLE " .
 651  #          code_boucle($boucles, $id, $nom). # pas au point
 652            $boucle->type_requete .
 653            ">\n//\n" .
 654            $boucle->return;
 655      }
 656  
 657      $secondes = spip_timer('calcul_skel');
 658      spip_log("calcul skel $sourcefile ($secondes)");
 659  
 660      $squelette_compile = "<"."?php
 661  /*
 662   * Squelette : $sourcefile
 663   * Date :      ".http_gmoddate(@filemtime($sourcefile))." GMT
 664   * Compile :   ".http_gmoddate(time())." GMT ($secondes)
 665   * " . (!$boucles ?  "Pas de boucle" :
 666      ("Boucles :   " . join (', ', array_keys($boucles)))) ."
 667   */ " .
 668        $code . "
 669  
 670  //
 671  // Fonction principale du squelette $sourcefile
 672  //
 673  function $nom (\$Cache, \$Pile, \$doublons=array(), \$Numrows='', \$SP=0) {
 674  \$t0 = $corps;
 675  
 676      return array(
 677          'texte' => \$t0,
 678          'squelette' => '$nom',
 679          'process_ins' => ((strpos(\$t0,'<'.'?')=== false) ? 'html' : 'php'),
 680          'invalideurs' => \$Cache
 681      );
 682  }
 683  
 684  ?".">";
 685  
 686      if ($GLOBALS['var_mode'] == 'debug')
 687        squelette_debug_compile($nom, $sourcefile, $squelette_compile, $squelette);
 688      return $squelette_compile;
 689  
 690  }
 691  
 692  ?>


[ Powered by PHPXref - Served by Debian GNU/Linux ]