''); if (preg_match(_PREG_CRAYON, $class, $regs)) { list(,$nomcrayon,$type,$champ,$id) = $regs; $regs[] = $class; // A-t-on le droit de crayonner ? spip_log("autoriser('crayonner', $type, $id, NULL, array('modele'=>$champ)","crayons_distant"); if (!autoriser('crayonner',$type, $id, NULL, array('modele'=>$champ))) { $return['$erreur'] = "$type $id: " . _U('crayons:non_autorise'); } else { $f = charger_fonction($type.'_'.$champ, 'controleurs', true) OR $f = charger_fonction($champ, 'controleurs', true) OR $f = charger_fonction($type, 'controleurs', true) OR $f = 'controleur_dist'; list($html,$status) = $f($regs, $c); if ($status) $return['$erreur'] = $html; else $return['$html'] = $html; } } else $return['$erreur'] = _U('crayons:donnees_mal_formatees'); return $return; } function controleur_dist($regs, $c=null) { list( , $nomcrayon, $type, $champ, $id, $class) = $regs; $options = array( 'class' => $class ); list($distant,$table) = distant_table($type); // Si le controleur est un squelette html, on va chercher // les champs qu'il lui faut dans la table demandee // Attention, un controleur multi-tables ne fonctionnera // que si les champs ont le meme nom dans toutes les tables // (par exemple: hyperlien est ok, mais pas nom) if (($fichier = find_in_path( ($controleur = 'controleurs/' . $type . '_' . $champ) . '.html')) || ($fichier = find_in_path( ($controleur = 'controleurs/' . $champ) .'.html'))) { if (!lire_fichier($fichier, $controldata)) die('erreur lecture controleur'); if (preg_match_all('/\bname=(["\'])#ENV\{name_(\w+)\}\1/', $controldata, $matches, PREG_PATTERN_ORDER)) $champ = $matches[2]; } else $controleur = ''; $valeur = valeur_colonne_table($type, $champ, $id); #spip_log("$valeur = valeur_colonne_table($type, $champ, $id);"); #spip_log($champ); if ($valeur === false) return array("$type $id $champ: " . _U('crayons:pas_de_valeur'), 6); /* if (is_scalar($valeur)) { $valeur = array($champ => $valeur); }*/ // type du crayon (a revoir quand le core aura type ses donnees) $inputAttrs = array(); if ($controleur) { $options['hauteurMini'] = 80; // base de hauteur mini $option['inmode'] = 'controleur'; $options['controleur'] = $controleur; } else // si la valeur fait plusieurs lignes on doit mettre un textarea // derogation specifique pour descriptif_site de spip_metas if ( preg_match(",[\n\r],", $valeur[$champ]) OR (($champ == 'valeur') && ($id == 'descriptif_site')) OR // on regarde le type tel que defini dans serial // (attention il y avait des blob dans les vieux spip) ($sqltype = colonne_table($type, $champ)) && (in_array($sqltype['type'] , array('mediumtext', 'longblob', 'longtext')) || (($sqltype['type'] == 'text' || $sqltype['type'] == 'blob') && in_array($champ, array('descriptif', 'bio'))))) { $options['hauteurMini'] = 80; // hauteur mini d'un textarea $option['inmode'] = 'texte'; } else { // ligne, hauteur naturelle $options['hauteurMaxi'] = 0; $option['inmode'] = 'ligne'; // c'est un nombre entier if ($sqltype['long']) { // si long est [4,3] sa longueur maxi est 8 (1234,123) if (is_array($sqltype['long'])) { if (count($sqltype['long']) == 2) { $inputAttrs['maxlength'] = $sqltype['long'][0] + 1 + $sqltype['long'][1]; } // on ne sait pas ce que c'est ! else { $inputAttrs['maxlength'] = $sqltype['long'][0]; } } else { $inputAttrs['maxlength'] = $sqltype['long']; } } } $crayon = new Crayon($nomcrayon, $valeur, $options, $c); $inputAttrs['style'] = implode('',$crayon->styles); if (!$controleur) { $inputAttrs['style'] .= 'width:' . $crayon->largeur . 'px;' . ($crayon->hauteur ? ' height:' . $crayon->hauteur . 'px;' : ''); } $html = $controleur ? $crayon->formulaire(null, $inputAttrs) : $crayon->formulaire($option['inmode'], $inputAttrs); $status = NULL; return array($html,$status); } // Definition des crayons class Crayon { // le nom du crayon "type-modele-id" comme "article-introduction-237" var $name; // type, a priori une table, extrait du nom plus eventuellement base distante var $type; // table la table a crayonner var $table; // distant base distante var $distant; // modele, un champ comme "texte" ou un modele, extrait du nom var $modele; // l'identificateur dans le type, comme un numero d'article var $id; // la ou les valeurs des champs du crayon, tableau associatif champ => valeur var $texts = array(); // une cle unique pour chaque crayon demande var $key; // un md5 associe aux valeurs pour verifier et detecter si elles changent var $md5; // dimensions indicatives var $largeurMini = 170; var $largeurMaxi = 700; var $hauteurMini = 80; var $hauteurMaxi = 700; var $largeur; // le mode d'entree: texte, ligne ou controleur var $inmode = ''; // eventuellement le fond modele pour le controleur var $controleur = ''; var $styles = array(); // le constructeur du crayon // $name : son nom // $texts : tableau associatif des valeurs ou valeur unique si crayon monochamp // $options : options directes du crayon (developpement) function Crayon($name, $texts = array(), $options = array(), $c=null) { $this->name = $name; list($this->type, $this->modele, $this->id) = array_pad(explode('-', $this->name, 3), 3, ''); list($this->distant,$this->table) = distant_table($this->type); if (is_scalar($texts) || is_null($texts)) { $texts = array($this->modele => $texts); } $this->texts = $texts; $this->key = strtr(uniqid('wid', true), '.', '_'); $this->md5 = $this->md5(); foreach ($options as $opt=>$val) { $this->$opt = $val; } $this->dimension($c); $this->css(); } // calcul du md5 associe aux valeurs function md5() { #spip_log($this->texts, 'crayons'); return md5(serialize($this->texts)); } // dimensions indicatives function dimension($c) { // largeur du crayon $this->largeur = min(max(intval(_request('w', $c)), $this->largeurMini), $this->largeurMaxi); // hauteur maxi d'un textarea selon wh: window height $maxheight = min(max(intval(_request('wh', $c)) - 50, 400), $this->hauteurMaxi); $this->hauteur = min(max(intval(_request('h', $c)), $this->hauteurMini), $maxheight); $this->left = _request('left'); $this->top = _request('top'); $this->w = _request('w'); $this->h = _request('h'); $this->ww = _request('ww'); $this->wh = _request('wh'); } // recuperer les elements de style function css() { foreach(array('color', 'font-size', 'font-family', 'font-weight', 'line-height', 'min-height', 'text-align') as $property) { if (null !== ($p = _request($property))) $this->styles[] = "$property:$p;"; } $property = 'background-color'; if (!$p = _request($property) OR $p == 'transparent') { $p = 'white'; } $this->styles[] = "$property:$p;"; } // formulaire standard function formulaire($contexte = array(), $inputAttrs = array()) { return $this->code() . $this->input($contexte, $inputAttrs); } // balises input type hidden d'identification du crayon function code() { return ''."\n" . ''."\n" . '' . "\n" . ''."\n" . '' ."\n" ; } /** * Fabriquer les balises des champs d'apres un modele controleurs/(type_)modele.html * * @param array $contexte * tableau (nom=>valeur) qui sera enrichi puis passe à recuperer_fond * @return string * le contenu de recuperer_fond du controleur */ function fond($contexte = array()) { include_spip('inc/filtres'); $contexte['id_' . $this->type] = $this->id; $contexte['id_' . $this->table] = $this->id; $contexte['crayon_type'] = $this->type; $contexte['crayon_modele'] = $this->modele; $contexte['lang'] = $GLOBALS['spip_lang']; $contexte['key'] = $this->key; $contexte['largeur'] = $this->largeur; $contexte['hauteur'] = $this->hauteur; $contexte['self'] = _request('self'); foreach ($this->texts as $champ => $val) { $contexte['name_' . $champ] = 'content_' . $this->key . '_' . $champ; } $contexte['style'] = join(' ',$this->styles); include_spip('public/assembler'); return recuperer_fond($this->controleur, $contexte); } /** * Fabriquer les balises du ou des champs * $attrs est un tableau (attr=>val) d'attributs communs ou pour le champs unique * * @param string|array $spec * soit un scalaire 'ligne' ou 'texte' précisant le type de balise * soit un array($champ=>array('type'=>'...', 'attrs'=>array(attributs specifique du champs))) * @return string * le html de l'input */ function input($spec = 'ligne', $attrs = array()) { if ($this->controleur) { return $this->fond($spec); } include_spip('inc/filtres'); $return = ''; foreach ($this->texts as $champ => $val) { $type = is_array($spec) ? $spec[$champ]['type'] : $spec; switch ($type) { case 'texte': $id = uniqid('wid'); $input = '\n"; break; case 'ligne': default: $input = ''."\n"; } if (is_array($spec) && isset($spec[$champ]['attrs'])) { foreach ($spec[$champ]['attrs'] as $attr=>$val) { $input = inserer_attribut($input, $attr, $val); } } foreach ($attrs as $attr=>$val) { $input = inserer_attribut($input, $attr, $val); } // petit truc crado pour mettre la barre typo si demandee // pour faire propre il faudra reprogrammer la bt en jquery $meta_crayon = isset($GLOBALS['meta']['crayons']) ? unserialize($GLOBALS['meta']['crayons']) : array(); if (isset($meta_crayon['barretypo']) AND $meta_crayon['barretypo'] AND $type == 'texte') { // Pas la peine de mettre cette barre si PortePlume est la if ( !( function_exists('chercher_filtre') AND $f = chercher_filtre('info_plugin') AND $f('PORTE_PLUME','est_actif') ) ) { include_spip('inc/barre'); $input = "
" . (function_exists('afficher_barre') ? afficher_barre("document.getElementById('$id')") : '') . '
' . $input; } } $return .= $input; } return $return; } } /** * Fabriquer les boutons du formulaire * * @param array $boutons * Le tableau des boutons * @return string * Le html des boutons */ function crayons_boutons($boutons = array()) { $boutons['submit'] = array('ok', texte_backend(_T('bouton_enregistrer'))); $boutons['cancel'] = array('cancel', texte_backend(_T('crayons:annuler'))); $html = ''; foreach ($boutons as $bnam => $bdef) if ($bdef) { $html .= ''; } if ($html) return '
'.$html.'
'; } function crayons_formulaire($html, $action='crayons_store') { if (!$html) return ''; // on est oblige de recreer un Crayon pour connaitre la largeur du form. // Pb conceptuel a revoir $crayon = new Crayon(""); $class = ($crayon->largeur<250?" small":""); include_spip('inc/filtres'); return liens_absolus( '
' . '
' . $html . crayons_boutons() . '
' .'
' ); } // // Un Crayon avec une verification de code de securite // class SecureCrayon extends Crayon { function SecureCrayon($name, $text='') { parent::Crayon($name, $text); } function code() { $code = parent::code(); $secu = md5($GLOBALS['meta']['alea_ephemere']. '=' . $this->name); return $code .''."\n"; } } /** * Action affichant le controleur html ou php adéquat * * on affiche le formulaire demande (controleur associe au crayon) * Si le crayon n'est pas de type "crayon", c'est un crayon etendu, qui * integre le formulaire requis à son controleur (pour avoir les boutons * du formulaire dans un controleur Draggable, par exemple, mais il y a * d'autres usages possibles) * */ function action_crayons_html_dist() { include_spip('inc/crayons'); // Utiliser la bonne langue d'environnement if(!isset($GLOBALS['forcer_lang']) OR !$GLOBALS['forcer_lang'] OR ($GLOBALS['forcer_lang'] === 'non')) lang_select($GLOBALS['auteur_session']['lang']); $return = affiche_controleur(_request('class')); if (!_request('type') OR _request('type') == 'crayon') $return['$html'] = crayons_formulaire($return['$html']); $json = trim(crayons_json_encode($return)); header("Content-Type: text/plain; charset=utf-8"); die($json); } ?>