$chemin) { $objets_selectionner[] = preg_replace('/^hierarchie-([\w]+)[.]html$/', '$1', $fichier); } // S'il y a une whitelist on ne garde que ce qui est dedans if (!empty($whitelist)) { $whitelist = array_map('table_objet', $whitelist); $objets_selectionner = array_intersect($objets_selectionner, $whitelist); } // On supprime ce qui est dans la blacklist $blacklist = array_map('table_objet', $blacklist); // On enlève toujours la racine $blacklist[] = 'racine'; $objets_selectionner = array_diff($objets_selectionner, $blacklist); // Ensuite on cherche ce qu'on doit afficher : au moins ceux qu'on peut sélectionner $objets_afficher = $objets_selectionner; // Il faut alors chercher d'éventuels parents obligatoires en plus : // lister-trucs-bidules.html => on doit afficher des "trucs" pour trouver des "bidules" if (!$liste_parents) { $liste_parents = find_all_in_path('formulaires/selecteur/', 'lister-[\w]+-[\w]+[.]html$'); } foreach ($liste_parents as $fichier => $chemin) { preg_match('/^lister-([\w]+)-([\w]+)[.]html$/', $fichier, $captures); $parent = $captures[1]; $type = $captures[2]; // Si le type fait partie de ce qu'on doit afficher alors on ajoute aussi le parent à l'affichage if (in_array($type, $objets_afficher)) { $objets_afficher[] = $parent; } } $objets = array( 'selectionner' => array_unique($objets_selectionner), 'afficher' => array_unique($objets_afficher), ); return $objets; } /** * Extrait des informations d'un tableau d'entrées `array("rubrique|9", "article|8", ...)` * ou une chaine brute `rubrique|9,article|8,...` * * Peut retourner un tableau de couples (objet => id_objet) ou la liste * des identifiants d'un objet précis si `$type` est fourni. * * @example * `picker_selected(array('article|1', 'article|2', 'rubrique|5'))` * retourne `array('article' => 1, 'article' => 2, 'rubrique' => 5)` * @example * `picker_selected(array('article|1', 'article|2', 'rubrique|5'), 'article')` * retourne `array(1, 2)` * * @filtre * * @param array|string $selected * Liste des entrées : tableau ou chaine séparée par des virgules * @param string $type * Type de valeur à recuperer tel que `rubrique`, `article` * @return array * liste des couples (objets => id_objet) ou liste des identifiants d'un type d'objet. **/ function picker_selected($selected, $type = '') { $select = array(); $type = preg_replace(',\W,', '', $type); if ($selected and !is_array($selected)) { $selected = explode(',', $selected); } if (is_array($selected)) { foreach ($selected as $value) { // Si c'est le bon format déjà if (preg_match('/^([\w]+)[|]([0-9]+)$/', $value, $captures)) { $objet = $captures[1]; $id_objet = intval($captures[2]); // Si on cherche un type et que c'est le bon, on renvoit un tableau que d'identifiants if (is_string($type) and $type == $objet and ($id_objet or in_array($objet, array('racine', 'rubrique')))) { $select[] = $id_objet; } elseif (!$type and ($id_objet or in_array($objet, array('racine', 'rubrique')))) { $select[] = array('objet' => $objet, 'id_objet' => $id_objet); } } } } return $select; } /** * Récupère des informations sur un objet pour pouvoir l'ajouter aux éléments sélectionnés * * @uses typer_raccourci() * * @param string $ref * Référence de l'objet à chercher, de la forme "type|id", par exemple "rubrique|123". * @param mixed $rubriques_ou_objets * Soit un booléen (pouvant être une chaîne vide aussi) indiquant que les rubriques sont sélectionnables * soit un tableau complet des objets sélectionnables. * @param bool $articles * Booléen indiquant si les articles sont sélectionnables */ function picker_identifie_id_rapide($ref, $rubriques_ou_objets = false, $articles = false) { include_spip('inc/json'); include_spip('inc/lien'); // On construit un tableau des objets sélectionnables suivant les paramètres $objets = array(); if ($rubriques_ou_objets and is_array($rubriques_ou_objets)) { $objets = $rubriques_ou_objets; } else { if ($rubriques_ou_objets) { $objets[] = 'rubriques'; } if ($articles) { $objets[] = 'articles'; } } // Si la référence ne correspond à rien, c'est fini if (!($match = typer_raccourci($ref))) { return json_export(false); } // Sinon on récupère les infos utiles @list($type, , $id, , , , ) = $match; // On regarde si le type trouvé fait partie des objets sélectionnables if (!in_array(table_objet($type), $objets)) { return json_export(false); } // Maintenant que tout est bon, on cherche les informations sur cet objet include_spip('inc/filtres'); if (!$titre = generer_info_entite($id, $type, 'titre')) { return json_export(false); } // On simplifie le texte $titre = attribut_html($titre); return json_export(array('type' => $type, 'id' => "$type|$id", 'titre' => $titre)); } /** * Déterminer si une rubrique a des enfants à afficher ou non * * On test d'abord si la rubrique a des sous rubriques, et sinon on regarde * les autres types sélectionnables, puis on regarde si la rubrique contient * certains de ces objets * * @note * Pour optimiser, la fonction calcule sa valeur sur toute la fratrie d'un coup, * puisqu'elle est appellée N fois pour toutes les rubriques d'un même niveau * * @param int $id_rubrique * Identifiant de la rubrique * @param array $types * Liste de type d'objets. Si l'un de ces objet est présent dans la rubrique, * alors cette rubrique est à afficher * @return string * Comme le filtre `oui` : espace (` `) si rubrique à afficher, chaîne vide sinon. */ function test_enfants_rubrique($id_rubrique, $types = array()) { static $has_child = array(); if (!isset($has_child[$id_rubrique])) { $types = (is_array($types) ? array_filter($types) : array()); // recuperer tous les freres et soeurs de la rubrique visee $id_parent = sql_getfetsel('id_parent', 'spip_rubriques', 'id_rubrique=' . intval($id_rubrique)); $fratrie = sql_allfetsel('id_rubrique', 'spip_rubriques', 'id_parent=' . intval($id_parent)); $fratrie = array_map('reset', $fratrie); $has = sql_allfetsel('DISTINCT id_parent', 'spip_rubriques', sql_in('id_parent', $fratrie)); $has = array_map('reset', $has); $fratrie = array_diff($fratrie, $has); while (count($fratrie) and is_array($types) and count($types)) { $type = array_shift($types); $h = sql_allfetsel('DISTINCT id_rubrique', table_objet_sql($type), sql_in('id_rubrique', $fratrie)); $h = array_map('reset', $h); $has = array_merge($has, $h); $fratrie = array_diff($fratrie, $h); } if (count($has)) { $has_child = $has_child + array_combine($has, array_pad(array(), count($has), true)); } if (count($fratrie)) { $has_child = $has_child + array_combine($fratrie, array_pad(array(), count($fratrie), false)); } } return $has_child[$id_rubrique] ? ' ' : ''; }