You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

407 lines
12 KiB

<?php
/**
* Plugin Rôles de documents
* (c) 2015
* Licence GNU/GPL
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Ajout de contenu dans le bloc «actions» des documents
*
* - Formulaire pour définir les rôles des documents
*
* @pipeline document_desc_actions
*
* @param array $flux Données du pipeline
* @return array Données du pipeline
*/
function roles_documents_document_desc_actions($flux) {
include_spip('inc/autoriser');
$texte = '';
$exec = trouver_objet_exec(_request('exec'));
$objet_exec = $exec['type'];
$id_table_objet_exec = $exec['id_table_objet'];
$id_objet_exec = intval(_request($id_table_objet_exec));
// soit objet et id_objet sont passés en paramètre, soit on prend l'objet édité sur la page
$objet = !empty($flux['args']['objet']) ? $flux['args']['objet'] : $objet_exec;
$id_objet = !empty($flux['args']['id_objet']) ? $flux['args']['id_objet'] : $id_objet_exec;
if (
$exec !== false // page d'un objet éditorial
and $exec['edition'] === false // pas en mode édition
and $flux['args']['variante'] != 'editer_logo'
and $id_document = intval($flux['args']['id_document'])
and autoriser('modifier', 'document', $id_document)
and $objet
and $id_objet
) {
// bloc à recharger
$ajaxreload = !empty($flux['args']['ajaxreload']) ? $flux['args']['ajaxreload'] : '.liste_items.documents';
// mini-formulaire
$form = recuperer_fond(
'prive/squelettes/inclure/editer_roles_document',
array(
'id_document' => $id_document,
'objet' => $objet,
'id_objet' => $id_objet,
'options' => array(
'ajaxReload' => $ajaxreload,
),
)
);
$texte = $form;
}
if ($texte) {
$flux['data'] .= $texte;
}
return $flux;
}
/**
* Synchroniser les champs "vu" et "rang_lien" lors de la création d'un nouveau lien de document portant un rôle.
*
* @pipeline post_edition_liens
*
* @param array $flux Données du pipeline
* @return array Données du pipeline
*/
function roles_documents_post_edition_lien($flux) {
if (
$flux['args']['action'] == 'insert' // il s'agit d'une création de lien
and $flux['args']['objet_source'] == 'document' // on a affaire à un document
and isset($flux['args']['role'])
and $role = $flux['args']['role']
and strlen($role) // et il y a un role donné
and isset($flux['args']['colonne_role'])
and $colonne_role = $flux['args']['colonne_role']
and $id_document = intval($flux['args']['id_objet_source'])
and $objet = $flux['args']['objet']
and $id_objet = intval($flux['args']['id_objet'])
) {
// le champ 'rang_lien' n'est présent qu'à partir de SPIP 3.2 (ou avec le plugin ordoc)
$champs_synchronises = array('vu', 'rang_lien');
$trouver_table = charger_fonction('trouver_table', 'base');
$desc = $trouver_table('spip_documents_liens');
$champs_presents = array_flip(array_intersect_key(array_flip($champs_synchronises), $desc['field']));
$qualifier = sql_fetsel(
$champs_presents,
'spip_documents_liens',
array(
'id_document=' . $id_document,
'objet=' . sql_quote($objet),
'id_objet=' . $id_objet,
$colonne_role . '=' . sql_quote('document')
)
);
if ($qualifier) {
include_spip('action/editer_liens');
objet_qualifier_liens(
array('document' => $id_document),
array($objet => $id_objet),
array($colonne_role => $role) + $qualifier
);
}
}
return $flux;
}
/**
* Après la modif d'un objet, synchroniser le vu de tous les document liés ayant un rôle
* avec celui du lien de base (ayant le rôle par défaut)
*
* @pipeline post_edition
*
* @param array $flux Données du pipeline
* @return array Données du pipeline
*/
function roles_documents_post_edition($flux) {
if (
isset($flux['args']['action'])
and $flux['args']['action'] == 'modifier' // on modifie un objet
and $flux['args']['table'] !== 'spip_documents' // mais pas un document
and $objet = $flux['args']['type']
and $id_objet = intval($flux['args']['id_objet'])
) {
include_spip('action/editer_liens');
// on regarde s'il y a des documents liés à l'objet modifié
if (count($liens = objet_trouver_liens(array('document'=>'*'), array($objet=>$id_objet)))) {
foreach ($liens as $l) {
// on récupère le champ "vu" du lien avec le rôle par défaut
$vu = sql_getfetsel(
'vu',
'spip_documents_liens',
'id_document=' .$l['id_document'] .' AND objet='.sql_quote($objet) .'
AND id_objet='.$id_objet .' AND role='.sql_quote('document')
);
// on met à jour tous les autres liens avec rôle
sql_updateq(
'spip_documents_liens',
array('vu'=>$vu),
'id_document=' .$l['id_document'] .' AND objet='.sql_quote($objet) .'
AND id_objet='.$id_objet .' AND role!='.sql_quote('document')
);
}
}
}
return $flux;
}
/**
* Empêcher les logos de sortir dans les boucles DOCUMENTS lorsqu'il y a une jointure sur la table de liens (et donc des rôles actifs).
*
* C'est nécessaire pour la rétro-compatibilité avec les squelettes existants.
* Pour voir les logos dans les boucles DOCUMENTS, il faut utiliser
* explicitement le critère {tout} ou {role=logo} ou {role?}
*
* @pipeline pre_boucle
* @param array $boucle Données du pipeline
* @return array Données du pipeline
*/
function roles_documents_pre_boucle($boucle) {
// Boucle DOCUMENTS
if ($boucle->type_requete === 'documents') {
// Vérifier s'il y a une jointure sur la table de liens
$jointure_documents = false;
if ($boucle->join) {
foreach($boucle->join as $join) {
if (array_search(sql_quote('documents'), $join) !== false) {
$jointure_documents = true;
break;
}
}
}
// Vérifier la présence du critère {role}
// [FIXME] vérifier sa valeur (=logo)
$utilise_critere_logo = false;
foreach ($boucle->criteres as $critere) {
if ($critere->type === 'critere') {
if (
(isset($critere->param[0][0]->texte) and $critere->param[0][0]->texte === 'role')
or ($critere->op === 'role')
) {
$utilise_critere_logo = true;
}
}
}
// Gros hack : on évite le traitement pour certains squelettes,
// afin d'éviter de les surcharger
$bypass = false;
$squelettes_bypass = array(
array(
'sourcefile' => 'document_desc.html',
'id_boucle' => '_docslies',
)
);
foreach($squelettes_bypass as $squelette) {
if (substr($boucle->descr['sourcefile'], -strlen($squelette['sourcefile'])) == $squelette['sourcefile']
and $boucle->id_boucle == $squelette['id_boucle']
) {
$bypass = true;
}
}
// Go go go
if (
$jointure_documents
and !$utilise_critere_logo
and (empty($boucle->modificateur['tout']) or $boucle->modificateur['tout'] === false)
and !$bypass
) {
$table_liens = 'spip_documents_liens';
$abbrev_table_lien = array_search($table_liens, $boucle->from);
if ($abbrev_table_lien) {
$boucle->where[] = array(
"'!='",
"'SUBSTR($abbrev_table_lien.role, 1, 4)'",
"'\'logo\''"
);
}
}
}
return $boucle;
}
/**
* Modifier le tableau retourné par la fonction charger d'un formulaire
*
* Ajout du champ 'role' sur le formulaire d'ajout de document
*
* @pipeline formulaire_charger
*
* @param array $flux Données du pipeline
* @return array Données du pipeline
*/
function roles_documents_formulaire_charger($flux) {
// Formulaire d'ajout de document
if ($flux['args']['form'] == 'joindre_document') {
$flux['data']['roles'] = '';
}
return $flux;
}
/**
* Complèter le tableau de réponse ou faire des traitements supplémentaires pour un formulaire
*
* Qualifier le lien crée avec le rôle choisi
*
* @pipeline formulaire_traiter
*
* @param array $flux Données du pipeline
* @return array Données du pipeline
*/
function roles_documents_formulaire_traiter($flux) {
// Formulaire d'ajout de document
// En présence d'un role sélectionne, on requalifie le lien créé
// sauf si c'est le rôle par défaut
if ($flux['args']['form'] == 'joindre_document'
and $roles = _request('roles')
and $objet = $flux['args']['args'][2]
and $id_objet = $flux['args']['args'][1]
and !empty($flux['data']['ids'])
) {
foreach ($flux['data']['ids'] as $id_document) {
if (!is_array($roles)) {
$roles = array($roles);
}
foreach ($roles as $role) {
if ($role != 'document') {
$update = sql_updateq(
'spip_documents_liens',
array('role' => $role),
array(
'id_document=' . intval($id_document),
'objet=' . sql_quote($objet),
'id_objet=' . intval($id_objet),
'role=' . sql_quote('document'),
)
);
}
}
}
}
return $flux;
}
/**
* Modifier le résultat du calcul d’un squelette donné.
*
* - Formulaire d'ajout de document : ajout du sélecteur de rôle, et rendre les identifiants uniques pour éviter un pb de JS quand le form est présent plusieurs fois sur la page.
* - Mediathèque : ajout du filtrage par rôle
*
* @pipeline recuperer_fond
*
* @param array $flux Données du pipeline
* @return array Données du pipeline
*/
function roles_documents_recuperer_fond($flux) {
// Ajout de document
if (
$flux['args']['fond'] == 'formulaires/inc-upload_document'
and isset($flux['args']['contexte']['objet'])
and isset($flux['args']['contexte']['id_objet'])
) {
// 1) Ajout du sélecteur de rôle
// Est-ce qu'il s'agit d'un ajout de logo ?
$editer_logo = !empty($flux['args']['contexte']['editer_logo']);
$principaux = $editer_logo ? true : false;
// Retrouver les rôles restant à associer
$objet = $flux['args']['contexte']['objet'];
$id_objet = $flux['args']['contexte']['id_objet'];
$roles = roles_documents_presents_sur_objet($objet, $id_objet, 0, $principaux);
$roles_attribuables = isset($flux['args']['contexte']['roles_attribuables']) ?
$flux['args']['contexte']['roles_attribuables'] :
($editer_logo ?
$roles['attribuables'] :
$roles['possibles']
);
$multiple = $editer_logo ? null : (count($roles_attribuables) > 1 ? 'oui' : null);
$contexte = array(
'roles' => (isset($flux['args']['contexte']['roles']) ? $flux['args']['contexte']['roles'] : ''),
'roles_attribuables' => $roles_attribuables,
'multiple' => $multiple,
'editer_logo' => $editer_logo,
);
// On place le sélecteur au début (compliqué de le placer juste avant les boutons, déplacés en JS, et des blocs cachés)
$selecteur_roles = recuperer_fond('formulaires/inc-selecteur_role', $contexte);
$flux['data']['texte'] = $selecteur_roles . $flux['data']['texte'];
// 2) Rendre les identifiants vraiment uniques pour le JS
if (preg_match('/id=["\']defaultsubmit([^"\']+)/i', $flux['data']['texte'], $res)) {
$domid = $res[1]; // L'identifiant pas si unique présent par défaut
$uniqid = $domid . '_' . uniqid(); // Identifiant vraiement unique
$flux['data']['texte'] = str_replace($domid, $uniqid, $flux['data']['texte']);
}
}
// Médiathèque
if ($flux['args']['fond'] == 'prive/squelettes/inclure/mediatheque-navigation') {
$fond_roles = recuperer_fond('prive/squelettes/inclure/mediatheque-navigation-roles', $flux['args']['contexte']);
// On s'insère après le dernier <ul> de la barre d'onglets secondaires
// Sans parseur, c'est la galère
$cherche = "#<ul\s+class=[\"']sanstitre[\"']>\s*(?:<li[^>]*>(?!.*<li>).*?</li>\s*)+\s*</ul>#i";
$remplace = "$0$fond_roles";
$flux['data']['texte'] = preg_replace($cherche, $remplace, $flux['data']['texte']);
}
return $flux;
}
/**
* Modifier le résultat du calcul d’un squelette de formulaire.
*
* - Formulaire d'édition de logo : on a besoin de bénéficier des éventuelles modifications effectuées auu formulaire joindre_document.
* Pour se faire on appelle le même pipeline à nouveau en se faisant passer pour ce dernier.
*
* @param array $flux
* @return array
**/
function roles_documents_formulaire_fond($flux) {
if ($flux['args']['form'] == 'editer_logo'
//and !empty($flux['args']['contexte']['_bigup_rechercher_fichiers'])
) {
$flux_joindre_document = $flux;
$flux_joindre_document['args']['form'] = 'joindre_document';
$data = pipeline('formulaire_fond', $flux_joindre_document);
$flux['data'] = $data;
}
return $flux;
}