<?php /** * Fonctions utiles au plugin Blocks * * @plugin Blocks * @copyright 2023 * @author nicod_ * @licence GNU/GPL * @package SPIP\Blocks\Fonctions */ /** * Sérialisation de données (saisies ou valeurs) * * @param $data * @return false|string */ function blocks_serialize($data) { return ($data && is_array($data)) ? json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK) : ''; } /** * Désérialisation de données (saisies ou valeurs) * * @param $data * @return array|null */ function blocks_deserialize($data): ?array { $retour = json_decode($data ?? '', true); return is_array($retour) ? $retour : null; } /** * Obtenir les saisies d'un block * * @param int $id_block * @return array */ function block_get_saisies(int $id_block): array { static $cache; if (isset($cache[$id_block])) { return $cache[$id_block]; } $saisies = []; if ($blocktype = block_get_blocktype($id_block)) { $saisies = blocktype_info($blocktype, 'saisies'); } else { spip_log("get_block_saisies($id_block) : pas de blocktype", 'blocks.' . _LOG_INFO_IMPORTANTE); } $cache[$id_block] = $saisies; return $saisies; } /** * Retourner le type de block d'un block * * @param int $id_block * @return mixed */ function block_get_blocktype(int $id_block) { return sql_getfetsel('blocktype', 'spip_blocks', 'id_block = ' . $id_block); } /** * Retourner un tableau des valeurs saisies * * @param array $saisies * @param array $valeurs * * @return array */ function block_get_valeurs(array $saisies, array $valeurs): array { $retour = []; include_spip('inc/saisies_lister'); $saisies_par_nom = saisies_lister_par_nom($saisies); foreach ($saisies_par_nom as $nom => $saisie) { $retour[$nom] = $valeurs[$nom] ?? null; } return $retour; } /** * Chercher le squelette correspondant à un block par son identifiant * * @param string $blocktype Type de block (identifiant) * @param bool $force_public Forcer une recherche du squelette public * @param bool $chemin_complet Retourne le chemin complet du squelette * @param bool $dist Retourne le squelette par défaut (dist)) * @return string Chemin du squelette trouvé */ /** * Chercher tous les types de blocks existant * On cherche des fichiers blocks/*.yaml dans le PATH * * @param bool $exclure_ignores * @return array */ function blocktypes_lister_types(bool $exclure_ignores = true): array { static $cache; $hash = ($exclure_ignores ? 1 : 0); if (isset($cache[$hash])) { return $cache[$hash] ?: []; } $liste_blocktypes = []; $match = '[^-]*[.]yaml$'; $liste = find_all_in_path('blocks/', $match); if ($liste) { include_spip('inc/yaml'); foreach ($liste as $blocktype => $chemin) { $blocktype = str_replace('.yaml', '', $blocktype);// $yaml_data = yaml_charger_inclusions(yaml_decode_file($chemin)); if (is_array($yaml_data)) { $yaml_data['titre'] = _T_ou_typo($yaml_data['titre']); $yaml_data['identifiant'] = $blocktype; $yaml_data['description'] = _T_ou_typo($yaml_data['description']); $yaml_data['icone'] = isset($yaml_data['icone']) ? _blocktype_find_icone_path($yaml_data['icone']) : ''; $yaml_data['saisies'] = $yaml_data['saisies'] ?? []; $liste_blocktypes[$blocktype] = $yaml_data; } else { spip_log("blocktypes_lister_types : $chemin / $blocktype => yaml pas décodé", 'blocks' . _LOG_INFO_IMPORTANTE); } } } // Puis les trier par ordre alphabétique uasort($liste_blocktypes, function ($valeur1, $valeur2) { if ($valeur1['nom'] > $valeur2['nom']) { return 1; } else if ($valeur1['nom'] == $valeur2['nom']) { return 0; } else { return -1; } }); // Retirer les modèles désactivés dans la config if ($exclure_ignores === true) { include_spip('inc/config'); $config_ignorer = lire_config('blocks/ignorer_blocktypes') ?? []; foreach ($config_ignorer as $ignorer) { unset($liste_blocktypes[$ignorer]); } } $cache[$hash] = $liste_blocktypes; return $liste_blocktypes; } /** * Retrouver l'icone d'un blocktype, la réduire à 16 px * * @param string $blocktype Type de block (identifiant) * @return string chemin **/ function _blocktype_find_icone_path(string $blocktype): string { static $cache; if (isset($cache[$blocktype])) { return $cache[$blocktype]; } if (!$chemin = find_in_path("blocks/$blocktype")) { if (!$chemin = find_in_path("icones/$blocktype")) { if (!$chemin = find_in_theme("images/$blocktype")) { if (!$chemin = find_in_path($blocktype)) { $chemin = ''; } } } } include_spip('inc/filtres'); include_spip('inc/filtres_images_mini'); //Au cas où find_in_theme nous return un truc genre gis-xx.svg?16px $chemin = preg_replace('#\?.*$#', '', $chemin); //On force la reduction à 16px //$chemin = extraire_attribut(image_reduire($chemin, 16), 'src'); $cache[$blocktype] = $chemin; return $chemin; } /** * Obtenir une info de la config d'un block * * @param string $blocktype Type de block (identifiant) * @param string $config Clé de la config à retrouver * @return string|array|null */ function blocktype_info(string $blocktype, string $config) { $blocktypes = blocktypes_lister_types(); switch ($config) { case 'saisies': $defaut = []; break; default: $defaut = null; break; } return $blocktypes[$blocktype][$config] ?? $defaut; } function _blocktype_trouver_squelette( string $blocktype, bool $force_public = false, bool $chemin_complet = false, bool $dist = true ): string { static $cache; $cle = $blocktype . (int)$force_public . (int)$chemin_complet . (int)$dist; if (isset($cache[$cle])) { return $cache[$cle]; } $squelette = ''; if ( !$force_public && test_espace_prive() && ($f = find_in_path('blocks/' . $blocktype . '_prive.' . _EXTENSION_SQUELETTES)) && lire_fichier($f, $contenu) ) { $squelette = $chemin_complet ? $f : 'blocks/' . $blocktype . '_prive'; } else if ( ($f = find_in_path('blocks/' . $blocktype . '.' . _EXTENSION_SQUELETTES)) && lire_fichier($f, $contenu) ) { $squelette = $chemin_complet ? $f : 'blocks/' . $blocktype; } else if ( $dist && ($f = find_in_path('blocks/dist.' . _EXTENSION_SQUELETTES)) && lire_fichier($f, $contenu) ) { $squelette = $chemin_complet ? $f : 'blocks/dist'; } $cache[$cle] = $squelette; return $squelette; } /** * Wrapper sans typage de la fonction _blocktype_trouver_squelette pour les squelettes SPIP * Les paramètres peuvent être vides ou des chaines et pas des bool * * @param $blocktype * @param $force_public * @param $chemin_complet * @param $dist * @return string */ function filtre_blocktype_squelette( $blocktype, $force_public = false, $chemin_complet = false, $dist = true ) { return _blocktype_trouver_squelette( (string)$blocktype, (bool)$force_public, (bool)$chemin_complet, (bool)$dist ); } /** * Calculer la liste des types de blocks pouvant être créés sous un type de block * @param $blocktype * @return array */ function blocktype_trouver_enfants($blocktype): array { return _blocktype_trouver_role($blocktype, 'enfant'); } /** * Calculer la liste des types de blocks dans lesquels un type de block peut être créé * @param $blocktype * @return array */ function blocktype_trouver_parents($blocktype): array { return _blocktype_trouver_role($blocktype, 'parent'); } /** * Calculer une liste de types de blocks enfants ou parents en fonction du rôle * @param string $blocktype Type de block (identifiant) * @param string $role * @return array */ function _blocktype_trouver_role(string $blocktype, string $role): array { $blocktypes_roles = []; if ( $blocktype && ($blocktypes = blocktypes_lister_types()) ) { $blocktypes_roles = $blocktypes[$blocktype]['roles'][$role] ?? []; } return $blocktypes_roles; } /** * Génére la liste des objets (du type `article`) utilisable dans une saisie * * @return array */ function blocks_objets_config() { include_spip('base/objets'); $data = []; if ($objets = array_filter(lire_config('blocks/objets'))) { foreach ($objets as $objet) { $objet_type = objet_type($objet); $infos = objet_info($objet_type, 'texte_objet'); $data[$objet_type] = _T($infos); } asort($data); } return $data; }