$value) { $execs[$key] = trim($value); } if ($exec_autorise == '*' || in_array($exec, $execs)) { return true; } } return false; } /** * Ajouter la gestion des crayons dans l'espace privé * * @pipeline header_prive * @uses Crayons_preparer_page() * * @param string $head * Contenu du header * @return string * Contenu du header **/ function Crayons_insert_head($head) { // verifie la presence d'une meta crayons, si c'est vide // on ne cherche meme pas a traiter l'espace prive if (empty($GLOBALS['meta']['crayons'])) { return $head; } $config_espace_prive = @unserialize($GLOBALS['meta']['crayons']); if (empty($config_espace_prive)) { return $head; } // verifie que l'edition de l'espace prive est autorisee if (isset($config_espace_prive['espaceprive']) and $config_espace_prive['espaceprive'] == 'on') { // determine les pages (exec) crayonnables if (test_exec_crayonnable(_request('exec'))) { // Calcul des droits include_spip('inc/crayons'); $head = Crayons_preparer_page($head, '*', wdgcfg(), 'head'); } } // retourne l'entete modifiee return $head; } /** * Ajouter la gestion des crayons dans l'espace public * * @pipeline affichage_final * @uses analyse_droits_rapide_dist() * @uses Crayons_preparer_page() * @note * Le pipeline affichage_final est executé à chaque hit sur toute la page * * @param string $page * Contenu de la page à envoyer au navigateur * @return string * Contenu de la page à envoyer au navigateur **/ function Crayons_affichage_final($page) { // ne pas se fatiguer si le visiteur n'a aucun droit if (!(function_exists('analyse_droits_rapide')?analyse_droits_rapide():analyse_droits_rapide_dist())) { return $page; } // sinon regarder rapidement si la page a des classes crayon if (strpos($page, 'crayon')===false) { return $page; } // voir un peu plus precisement lesquelles include_spip('inc/crayons'); if (!preg_match_all(_PREG_CRAYON, $page, $regs, PREG_SET_ORDER)) { return $page; } $wdgcfg = wdgcfg(); // calculer les droits sur ces crayons include_spip('inc/autoriser'); $droits = array(); $droits_accordes = 0; foreach ($regs as $reg) { list(,$crayon,$type,$champ,$id) = $reg; if (_DEBUG_CRAYONS) { spip_log("autoriser('modifier', $type, $id, NULL, array('champ'=>$champ))", 'crayons_distant'); } if (autoriser('modifier', $type, $id, null, array('champ'=>$champ))) { if (!isset($droits['.' . $crayon])) { $droits['.' . $crayon] = 0; } $droits['.' . $crayon]++; $droits_accordes ++; } } // et les signaler dans la page if ($droits_accordes == count($regs)) { // tous les droits $page = Crayons_preparer_page($page, '*', $wdgcfg); } elseif ($droits) { // seulement certains droits, preciser lesquels $page = Crayons_preparer_page($page, join(',', array_keys($droits)), $wdgcfg); } return $page; } /** * Ajoute les scripts css et js nécessaires aux crayons dans le code HTML * * @uses crayons_var2js() * * @param string $page * Code HTML de la page complète ou du header seulement * @param string $droits * - Liste de css définissant les champs crayonnables * (séparés par virgule) dont l'édition est autorisée * - "*" si tous sont autorisés * @param array $wdgcfg * Description de la configuration des crayons (attribut => valeur) * @param string $mode * - page : toute la page est présente dans `$page` * - head : seul le header est présent dans `$page` * @return **/ function &Crayons_preparer_page(&$page, $droits, $wdgcfg = array(), $mode = 'page') { /** * Si pas forcer_lang, on charge le contrôleur dans la langue que l'utilisateur a dans le privé */ if (!isset($GLOBALS['forcer_lang']) or !$GLOBALS['forcer_lang'] or ($GLOBALS['forcer_lang'] === 'non')) { if (isset($GLOBALS['auteur_session']) and isset($GLOBALS['auteur_session']['lang'])) { lang_select($GLOBALS['auteur_session']['lang']); } } $jsSkel = find_in_path('crayons.js.html'); $contexte = array('callback' => 'startCrayons'); if (_DEBUG_CRAYONS) { $contexte['debug_crayons'] = 1; } $hash = substr(md5($jsSkel . json_encode($contexte)),0,7); $jsFile = _DIR_VAR . "crayons-{$hash}.js"; if (!file_exists($jsFile) or _VAR_MODE === 'recalcul') { include_spip('inc/filtres'); // pour produire_fond_statique() $jsFondStatique = supprimer_timestamp(produire_fond_statique('crayons.js', $contexte)); @copy($jsFondStatique, $jsFile); } $jsFile .= "?" . filemtime($jsFile); $cssFile = find_in_path('css/crayons.css'); if (lang_dir() === 'rtl') { include_spip('inc/filtres'); // pour direction_css() $cssFile = direction_css($cssFile, 'rtl'); } $cssFile .= "?" . filemtime($cssFile); $config = crayons_var2js(array( 'imgPath' => dirname(find_in_path('css/images/crayon.svg')), // ne sert visiblement plus ? 'droits' => $droits, 'dir_racine' => _DIR_RACINE, 'self' => self('&'), 'txt' => array( 'error' => _U('crayons:svp_copier_coller'), 'sauvegarder' => $wdgcfg['msgAbandon'] ? _U('crayons:sauvegarder') : '' ), 'img' => array( 'searching' => array( 'txt' => _U('crayons:veuillez_patienter') ), 'crayon' => array( 'txt' => _U('crayons:editer') ), 'edit' => array( 'txt' => _U('crayons:editer_tout') ), 'img-changed' => array( 'txt' => _U('crayons:deja_modifie') ) ), 'cfg' => $wdgcfg )); // Est-ce que PortePlume est la ? $meta_crayon = (isset($GLOBALS['meta']['crayons']) ? unserialize($GLOBALS['meta']['crayons']): array()); $pp = ''; if (isset($meta_crayon['barretypo']) && $meta_crayon['barretypo']) { if (test_plugin_actif('porte_plume')) { $pp = <<"; $incJS = <</* */ EOH; if ($mode == 'head') { //js inline avant les css, sinon ca bloque le chargement $page = $page . $incJS . $incCSS; return $page; } $pos_head = strpos($page, ''); if ($pos_head === false) { return $page; } // js inline avant la premiere css, ou sinon avant la fin du head $pos_link = strpos($page, ''); $page = substr_replace($page, $incCSS, $pos_head, 0); return $page; } /** * Balise indiquant un champ SQL crayonnable * * @note * Si cette fonction est absente, `balise_EDIT_dist()` déclarée par SPIP * ne retourne rien * * @example * ``` *
#TEXTE
*
#PS
* ``` * * @param Champ $p * Pile au niveau de la balise * @return Champ * Pile complétée par le code à générer **/ function balise_EDIT($p) { // le code compile de ce qui se trouve entre les {} de la balise $label = interprete_argument_balise(1, $p); // Verification si l'on est dans le cas d'une meta // #EDIT{meta-descriptif_site} ou #EDIT{meta-demo/truc} if (preg_match('/meta-(.*)\'/', $label, $meta)) { $type = 'meta'; $label= 'valeur'; $primary = $meta[1]; $p->code = "classe_boucle_crayon('" . $type ."','" .$label ."'," . "str_replace('/', '__', '$primary')" # chaque / doit être remplacé pour CSS. .").' '"; $p->interdire_scripts = false; return $p; } $i_boucle = $p->nom_boucle ? $p->nom_boucle : $p->id_boucle; // #EDIT hors boucle? ne rien faire if (!isset($p->boucles[$i_boucle]) or !$type = ($p->boucles[$i_boucle]->type_requete)) { $p->code = "''"; $p->interdire_scripts = false; return $p; } // crayon sur une base distante 'nua__article-intro-5' if ($distant = $p->boucles[$i_boucle]->sql_serveur) { $type = $distant.'__'.$type; } $primary = $p->boucles[$i_boucle]->primary; // On rajoute ici un debug dans le cas où aucune clé primaire n'est trouvée. // Cela peut se présenter par exemple si on utilise #EDIT{monchamp} directement // dans une boucle CONDITION sans faire référence au nom de la boucle d'au dessus. if (!$primary) { erreur_squelette(_T('crayons:absence_cle_primaire'), $p); } $primary = explode(',', $primary); $id = array(); foreach ($primary as $key) { $id[] = champ_sql(trim($key), $p); } $primary = implode(".'-'.", $id); $p->code = "classe_boucle_crayon('" . $type ."'," .sinon($label, "''") .',' . $primary .").' '"; $p->interdire_scripts = false; return $p; } /** * Balise indiquant une configuration crayonnable * * @example * ``` *
#DESCRIPTIF_SITE_SPIP
*
#CONFIG{demo/truc}
* ``` * * @param Champ $p * Pile au niveau de la balise * @return Champ * Pile complétée par le code à générer **/ if (!function_exists('balise_EDIT_CONFIG_dist')) { function balise_EDIT_CONFIG_dist($p) { // le code compile de ce qui se trouve entre les {} de la balise $config = interprete_argument_balise(1, $p); if (!$config) { return $p; } // chaque / du nom de config doit être transformé pour css. // nous utiliserons '__' à la place. $type = 'meta'; $label= 'valeur'; $p->code = "classe_boucle_crayon('" . $type . "','" . $label . "'," . "str_replace('/', '__', $config)" . ").' '"; $p->interdire_scripts = false; return $p; } } /** * Crée le controleur du crayon indiqué par la classe CSS * * @param string $class * Class CSS de crayon tel que créé par #EDIT * @return string * HTML du crayon, sinon texte d'erreur **/ function creer_le_crayon($class) { include_spip('inc/crayons'); include_spip('action/crayons_html'); $a = affiche_controleur($class, array('w' => 485, 'h' => 300, 'wh' => 500)); return $a['$erreur'] ? $a['$erreur'] : $a['$html']; } /** * Balise `#CRAYON` affichant un formulaire de crayon * * SI `?edit=1;` * * @example * ``` * #CRAYON{ps} * ``` * * @param Champ $p * Pile au niveau de la balise * @return Champ * Pile complétée par le code à générer **/ function balise_CRAYON($p) { $p = balise_EDIT($p); $p->code = 'creer_le_crayon('.$p->code.')'; return $p; } /** * Donne la classe CSS crayon * * En fonction : * - du type de la boucle * (attention aux exceptions pour `#EDIT` dans les boucles HIERARCHIE et SITES) * - du champ demande (vide, + ou se terminant par + : (+)classe type--id) * - de l'id courant * * @param string $type * Type d'objet, ou "meta" pour un champ de configuration * @param string $champ * Champ SQL concerné * @param int|string $id * Identifiant de la ligne sql * @return string * Classes CSS (à ajouter dans le HTML à destination du javascript de Crayons) **/ function classe_boucle_crayon($type, $champ, $id) { // $type = objet_type($type); $type = $type[strlen($type) - 1] == 's' ? substr($type, 0, -1) : str_replace( array('hierarchie','syndication'), array('rubrique','site'), $type ); $plus = (substr($champ, -1) == '+' and $champ = substr($champ, 0, -1)) ? " $type--$id" : ''; // test rapide pour verifier que l'id est valide (a-zA-Z0-9) if (false !== strpos($id, ' ')) { spip_log("L'identifiant ($id) ne pourra être géré ($type | $champ)", 'crayons'); return 'crayon_id_ingerable'; } return 'crayon ' . $type . '-' . $champ . '-' . $id . $plus; }