On refait totalement le fichier d'action editer_logo en repartant de celui du core de SPIP 4. Ce qui permet de garder la fonction de migration, mais aussi de refaire le reste. Ou même de faire tout court, car logo_modifier() n'avait jamais été fait pour marcher avec les rôles, ce qui est le cas maintennt. Au passage la fonction de migration n'a rien à faire là, on peut vouloir surcharger les fonctions d'API sans devoir zapper la fonction de migration (qui devrait être dans une action dédiée par ex).

pull/28/head
RastaPopoulos 5 months ago committed by Gitea
parent 098bbb2601
commit 3f47cac742

@ -1,17 +1,21 @@
<?php
/***************************************************************************\
* SPIP, Système de publication pour l'internet *
* *
* Copyright © avec tendresse depuis 2001 *
* Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James *
* *
* Ce programme est un logiciel libre distribué sous licence GNU/GPL. *
* Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne. *
\***************************************************************************/
/**
* Rôles de documents : gestion de l'API de modification/suppression des logos
* Gestion de l'API de modification/suppression des logos
*
* Surcharge du core.
*
* @plugin Rôles de documents
* @copyright 2015-2018
* @author tcharlss
* @licence GNU/GPL
* @package SPIP\Core\Logo\Edition
* @package SPIP\Core\Logo\Edition
*/
// Sécurité
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
@ -20,56 +24,43 @@ if (!defined('_ECRIRE_INC_VERSION')) {
/**
* Supprimer le logo d'un objet
*
* @uses dissocier_document_role()
* @uses chercher_logo()
*
* @param string $objet
* @param int $id_objet
* @param string $role
* - Rôle pour un document : `logo`, `logo_survol`, etc.
* - `on` ou `off` pour un vieux logo
* @return bool
* @param string $etat
* `on` ou `off`
*/
function logo_supprimer($objet, $id_objet, $role) {
$res = false;
function logo_supprimer($objet, $id_objet, $etat) {
$chercher_logo = charger_fonction('chercher_logo', 'inc');
$objet = objet_type($objet);
$id_table_objet = id_table_objet($objet);
$etats = array('on', 'off'); // États des vieux logos
// Vieux logos
if (in_array($role, $etats)) {
$chercher_logo = charger_fonction('chercher_logo', 'inc');
$logo = $chercher_logo($id_objet, $id_table_objet, $role, true);
if ($logo) {
$res = spip_unlink($logo[0]);
}
$primary = id_table_objet($objet);
include_spip('inc/chercher_logo');
// Documents
// On n'appelle pas directement supprimer_document()
// Il faut faire diverses choses avant, ce dont dissocier_document_role() se charge.
} else {
include_spip('action/editer_liens');
if ($lien_role = objet_trouver_liens(
array('document' => '*'),
array($objet => $id_objet),
array('role' => $role)
)
and $id_document = intval(array_shift(array_column($lien_role, 'id_document')))
// existe-t-il deja un logo ?
$logo = $chercher_logo($id_objet, $primary, $etat);
if ($logo) {
# TODO : deprecated, a supprimer -> anciens logos IMG/artonxx.png pas en base
if ((is_countable($logo) ? count($logo) : 0) < 6) {
spip_log('Supprimer ancien logo ' . json_encode($logo, JSON_THROW_ON_ERROR), 'logo');
spip_unlink($logo[0]);
}
// Documents
// On n'appelle pas directement supprimer_document
// Il faut faire diverses choses avant, ce dont dissocier_document_role() se charge.
elseif (
$doc = $logo[5]
and isset($doc['id_document'])
and $id_document = $doc['id_document']
and $role = $doc['role'] // le vrai role finalement trouvé, pour l'état demandé au départ
) {
$dissocier_document_role = charger_fonction('dissocier_document_role', 'action');
$arg = "$id_objet-$objet-$id_document-$role-suppr-";
$res = $dissocier_document_role($arg);
}
}
return $res;
}
/**
* Modifier ou créer le logo d'un objet
*
* [TODO] : compatibilité avec les documents (création : action/ajouter_documents, modification : action/editer_document)
* Modifier le logo d'un objet
*
* @param string $objet
* @param int $id_objet
@ -86,128 +77,208 @@ function logo_modifier($objet, $id_objet, $etat, $source) {
$objet = objet_type($objet);
$primary = id_table_objet($objet);
include_spip('inc/chercher_logo');
$type = type_du_logo($primary);
include_spip('inc/roles');
// nom du logo
$nom = $type . $etat . $id_objet;
// supprimer le logo eventueel existant
logo_supprimer($objet, $id_objet, $etat);
$mode = preg_replace(',\W,', '', $etat);
if (!$mode) {
spip_log("logo_modifier : etat $etat invalide", 'logo');
$erreur = 'etat invalide';
return $erreur;
}
// On cherche le bon rôle à utiliser
$role = roles_documents_compatibilite_anciens_etats($objet, $mode);
include_spip('inc/documents');
$erreur = '';
if (!$source) {
spip_log('spip_image_ajouter : source inconnue');
spip_log('spip_image_ajouter : source inconnue', 'logo');
$erreur = 'source inconnue';
return $erreur;
}
$file_tmp = _DIR_LOGOS . $nom . '.tmp';
$ok = false;
// fichier dans upload/
if (is_string($source)) {
$tmp_name = false;
if (file_exists($source)) {
$ok = @copy($source, $file_tmp);
$tmp_name = $source;
} elseif (file_exists($f = determine_upload() . $source)) {
$ok = @copy($f, $file_tmp);
$tmp_name = $f;
}
} elseif (!$erreur = check_upload_error($source['error'], '', true)) {
// Intercepter une erreur a l'envoi
// analyse le type de l'image (on ne fait pas confiance au nom de
// fichier envoye par le browser : pour les Macs c'est plus sur)
$ok = deplacer_fichier_upload($source['tmp_name'], $file_tmp);
}
if (!$tmp_name) {
spip_log('spip_image_ajouter : source inconnue', 'logo');
$erreur = 'source inconnue';
if ($erreur) {
return $erreur;
}
$source = [
'tmp_name' => $tmp_name,
'name' => basename($tmp_name),
];
} elseif ($erreur = check_upload_error($source['error'], '', true)) {
return $erreur;
}
if (!$ok or !file_exists($file_tmp)) {
spip_log($erreur = "probleme de copie pour $file_tmp ");
// supprimer le logo eventueel existant
// utilse notre fonction avec rôle qui va supprimer ou pas si utilisé ailleurs
if (empty($GLOBALS['logo_migrer_en_base'])) {
logo_supprimer($objet, $id_objet, $mode);
}
include_spip('inc/autoriser');
$source['mode'] = 'choix'; // on laisse faire (si jamais ya des rôles principaux qui sont pas pour des images, par ex des PDF))
$ajouter_documents = charger_fonction('ajouter_documents', 'action');
autoriser_exception('associerdocuments', $objet, $id_objet);
$ajoutes = $ajouter_documents('new', [$source], $objet, $id_objet, 'choix');
autoriser_exception('associerdocuments', $objet, $id_objet, false);
$id_document = reset($ajoutes);
if (!is_numeric($id_document)) {
$erreur = ($id_document ?: 'Erreur inconnue');
spip_log("Erreur ajout logo : $erreur pour source=" . json_encode($source, JSON_THROW_ON_ERROR), 'logo');
return $erreur;
}
// Si ça a bien été ajouté, il faut maintenant requalifier avec le bon rôle
$update = sql_updateq(
'spip_documents_liens',
['role' => $role],
[
'id_document=' . intval($id_document),
'objet=' . sql_quote($objet),
'id_objet=' . intval($id_objet),
'role=' . sql_quote('document'),
]
);
$size = @getimagesize($file_tmp);
$extension = !$size ? '' : ($size[2] > 3 ? '' : $GLOBALS['formats_logos'][$size[2] - 1]);
if ($extension) {
@rename($file_tmp, $file_tmp . ".$extension");
$file_tmp = $file_tmp . ".$extension";
$poids = filesize($file_tmp);
return ''; // tout est bon, pas d'erreur
}
if (defined('_LOGO_MAX_WIDTH') or defined('_LOGO_MAX_HEIGHT')) {
if ((defined('_LOGO_MAX_WIDTH') and _LOGO_MAX_WIDTH and $size[0] > _LOGO_MAX_WIDTH)
or (defined('_LOGO_MAX_HEIGHT') and _LOGO_MAX_HEIGHT and $size[1] > _LOGO_MAX_HEIGHT)
) {
$max_width = (defined('_LOGO_MAX_WIDTH') and _LOGO_MAX_WIDTH) ? _LOGO_MAX_WIDTH : '*';
$max_height = (defined('_LOGO_MAX_HEIGHT') and _LOGO_MAX_HEIGHT) ? _LOGO_MAX_HEIGHT : '*';
// pas la peine d'embeter le redacteur avec ca si on a active le calcul des miniatures
// on met directement a la taille maxi a la volee
if (isset($GLOBALS['meta']['creer_preview']) and $GLOBALS['meta']['creer_preview'] == 'oui') {
include_spip('inc/filtres');
$img = filtrer('image_reduire', $file_tmp, $max_width, $max_height);
$img = extraire_attribut($img, 'src');
$img = supprimer_timestamp($img);
if (@file_exists($img) and $img !== $file_tmp) {
spip_unlink($file_tmp);
@rename($img, $file_tmp);
$size = @getimagesize($file_tmp);
function logo_migrer_en_base($objet, $time_limit) {
$dir_logos_erreurs = sous_repertoire(_DIR_IMG, 'logo_erreurs');
$dir_logos = sous_repertoire(_DIR_IMG, 'logo');
$formats_logos = ['jpg', 'png', 'svg', 'gif'];
if (isset($GLOBALS['formats_logos'])) {
$formats_logos = $GLOBALS['formats_logos'];
}
$trouver_table = charger_fonction('trouver_table', 'base');
$chercher_logo = charger_fonction('chercher_logo', 'inc');
include_spip('inc/chercher_logo');
$_id_objet = id_table_objet($objet);
$table = table_objet_sql($objet);
$type = type_du_logo($_id_objet);
$desc = $trouver_table($table);
// on desactive les revisions
$liste_objets_versionnes = $GLOBALS['meta']['objets_versions'] ?? '';
unset($GLOBALS['meta']['objets_versions']);
// et le signalement des editions
$articles_modif = $GLOBALS['meta']['articles_modif'] ?? '';
$GLOBALS['meta']['articles_modif'] = 'non';
foreach (['on', 'off'] as $mode) {
$nom_base = $type . $mode;
$dir = (defined('_DIR_LOGOS') ? _DIR_LOGOS : _DIR_IMG);
$files = glob($dir . $nom_base . '*');
// est-ce que c'est une nouvelle tentative de migration ?
// dans ce cas les logos sont deja dans IMG/logo/
if (!(is_countable($files) ? count($files) : 0)) {
$files = glob($dir_logos . $nom_base . '*');
if (is_countable($files) ? count($files) : 0) {
// mais il faut verifier si ils ont pas deja ete migres pour tout ou partie
$filescheck = [];
foreach ($files as $file) {
$short = basename(dirname($file)) . DIRECTORY_SEPARATOR . basename($file);
$filescheck[$short] = $file;
}
// trouver ceux deja migres
$deja = sql_allfetsel('fichier', 'spip_documents', sql_in('fichier', array_keys($filescheck)) . " AND mode LIKE 'logo%'");
if (is_countable($deja) ? count($deja) : 0) {
$deja = array_column($deja, 'fichier');
$restant = array_diff(array_keys($filescheck), $deja);
$files = [];
if (count($restant)) {
foreach ($restant as $r) {
$files[] = $filescheck[$r];
}
}
}
// verifier au cas ou image_reduire a echoue
if ((defined('_LOGO_MAX_WIDTH') and _LOGO_MAX_WIDTH and $size[0] > _LOGO_MAX_WIDTH)
or (defined('_LOGO_MAX_HEIGHT') and _LOGO_MAX_HEIGHT and $size[1] > _LOGO_MAX_HEIGHT)
) {
spip_unlink($file_tmp);
$erreur = _T(
'info_logo_max_poids',
array(
'maxi' =>
_T(
'info_largeur_vignette',
array(
'largeur_vignette' => $max_width,
'hauteur_vignette' => $max_height
)
),
'actuel' =>
_T(
'info_largeur_vignette',
array(
'largeur_vignette' => $size[0],
'hauteur_vignette' => $size[1]
)
)
)
);
// et si il en reste on peut y aller...
// mais il faut modifier $dir qui sert de base dans la suite
if (is_countable($files) ? count($files) : 0) {
$dir = $dir_logos;
}
}
}
if (!$erreur and defined('_LOGO_MAX_SIZE') and _LOGO_MAX_SIZE and $poids > _LOGO_MAX_SIZE * 1024) {
spip_unlink($file_tmp);
$erreur = _T(
'info_logo_max_poids',
array(
'maxi' => taille_en_octets(_LOGO_MAX_SIZE * 1024),
'actuel' => taille_en_octets($poids)
)
);
}
$count = (is_countable($files) ? count($files) : 0);
spip_log("logo_migrer_en_base $objet $mode : " . $count . ' logos restant', 'maj' . _LOG_INFO_IMPORTANTE);
$deja = [];
foreach ($files as $file) {
$logo = substr($file, strlen($dir . $nom_base));
$logo = explode('.', $logo);
if (
is_numeric($logo[0])
and ($id_objet = intval($logo[0]) or in_array($objet, ['site', 'rubrique']))
) {
if (!isset($deja[$id_objet])) {
$logo = $chercher_logo($id_objet, $_id_objet, $mode);
// if no logo in base
if (!$logo or (is_countable($logo) ? count($logo) : 0) < 6) {
foreach ($formats_logos as $format) {
if (@file_exists($d = ($dir . ($nom = $nom_base . intval($id_objet) . '.' . $format)))) {
if (isset($desc['field']['date_modif'])) {
$date_modif = sql_getfetsel('date_modif', $table, "$_id_objet=$id_objet");
} else {
$date_modif = null;
}
// s'assurer que le logo a les bon droits au passage (evite un echec en cas de sanitization d'un svg)
@chmod($d, _SPIP_CHMOD & 0666);
// logo_modifier commence par supprimer le logo existant, donc on le deplace pour pas le perdre
@rename($d, $dir_logos . $nom);
// et on le declare comme nouveau logo
logo_modifier($objet, $id_objet, $mode, $dir_logos . $nom);
if ($date_modif) {
sql_updateq($table, ['date_modif' => $date_modif], "$_id_objet=$id_objet");
}
break;
}
}
}
$deja[$id_objet] = true;
}
}
// si le fichier est encore la on le move : rien a faire ici
// (sauf si c'est une re-migration : il est deja dans logo/ donc il bouge pas)
if ($dir !== $dir_logos and file_exists($file)) {
@rename($file, $dir_logos_erreurs . basename($file));
}
$count--;
if ($count % 250 === 0) {
spip_log("logo_migrer_en_base $objet $mode : " . $count . ' logos restant', 'maj' . _LOG_INFO_IMPORTANTE);
}
if (!$erreur) {
@rename($file_tmp, _DIR_LOGOS . $nom . ".$extension");
if ($time_limit and time() > $time_limit) {
effacer_meta('drapeau_edition');
return;
}
}
} else {
spip_unlink($file_tmp);
$erreur = _T(
'info_logo_format_interdit',
array('formats' => join(', ', $GLOBALS['formats_logos']))
);
}
return $erreur;
if ($liste_objets_versionnes) {
$GLOBALS['meta']['objets_versions'] = $liste_objets_versionnes;
}
$GLOBALS['meta']['articles_modif'] = $articles_modif;
effacer_meta('drapeau_edition');
}

@ -0,0 +1,213 @@
<?php
/**
* Rôles de documents : gestion de l'API de modification/suppression des logos
*
* Surcharge du core.
*
* @plugin Rôles de documents
* @copyright 2015-2018
* @author tcharlss
* @licence GNU/GPL
* @package SPIP\Core\Logo\Edition
*/
// Sécurité
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Supprimer le logo d'un objet
*
* @uses dissocier_document_role()
* @uses chercher_logo()
*
* @param string $objet
* @param int $id_objet
* @param string $role
* - Rôle pour un document : `logo`, `logo_survol`, etc.
* - `on` ou `off` pour un vieux logo
* @return bool
*/
function logo_supprimer($objet, $id_objet, $role) {
$res = false;
$objet = objet_type($objet);
$id_table_objet = id_table_objet($objet);
$etats = array('on', 'off'); // États des vieux logos
// Vieux logos
if (in_array($role, $etats)) {
$chercher_logo = charger_fonction('chercher_logo', 'inc');
$logo = $chercher_logo($id_objet, $id_table_objet, $role, true);
if ($logo) {
$res = spip_unlink($logo[0]);
}
// Documents
// On n'appelle pas directement supprimer_document()
// Il faut faire diverses choses avant, ce dont dissocier_document_role() se charge.
} else {
include_spip('action/editer_liens');
if ($lien_role = objet_trouver_liens(
array('document' => '*'),
array($objet => $id_objet),
array('role' => $role)
)
and $id_document = intval(array_shift(array_column($lien_role, 'id_document')))
) {
$dissocier_document_role = charger_fonction('dissocier_document_role', 'action');
$arg = "$id_objet-$objet-$id_document-$role-suppr-";
$res = $dissocier_document_role($arg);
}
}
return $res;
}
/**
* Modifier ou créer le logo d'un objet
*
* [TODO] : compatibilité avec les documents (création : action/ajouter_documents, modification : action/editer_document)
*
* @param string $objet
* @param int $id_objet
* @param string $etat
* `on` ou `off`
* @param string|array $source
* - array : sous tableau de `$_FILE` issu de l'upload
* - string : fichier source (chemin complet ou chemin relatif a `tmp/upload`)
* @return string
* Erreur, sinon ''
*/
function logo_modifier($objet, $id_objet, $etat, $source) {
$chercher_logo = charger_fonction('chercher_logo', 'inc');
$objet = objet_type($objet);
$primary = id_table_objet($objet);
include_spip('inc/chercher_logo');
$type = type_du_logo($primary);
// nom du logo
$nom = $type . $etat . $id_objet;
// supprimer le logo eventueel existant
logo_supprimer($objet, $id_objet, $etat);
include_spip('inc/documents');
$erreur = '';
if (!$source) {
spip_log('spip_image_ajouter : source inconnue');
$erreur = 'source inconnue';
return $erreur;
}
$file_tmp = _DIR_LOGOS . $nom . '.tmp';
$ok = false;
// fichier dans upload/
if (is_string($source)) {
if (file_exists($source)) {
$ok = @copy($source, $file_tmp);
} elseif (file_exists($f = determine_upload() . $source)) {
$ok = @copy($f, $file_tmp);
}
} elseif (!$erreur = check_upload_error($source['error'], '', true)) {
// Intercepter une erreur a l'envoi
// analyse le type de l'image (on ne fait pas confiance au nom de
// fichier envoye par le browser : pour les Macs c'est plus sur)
$ok = deplacer_fichier_upload($source['tmp_name'], $file_tmp);
}
if ($erreur) {
return $erreur;
}
if (!$ok or !file_exists($file_tmp)) {
spip_log($erreur = "probleme de copie pour $file_tmp ");
return $erreur;
}
$size = @getimagesize($file_tmp);
$extension = !$size ? '' : ($size[2] > 3 ? '' : $GLOBALS['formats_logos'][$size[2] - 1]);
if ($extension) {
@rename($file_tmp, $file_tmp . ".$extension");
$file_tmp = $file_tmp . ".$extension";
$poids = filesize($file_tmp);
if (defined('_LOGO_MAX_WIDTH') or defined('_LOGO_MAX_HEIGHT')) {
if ((defined('_LOGO_MAX_WIDTH') and _LOGO_MAX_WIDTH and $size[0] > _LOGO_MAX_WIDTH)
or (defined('_LOGO_MAX_HEIGHT') and _LOGO_MAX_HEIGHT and $size[1] > _LOGO_MAX_HEIGHT)
) {
$max_width = (defined('_LOGO_MAX_WIDTH') and _LOGO_MAX_WIDTH) ? _LOGO_MAX_WIDTH : '*';
$max_height = (defined('_LOGO_MAX_HEIGHT') and _LOGO_MAX_HEIGHT) ? _LOGO_MAX_HEIGHT : '*';
// pas la peine d'embeter le redacteur avec ca si on a active le calcul des miniatures
// on met directement a la taille maxi a la volee
if (isset($GLOBALS['meta']['creer_preview']) and $GLOBALS['meta']['creer_preview'] == 'oui') {
include_spip('inc/filtres');
$img = filtrer('image_reduire', $file_tmp, $max_width, $max_height);
$img = extraire_attribut($img, 'src');
$img = supprimer_timestamp($img);
if (@file_exists($img) and $img !== $file_tmp) {
spip_unlink($file_tmp);
@rename($img, $file_tmp);
$size = @getimagesize($file_tmp);
}
}
// verifier au cas ou image_reduire a echoue
if ((defined('_LOGO_MAX_WIDTH') and _LOGO_MAX_WIDTH and $size[0] > _LOGO_MAX_WIDTH)
or (defined('_LOGO_MAX_HEIGHT') and _LOGO_MAX_HEIGHT and $size[1] > _LOGO_MAX_HEIGHT)
) {
spip_unlink($file_tmp);
$erreur = _T(
'info_logo_max_poids',
array(
'maxi' =>
_T(
'info_largeur_vignette',
array(
'largeur_vignette' => $max_width,
'hauteur_vignette' => $max_height
)
),
'actuel' =>
_T(
'info_largeur_vignette',
array(
'largeur_vignette' => $size[0],
'hauteur_vignette' => $size[1]
)
)
)
);
}
}
}
if (!$erreur and defined('_LOGO_MAX_SIZE') and _LOGO_MAX_SIZE and $poids > _LOGO_MAX_SIZE * 1024) {
spip_unlink($file_tmp);
$erreur = _T(
'info_logo_max_poids',
array(
'maxi' => taille_en_octets(_LOGO_MAX_SIZE * 1024),
'actuel' => taille_en_octets($poids)
)
);
}
if (!$erreur) {
@rename($file_tmp, _DIR_LOGOS . $nom . ".$extension");
}
} else {
spip_unlink($file_tmp);
$erreur = _T(
'info_logo_format_interdit',
array('formats' => join(', ', $GLOBALS['formats_logos']))
);
}
return $erreur;
}
Loading…
Cancel
Save