[ Index ] |
|
Code source de SPIP 1.8.3 |
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 "<INCLURE($fichier)> - " 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 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Thu Feb 22 22:27:47 2007 | par Balluche grâce à PHPXref 0.7 |