Skip to content
Extraits de code Groupes Projets

Comparer les révisions

Les modifications sont affichées comme si la révision source était fusionnée avec la révision cible. En savoir plus sur la comparaison des révisions.

Source

Sélectionner le projet cible
No results found
Sélectionner une révision Git
  • 4.0
  • 4.2
  • 4.3
  • 4.4
  • Titre-complet-documents
  • dev-sortable
  • dev/issue_4645_lien_fichier
  • dev/issue_4913_svg_agrandir
  • issue4887_recherche_id_document_master
  • issue_4480
  • issue_4978
  • master
  • remove_joindre_document_galerie_valide
  • touti-patch-1
  • 4.3.5
  • 4.4.0
  • 4.4.1
  • 4.4.2
  • 4.4.3
  • 4.4.4
  • 4.4.5
  • 5.0.0
  • 5.0.1
  • spip/3.0.0
  • spip/3.0.1
  • spip/3.0.10
  • spip/3.0.11
  • spip/3.0.12
  • spip/3.0.13
  • spip/3.0.14
  • spip/3.0.15
  • spip/3.0.16
  • spip/3.0.17
  • spip/3.0.18
  • spip/3.0.19
  • spip/3.0.2
  • spip/3.0.20
  • spip/3.0.21
  • spip/3.0.22
  • spip/3.0.23
  • spip/3.0.24
  • spip/3.0.25
  • spip/3.0.26
  • spip/3.0.27
  • spip/3.0.28
  • spip/3.0.3
  • spip/3.0.4
  • spip/3.0.5
  • spip/3.0.6
  • spip/3.0.7
  • spip/3.0.8
  • spip/3.0.9
  • spip/3.1.0
  • spip/3.1.1
  • spip/3.1.10
  • spip/3.1.11
  • spip/3.1.12
  • spip/3.1.13
  • spip/3.1.14
  • spip/3.1.15
  • spip/3.1.2
  • spip/3.1.3
  • spip/3.1.4
  • spip/3.1.5
  • spip/3.1.6
  • spip/3.1.7
  • spip/3.1.8
  • spip/3.1.9
  • spip/3.2.0
  • spip/3.2.1
  • spip/3.2.10
  • spip/3.2.11
  • spip/3.2.12
  • spip/3.2.2
  • spip/3.2.3
  • spip/3.2.4
  • spip/3.2.5
  • spip/3.2.6
  • spip/3.2.7
  • spip/3.2.8
  • spip/3.2.9
  • spip/4.0.0
  • spip/4.0.0-alpha
  • spip/4.0.0-beta
  • spip/4.0.1
  • spip/4.0.2
  • spip/4.0.3
  • v0.1.0
  • v1.1.1
  • v1.1.2
  • v1.6.0
  • v2.0.0
  • v2.0.1
  • v2.0.2
  • v2.0.3
  • v2.0.4
  • v2.0.5
  • v2.1.0
  • v2.10.0
  • v2.10.1
  • v2.10.10
  • v2.10.11
  • v2.10.12
  • v2.10.13
  • v2.10.14
  • v2.10.15
  • v2.10.16
  • v2.10.17
  • v2.10.18
  • v2.10.19
  • v2.10.2
  • v2.10.20
  • v2.10.21
  • v2.10.22
114 résultats

Cible

Sélectionner le projet cible
No results found
Sélectionner une révision Git
  • 4.0
  • 4.2
  • 4.3
  • dev-sortable
  • dev/issue_4645_lien_fichier
  • dev/issue_4913_svg_agrandir
  • dev/issue_5000_coherence_logo_document
  • issue4887_recherche_id_document_master
  • issue_4480
  • issue_4935
  • issue_4978
  • issue_deprecated_http_post_files
  • issue_spip_5460
  • master
  • touti-patch-1
  • spip/3.0.0
  • spip/3.0.1
  • spip/3.0.10
  • spip/3.0.11
  • spip/3.0.12
  • spip/3.0.13
  • spip/3.0.14
  • spip/3.0.15
  • spip/3.0.16
  • spip/3.0.17
  • spip/3.0.18
  • spip/3.0.19
  • spip/3.0.2
  • spip/3.0.20
  • spip/3.0.21
  • spip/3.0.22
  • spip/3.0.23
  • spip/3.0.24
  • spip/3.0.25
  • spip/3.0.26
  • spip/3.0.27
  • spip/3.0.28
  • spip/3.0.3
  • spip/3.0.4
  • spip/3.0.5
  • spip/3.0.6
  • spip/3.0.7
  • spip/3.0.8
  • spip/3.0.9
  • spip/3.1.0
  • spip/3.1.1
  • spip/3.1.10
  • spip/3.1.11
  • spip/3.1.12
  • spip/3.1.13
  • spip/3.1.14
  • spip/3.1.15
  • spip/3.1.2
  • spip/3.1.3
  • spip/3.1.4
  • spip/3.1.5
  • spip/3.1.6
  • spip/3.1.7
  • spip/3.1.8
  • spip/3.1.9
  • spip/3.2.0
  • spip/3.2.1
  • spip/3.2.10
  • spip/3.2.11
  • spip/3.2.12
  • spip/3.2.2
  • spip/3.2.3
  • spip/3.2.4
  • spip/3.2.5
  • spip/3.2.6
  • spip/3.2.7
  • spip/3.2.8
  • spip/3.2.9
  • spip/4.0.0
  • spip/4.0.0-alpha
  • spip/4.0.0-beta
  • spip/4.0.1
  • spip/4.0.2
  • spip/4.0.3
  • v0.1.0
  • v1.1.1
  • v1.1.2
  • v1.6.0
  • v2.0.0
  • v2.0.1
  • v2.0.2
  • v2.0.3
  • v2.0.4
  • v2.0.5
  • v2.1.0
  • v2.10.0
  • v2.10.1
  • v2.10.10
  • v2.10.11
  • v2.10.12
  • v2.10.13
  • v2.10.14
  • v2.10.15
  • v2.10.16
  • v2.10.17
  • v2.10.18
  • v2.10.19
  • v2.10.2
  • v2.10.20
  • v2.10.21
  • v2.10.22
  • v2.10.23
  • v2.10.24
  • v2.10.25
  • v2.10.26
  • v2.10.27
  • v2.10.3
  • v2.10.4
  • v2.10.5
  • v2.10.6
115 résultats
Afficher les modifications
375 files
+ 8765
53054
Comparer les modifications
  • Côte à côte
  • En ligne

Fichiers

.editorconfig

0 → 100644
+18 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

[*]
indent_style = tab
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[composer.json]
indent_style = space

[CHANGELOG, *.md]
indent_size = 2

.gitattributes

0 → 100644
+8 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
/.editorconfig export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/phpstan.neon.dist export-ignore
/phpstan-baseline.neon export-ignore
/rector.php export-ignore
/ecs.php export-ignore
/tests export-ignore

.gitignore

0 → 100644
+4 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
/vendor/
/composer.phar
/composer.lock
/phpstan.neon

CHANGELOG.md

0 → 100644
+57 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
# Changelog

## Unreleased

### Added

- spip/spip#5775 Intégration dans médias de fonctions relatives aux logos & documents, qui étaient dans spip/ecrire

### Changed

- #5008 `inc_vignette_dist()` prend un media en second argument, pour décliner la vignette selon le type de fichier

### Fixed

- #5008 Calcul dynamique de `#MIME_TYPE` (qui peut varier par exemple pour les mp4 selon le media de type video, audio, ...)
- #5016 La navigation dans la médiathèque peut recevoir n'importe quel id d'objet

## 5.0.1 - 2025-12-21

### Added

- require `spip/archiviste=^3.0`

### Changed

- spip/spip#5566 / !5018 Animations de sélection/ajout/retrait de documents sans jQuery

## 5.0.0 - 2025-11-27

### Added

- Installable en tant que package Composer

### Changed

- spip/spip#6043 utilisation de la méthode de chargement `initjs`
- Utiliser `#LAYOUT_PRIVE` plutôt que `#LARGEUR_ECRAN`
- #4958 Appel à la globale `$formats_logos` remplacée par `_image_extensions_acceptees_en_entree()`
- Externalisation de la lib [james-heinrich/getid3](https://packagist.org/packages/james-heinrich/getid3)
- Appel de l'archiviste via `use Spip\Archiver\SpipArchiver`
- Compatible SPIP 5.0.0-dev

### Fixed

- spip/spip#5460 Utiliser les propriétés logiques dans la CSS de l'espace privé
- #5000 Ne plus réduire implicitement (dans certains cas) l’image retournée par `#LOGO_DOCUMENT`
- !5008 Corriger la duplication (plugin Duplicator par exemple) de logo si le dossier `tmp/upload` n'existe pas
- #4999 Affichage du sélecteur de rôles de documents (avec le plugin en question)
- !5009 Affichage des aperçus dans les modèles emb
- !5010 Correction chemin des plugins mediaelements
- !5010 Pas de fallback Flash

### Removed

- #4935 Gestion historique du portfolio. Suppression de `_COMPORTEMENT_HISTORIQUE_PORTFOLIO`, `_COMPORTEMENT_HISTORIQUE_IMG_DOC_EMB`
& `affiche_bouton_mode_image_portfolio()` et squelettes liés

README.md

0 → 100644
+3 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
# Plugin Médias

Ce plugin gère les documents éditoriaux (médias images, sons, pdf, ...)
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
@@ -21,22 +20,22 @@ include_spip('inc/headers');
// soit que le document est publie, c'est-a-dire
// joint a au moins 1 article ou rubrique publie

// https://code.spip.net/@action_acceder_document_dist
function action_acceder_document_dist() {
	$doc = [];
	include_spip('inc/documents');

	// $file exige pour eviter le scan id_document par id_document
	$f = rawurldecode(_request('file'));
	$f = rawurldecode((string) _request('file'));
	$file = get_spip_doc($f);
	$arg = rawurldecode(_request('arg'));
	$arg = rawurldecode((string) _request('arg'));

	$status = false;
	if (strpos($f, '../') !== false
		or preg_match(',^\w+://,', $f)
	if (
		str_contains($f, '../') || preg_match(',^\w+://,', $f)
	) {
		$status = 403;
	} else {
		if (!file_exists($file) or !is_readable($file)) {
		if (!file_exists($file) || !is_readable($file)) {
			$status = 404;
		} else {
			$where = 'D.fichier=' . sql_quote(set_spip_doc($file))
@@ -52,14 +51,13 @@ function action_acceder_document_dist() {
			} else {
				// ETag pour gerer le status 304
				$ETag = md5($file . ': ' . filemtime($file));
				if (isset($_SERVER['HTTP_IF_NONE_MATCH'])
					and $_SERVER['HTTP_IF_NONE_MATCH'] == $ETag
				if (
					isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $ETag
				) {
					http_status(304); // Not modified
					http_response_code(304); // Not modified
					exit;
				} else {
					header('ETag: ' . $ETag);
				}
				header('ETag: ' . $ETag);

				//
				// Verifier les droits de lecture du document
@@ -82,47 +80,28 @@ function action_acceder_document_dist() {
			break;

		case 404:
			http_status(404);
			http_response_code(404);
			include_spip('inc/minipres');
			echo minipres(_T('erreur') . ' 404', _T('medias:info_document_indisponible'));
			break;

		default:
			header('Content-Type: ' . $doc['mime_type']);

			// pour les images ne pas passer en attachment
			// sinon, lorsqu'on pointe directement sur leur adresse,
			// le navigateur les downloade au lieu de les afficher
			include_spip('inc/livrer_fichier');

			$options = ['attachment' => false];
			if ($doc['inclus'] == 'non') {
				$options['attachment'] = true;
				// Si le fichier a un titre avec extension,
				// ou si c'est un nom bien connu d'Unix, le prendre
				// sinon l'ignorer car certains navigateurs pataugent

				$f = basename($file);
				if (isset($doc['titre'])
					and (preg_match('/^\w+[.]\w+$/', $doc['titre']) or $doc['titre'] == 'Makefile')
				if (
					isset($doc['titre']) && (preg_match('/^\w+[.]\w+$/', (string) $doc['titre']) || $doc['titre'] == 'Makefile')
				) {
					$f = $doc['titre'];
				}

				// ce content-type est necessaire pour eviter des corruptions de zip dans ie6
				header('Content-Type: application/octet-stream');

				header("Content-Disposition: attachment; filename=\"$f\";");
				header('Content-Transfer-Encoding: binary');

				// fix for IE catching or PHP bug issue
				header('Pragma: public');
				header('Expires: 0'); // set expiration time
				header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
					$options['attachment'] = $doc['titre'];
				}

			if ($cl = filesize($file)) {
				header('Content-Length: ' . $cl);
			}

			readfile($file);
			spip_livrer_fichier($file, $doc['mime_type'], $options);
			exit;
			break;
	}
}
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?php

use Spip\Archiver\SpipArchiver;

/***************************************************************************\
 *  SPIP, Système de publication pour l'internet                           *
 *                                                                         *
@@ -7,14 +9,13 @@
 *  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.   *
\***************************************************************************/

/**
 * Gestion de l'action ajouter_documents
 *
 * @package SPIP\Medias\Action
 **/
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
@@ -44,7 +45,7 @@ include_spip('inc/renseigner_document');
 */
function action_ajouter_documents_dist($id_document, $files, $objet, $id_objet, $mode) {
	$ajouter_un_document = charger_fonction('ajouter_un_document', 'action');
	$ajoutes = array();
	$ajoutes = [];

	// on ne peut mettre qu'un seul document a la place d'un autre ou en vignette d'un autre
	if (intval($id_document)) {
@@ -82,7 +83,6 @@ function action_ajouter_documents_dist($id_document, $files, $objet, $id_objet,
 *
 *   - int : l'id_document ajouté (opération réussie)
 *   - string : une erreur s'est produit, la chaine est le message d'erreur
 *
 */
function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet, $mode) {

@@ -95,17 +95,30 @@ function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet,
	// et on aura une collision en cas de changement de file system
	$file['name'] = strtolower(translitteration($file['name']));

	// Sécurité : si jamais il existe deja une entrée dans la BDD avec ce chemin de document, remettre le document dans tmp, ce qui permettra ensuite qu'il soit dupliqué, et qu'il n'y ait pas deux entrées en base avec la même ligne 'fichier'.
	// Cela n'arrive que si $file indique un document qui se trouve déjà dans IMG.
	while (sql_getfetsel('fichier', 'spip_documents', 'fichier=' . sql_quote(set_spip_doc($file['tmp_name'])))) {
		$tmp = tempnam(is_dir(_DIR_TRANSFERT) ? _DIR_TRANSFERT : _DIR_TMP, $file['tmp_name']);
		if (deplacer_fichier_upload($file['tmp_name'], $tmp)) {
			$file['tmp_name'] = $tmp;
		} else {
			spip_log('Erreur lors de la tenative de copie de ' . $file['tmp_name'] . ' en ' . $tmp, 'medias' . _LOG_ERREUR);
			break;
		}
	}

	// Pouvoir definir dans mes_options.php que l'on veut titrer tous les documents par d?faut
	if (!defined('_TITRER_DOCUMENTS')) {
		define('_TITRER_DOCUMENTS', false);
	}

	$titrer = isset($file['titrer']) ? $file['titrer'] : _TITRER_DOCUMENTS;
	$mode = ((isset($file['mode']) and $file['mode']) ? $file['mode'] : $mode);
	$titrer = $file['titrer'] ?? _TITRER_DOCUMENTS;
	$mode = ((isset($file['mode']) && $file['mode']) ? $file['mode'] : $mode);

	include_spip('inc/modifier');
	if (isset($file['distant']) and $file['distant']
		and !in_array($mode, array('choix', 'auto', 'image', 'document'))) {
	if (
		isset($file['distant']) && $file['distant'] && !in_array($mode, ['choix', 'auto', 'image', 'document'])
	) {
		spip_log("document distant $source accepte sans verification, mode=$mode", 'medias' . _LOG_INFO_IMPORTANTE);
		include_spip('inc/distant');
		$file['tmp_name'] = _DIR_RACINE . copie_locale($source);
@@ -116,22 +129,29 @@ function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet,
	// Documents distants : pas trop de verifications bloquantes, mais un test
	// via une requete HEAD pour savoir si la ressource existe (non 404), si le
	// content-type est connu, et si possible recuperer la taille, voire plus.
	if (isset($file['distant']) and $file['distant']) {
	if (isset($file['distant']) && $file['distant']) {
		if (!tester_url_absolue($source)) {
			return _T('medias:erreur_chemin_distant', array('nom' => $source));
			return _T('medias:erreur_chemin_distant', ['nom' => $source]);
		}
		include_spip('inc/distant');
		$source = str_replace(array("'",'"','<'),array("%27",'%22','%3C'), $source);
		$source = str_replace(["'", '"', '<'], ['%27', '%22', '%3C'], $source);
		if (is_array($a = renseigner_source_distante($source))) {
			$champs = $a;
			# NB: dans les bonnes conditions (fichier autorise et pas trop gros)
			# $a['fichier'] est une copie locale du fichier
			# $a['copie_locale'] est une copie locale du fichier

			// voir si le document a besoin d'un nettoyage et le cas echeant relire ses infos apres
			if (!empty($champs['copie_locale']) && file_exists($champs['copie_locale'])) {
				$res_sanitize = sanitizer_document($champs['copie_locale'], $champs['extension']);
				$infos = renseigner_taille_dimension_image($champs['copie_locale'], $champs['extension']);
			} else {
				$infos = renseigner_taille_dimension_image($champs['fichier'], $champs['extension'], true);
			}

			// on ignore erreur eventuelle sur $infos car on est distant, ca ne marche pas forcement
			if (is_array($infos)) {
				foreach ($infos as $k => $v) {
					if (!empty($v) or empty($champs[$k])) {
					if (!empty($v) || empty($champs[$k])) {
						$champs[$k] = $v;
					}
				}
@@ -145,26 +165,28 @@ function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet,
			return $a; // message d'erreur
		}
	} else { // pas distant

		$champs = array(
			'distant' => 'non'
		);
		$champs = [
			'distant' => 'non',
		];

		$champs['titre'] = '';
		if ($titrer) {
			if ($titrer_document = charger_fonction('titrer_document', 'inc', true)) {
				$champs['titre'] = $titrer_document($nom_envoye);
			}
			else {
				$titre = substr($nom_envoye, 0, strrpos($nom_envoye, '.')); // Enlever l'extension du nom du fichier
			} else {
				$titre = substr(
					(string) $nom_envoye,
					0,
					strrpos((string) $nom_envoye, '.')
				); // Enlever l'extension du nom du fichier
				$titre = preg_replace(',[[:punct:][:space:]]+,u', ' ', $titre);
				$champs['titre'] = preg_replace(',\.([^.]+)$,', '', $titre);
				$champs['titre'] = preg_replace(',\.([^.]+)$,', '', (string) $titre);
			}
		}

		if (!is_array($fichier = fixer_fichier_upload($file, $mode))) {
			return is_string($fichier) ?
				$fichier : _T('medias:erreur_upload_type_interdit', array('nom' => $file['name']));
				$fichier : _T('medias:erreur_upload_type_interdit', ['nom' => $file['name']]);
		}

		$champs['inclus'] = $fichier['inclus'];
@@ -187,10 +209,18 @@ function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet,

		// lorsqu’une image arrive avec une mauvaise extension par rapport au mime type, adapter.
		// Exemple : si extension .jpg mais le contenu est un png
		if (!empty($infos['type_image']) and $infos['type_image'] !== $champs['extension']) {
			spip_log('Image `' . $file['name'] . '` mauvaise extension. Correcte : ' . $infos['type_image'], 'medias' . _LOG_INFO);
		if (!empty($infos['type_image']) && $infos['type_image'] !== $champs['extension']) {
			spip_log(
				'Image `' . $file['name'] . '` mauvaise extension. Correcte : ' . $infos['type_image'],
				'medias' . _LOG_INFO
			);
			$subdir = determiner_sous_dossier_document($infos['type_image'], $file['name'] . '.' . $infos['type_image'], $mode);
			$new = copier_document($infos['type_image'], $file['name'] . '.' . $infos['type_image'], $champs['fichier'], $subdir);
			$new = copier_document(
				$infos['type_image'],
				$file['name'] . '.' . $infos['type_image'],
				$champs['fichier'],
				$subdir
			);
			if ($new) {
				supprimer_fichier($champs['fichier']);
				$champs['fichier'] = $new;
@@ -202,7 +232,10 @@ function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet,
				}
				spip_log('> Image `' . $file['name'] . '` renommée en : ' . basename($champs['fichier']), 'medias' . _LOG_INFO);
			} else {
				spip_log('! Image  `' . $file['name'] . '` non renommée en extension : ' . $champs['extension'], 'medias' . _LOG_INFO_IMPORTANTE);
				spip_log(
					'! Image  `' . $file['name'] . '` non renommée en extension : ' . $champs['extension'],
					'medias' . _LOG_INFO_IMPORTANTE
				);
			}
		}

@@ -214,7 +247,7 @@ function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet,
		$champs = array_merge($champs, $infos);

		// Si mode == 'choix', fixer le mode image/document
		if (in_array($mode, array('choix', 'auto'))) {
		if (in_array($mode, ['choix', 'auto'])) {
			$choisir_mode_document = charger_fonction('choisir_mode_document', 'inc');
			$mode = $choisir_mode_document($champs, $champs['inclus'] == 'image', $objet);
		}
@@ -246,7 +279,7 @@ function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet,

	// lier le parent si necessaire
	// attention au cas particulier du site 0 utilisé pour le logo du site
	if ($objet and (($id_objet = intval($id_objet)) or in_array($objet, ['site', 'rubrique']))) {
	if ($objet && (($id_objet = intval($id_objet)) || in_array($objet, ['site', 'rubrique']))) {
		$champs['parents'][] = "$objet|$id_objet";
	}

@@ -276,7 +309,7 @@ function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet,
		}
	}
	if (!$id_document) {
		return _T('medias:erreur_insertion_document_base', array('fichier' => '<em>' . $file['name'] . '</em>'));
		return _T('medias:erreur_insertion_document_base', ['fichier' => '<em>' . $file['name'] . '</em>']);
	}

	document_modifier($id_document, $champs);
@@ -286,8 +319,8 @@ function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet,
	// Ce plugin ferait quand même mieux de se placer dans metadata/jpg.php
	pipeline(
		'post_edition',
		array(
			'args' => array(
		[
			'args' => [
				'table' => 'spip_documents', // compatibilite
				'table_objet' => 'documents',
				'spip_table_objet' => 'spip_documents',
@@ -297,9 +330,9 @@ function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet,
				'serveur' => '', // serveur par defaut, on ne sait pas faire mieux pour le moment
				'action' => 'ajouter_document',
				'operation' => 'ajouter_document', // compat <= v2.0
			),
			'data' => $champs
		)
			],
			'data' => $champs,
		]
	);

	return $id_document;
@@ -308,52 +341,13 @@ function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet,
/**
 * Sous-repertoire dans lequel on stocke le document
 * en regle general $ext/ sauf pour les logo
 * @param $ext
 * @param $fichier
 * @param $mode
 * @return mixed
 */
function determiner_sous_dossier_document($ext, $fichier, $mode) {

	// si mode un logoxx on met dans logo/
	if (strncmp($mode, 'logo', 4) === 0) {
		return "logo";
	}

	return $ext;
}

/**
 * Corrige l'extension du fichier dans quelques cas particuliers
 *
 * @note
 *     Une extension 'pdf ' passe dans la requête de contrôle
 *     mysql> SELECT * FROM spip_types_documents WHERE extension="pdf ";
 *
 * @todo
 *     À passer dans base/typedoc
 *
 * @param string $ext
 * @return string
 */
function corriger_extension($ext) {
	$ext = preg_replace(',[^a-z0-9],i', '', $ext);
	switch ($ext) {
		case 'htm':
			$ext = 'html';
			break;
		case 'jpeg':
			$ext = 'jpg';
			break;
		case 'tiff':
			$ext = 'tif';
			break;
		case 'aif':
			$ext = 'aiff';
			break;
		case 'mpeg':
			$ext = 'mpg';
			break;
	if (str_starts_with((string) $mode, 'logo')) {
		return 'logo';
	}

	return $ext;
@@ -376,31 +370,36 @@ function corriger_extension($ext) {
 *     - false ou message d'erreur si l'extension est refusée
 */
function verifier_upload_autorise($source, $mode = '') {
	$infos = array('fichier' => $source);
	$infos = ['fichier' => $source];
	$res = false;
	if (preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $source, $match)
		and $ext = $match[1]
	if (
		preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $source, $match)
		&& ($ext = $match[1])
	) {
		$ext = corriger_extension(strtolower($ext));
		if ($res = sql_fetsel(
		if (
			$res = sql_fetsel(
				'extension,inclus,media_defaut as media',
				'spip_types_documents',
				'extension=' . sql_quote($ext) . " AND upload='oui'"
		)) {
			)
		) {
			$infos = array_merge($infos, $res);
		}
	}
	if (!$res) {
		if ($res = sql_fetsel(
		if (
			$res = sql_fetsel(
				'extension,inclus,media_defaut as media',
				'spip_types_documents',
				"extension='zip' AND upload='oui'"
		)) {
			)
		) {
			$infos = array_merge($infos, $res);
			$res['autozip'] = true;
		}
	}
	if ($mode and $res) {
	if ($mode && $res) {
		// verifier en fonction du mode si une fonction est proposee
		if ($verifier_document_mode = charger_fonction('verifier_document_mode_' . $mode, 'inc', true)) {
			$check = $verifier_document_mode($infos); // true ou message d'erreur sous forme de chaine
@@ -410,14 +409,13 @@ function verifier_upload_autorise($source, $mode = '') {
		}
	}

	if (!$res or is_string($res)) {
	if (!$res || is_string($res)) {
		spip_log("Upload $source interdit ($res)", _LOG_INFO_IMPORTANTE);
	}

	return $res;
}


/**
 * Tester le type de document
 *
@@ -449,11 +447,11 @@ function fixer_fichier_upload($file, $mode = '') {
			if ($row['fichier'] && (!$taille = @intval(filesize(get_spip_doc($row['fichier']))))) {
				spip_log('Echec copie du fichier ' . $file['tmp_name'] . ' (taille de fichier indéfinie)');
				spip_unlink(get_spip_doc($row['fichier']));
				return _T('medias:erreur_copie_fichier', array('nom' => $file['tmp_name']));
			} else {
				return _T('medias:erreur_copie_fichier', ['nom' => $file['tmp_name']]);
			}
			return $row;

		}
		} else {
		// creer un zip comme demande
		// pour encapsuler un fichier dont l'extension n'est pas supportee
		unset($row['autozip']);
@@ -477,8 +475,7 @@ function fixer_fichier_upload($file, $mode = '') {

		$source = _DIR_TMP . basename($tmp_dir) . '.' . $ext;

			include_spip('inc/archives');
			$archive = new Spip\Archives\SpipArchives($source);
		$archive = new SpipArchiver($source);
		$res = $archive->emballer([$tmp]);

		effacer_repertoire_temporaire($tmp_dir);
@@ -497,14 +494,13 @@ function fixer_fichier_upload($file, $mode = '') {
			spip_log('Echec copie du fichier ' . $file['tmp_name'] . ' (taille de fichier indéfinie)');
			spip_unlink(get_spip_doc($row['fichier']));

				return _T('medias:erreur_copie_fichier', array('nom' => $file['tmp_name']));
			} else {
				return $row;
			return _T('medias:erreur_copie_fichier', ['nom' => $file['tmp_name']]);
		}
		return $row;

	}
	} else {
	return $row;
	} // retourner le message d'erreur
	// retourner le message d'erreur
}

/**
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}


/**
 * Cette action permet de basculer du mode image au mode document et vice versa
 *
 * https://code.spip.net/@action_changer_mode_document_dist
 *
 * @param int $id_document
 * @param string $mode
 * @return void
 */
function action_changer_mode_document_dist($id_document = null, $mode = null) {
	if (is_null($id_document) or is_null($mode)) {
	if ($id_document === null || $mode === null) {
		$securiser_action = charger_fonction('securiser_action', 'inc');
		$arg = $securiser_action();

		if (!preg_match(',^(\d+)\W(\w+)$,', $arg, $r)) {
		if (!preg_match(',^(\d+)\W(\w+)$,', (string) $arg, $r)) {
			spip_log("action_changer_mode_document $arg pas compris");
		} else {
			array_shift($r);
			list($id_document, $mode) = $r;
			[$id_document, $mode] = $r;
		}
	}

	if ($id_document
		and include_spip('inc/autoriser')
		and autoriser('modifier', 'document', $id_document)
	if (
		$id_document && include_spip('inc/autoriser') && autoriser('modifier', 'document', $id_document)
	) {
		action_changer_mode_document_post($id_document, $mode);
	}
}

// https://code.spip.net/@action_changer_mode_document_post
function action_changer_mode_document_post($id_document, $mode) {
	// - id_document le doc a modifier
	// - mode le mode a lui donner
	if ($id_document = intval($id_document)
		and in_array($mode, array('vignette', 'image', 'document'))
	if (
		($id_document = intval($id_document))
		&& in_array($mode, ['vignette', 'image', 'document'])
	) {
		include_spip('action/editer_document');
		document_modifier($id_document, array('mode' => $mode));
		document_modifier($id_document, ['mode' => $mode]);
	}
}
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
@@ -20,8 +19,6 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 * Il s'agit de la partie logique, c'est a dire que cette fonction
 * realise la copie.
 *
 * https://code.spip.net/@action_copier_local_dist
 *
 * @param null $id_document
 * @return bool|mixed|string
 */
@@ -39,16 +36,13 @@ function action_copier_local_dist($id_document = null) {
		spip_log("action_copier_local_dist $arg pas compris");

		return false;
	} else {
	}
	// arguments recuperes, on peut maintenant appeler la fonction.
	return action_copier_local_post($id_document);
	}

}

/**
 * https://code.spip.net/@action_copier_local_post
 *
 * @param  $id_document
 * @return bool|mixed|string
 */
function action_copier_local_post($id_document) {
@@ -59,35 +53,40 @@ function action_copier_local_post($id_document) {

	// si la source est bien un fichier distant
	// sinon c'est une donnee moisie, on ne fait rien
	if (tester_url_absolue($source)) {
		include_spip('inc/distant'); // pour 'copie_locale'
		$fichier = copie_locale($source);
		if ($fichier
			and tester_url_absolue($source)) {
	include_spip('inc/distant');
	if (
		tester_url_absolue($source) && valider_url_distante($source)
	) {
		// on fait une copie locale en verifiant aussi l'URL finale qui a été récupérée
		$fichier = copie_locale($source, 'auto', null, null, 'valider_url_distante');
		// on revalide la source *apres* copie car si elle est controlee par un serveur dns malicieux elle peut etre changeante
		if (
			$fichier && valider_url_distante($source)
		) {
			$fichier = _DIR_RACINE . $fichier;
			$files = array();
			$files[] = array('tmp_name' => $fichier, 'name' => basename($fichier));
			$files = [];
			$files[] = ['tmp_name' => $fichier, 'name' => basename($fichier)];
			$ajouter_documents = charger_fonction('ajouter_documents', 'action');
			spip_log("convertit doc $id_document en local: $source => $fichier", 'medias');
			$liste = array();
			$liste = [];
			$ajouter_documents($id_document, $files, '', 0, $row['mode'], $liste);

			spip_unlink($fichier);

			// ajouter l'origine du document aux credits
			include_spip('action/editer_document');
			document_modifier(
				$id_document,
				array('credits' => ($row['credits'] ? $row['credits'] . ', ' : '') . $source)
			);
			document_modifier($id_document, ['credits' => ($row['credits'] ? $row['credits'] . ', ' : '') . $source]);

			return true;
		} else {
		}
		spip_log("echec copie locale $source", 'medias' . _LOG_ERREUR);
		if ($fichier) {
			@unlink(_DIR_RACINE . $fichier);
		}

	} else {
		spip_log("echec copie locale $source n'est pas une URL distante", 'medias' . _LOG_ERREUR);
	}

	return _T('medias:erreur_copie_fichier', array('nom' => $source));
	return _T('medias:erreur_copie_fichier', ['nom' => $source]);
}
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

/**
 * Gestion de l'action desordonner_document
 *
 * @package SPIP\Medias\Action
 **/

 */
if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}


/**
 * Désordonner des documents
 *
@@ -30,25 +27,22 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 *
 *     - 4eme arg : suppr = true, false sinon
 *     - 5eme arg : safe = true, false sinon
 *
 * @return void
 */
function action_desordonner_liens_documents_dist($arg = null) {
	if (is_null($arg)) {
	if ($arg === null) {
		$securiser_action = charger_fonction('securiser_action', 'inc');
		$arg = $securiser_action();
	}

	$arg = explode('-', $arg);
	list($id_objet, $objet, $document) = $arg;
	$arg = explode('-', (string) $arg);
	[$id_objet, $objet, $document] = $arg;

	if (
		$id_objet = intval($id_objet)
		and autoriser('desordonnerdocuments', $objet, $id_objet)
		($id_objet = intval($id_objet)) && autoriser('desordonnerdocuments', $objet, $id_objet)
	) {
		desordonner_liens_documents($document, $objet, $id_objet);
	} else {
		spip_log("Interdit de désordonner les documents sur : $objet $id_objet", 'spip');
		spip_logger()->info("Interdit de désordonner les documents sur : $objet $id_objet");
	}
}

@@ -64,16 +58,16 @@ function action_desordonner_liens_documents_dist($arg = null) {
 *   objet duquel dissocier
 * @param  $id_objet
 *   id_objet duquel dissocier
 * @return void
 */
function desordonner_liens_documents($document, $objet, $id_objet) {
	include_spip('action/editer_liens');
	if ($id_document = intval($document)) {
		desordonner_liens_document($id_document, $objet, $id_objet);
	} else {
		list($image, $mode) = explode('/', $document);
		[$image, $mode] = explode('/', $document);
		$image = ($image == 'I');
		$typdoc = sql_in('docs.extension', array('gif', 'jpg', 'png'), $image ? '' : 'NOT');
		include_spip('inc/filtres_images_lib_mini');
		$typdoc = sql_in('docs.extension', _image_extensions_logos(), $image ? '' : 'NOT');

		$obj = 'id_objet=' . intval($id_objet) . ' AND objet=' . sql_quote($objet);

@@ -97,12 +91,7 @@ function desordonner_liens_documents($document, $objet, $id_objet) {
 *   objet duquel dissocier
 * @param  $id_objet
 *   id_objet duquel dissocier
 * @return void
 */
function desordonner_liens_document($id_document, $objet, $id_objet) {
	objet_qualifier_liens(
		array('document' => $id_document),
		array($objet => $id_objet),
		array('rang_lien' => 0)
	);
	objet_qualifier_liens(['document' => $id_document], [$objet => $id_objet], ['rang_lien' => 0]);
}
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

/**
 * Gestion de l'action dissocier_document
 *
 * @package SPIP\Medias\Action
 **/

 */
if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}


/**
 * Dissocier un document
 *
@@ -30,41 +27,40 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 *
 *     - 4eme arg : suppr = true, false sinon
 *     - 5eme arg : safe = true, false sinon
 *
 * @return void
 */
function action_dissocier_document_dist($arg = null) {
	if (is_null($arg)) {
	if ($arg === null) {
		$securiser_action = charger_fonction('securiser_action', 'inc');
		$arg = $securiser_action();
	}

	// attention au cas ou id_objet est negatif !
	if (strncmp($arg, '-', 1) == 0) {
		$arg = explode('-', substr($arg, 1));
		list($id_objet, $objet, $document) = $arg;
	if (str_starts_with((string) $arg, '-')) {
		$arg = explode('-', substr((string) $arg, 1));
		[$id_objet, $objet, $document] = $arg;
		$id_objet = -$id_objet;
	} else {
		$arg = explode('-', $arg);
		list($id_objet, $objet, $document) = $arg;
		$arg = explode('-', (string) $arg);
		[$id_objet, $objet, $document] = $arg;
	}

	$suppr = $check = false;
	if (count($arg) > 3 and $arg[3] == 'suppr') {
	if (count($arg) > 3 && $arg[3] == 'suppr') {
		$suppr = true;
	}
	if (count($arg) > 4 and $arg[4] == 'safe') {
	if (count($arg) > 4 && $arg[4] == 'safe') {
		$check = true;
	}
	if ($id_objet = intval($id_objet)
		and (
			($id_objet < 0 and $id_objet == -$GLOBALS['visiteur_session']['id_auteur'])
			or autoriser('dissocierdocuments', $objet, $id_objet)
	if (
		($id_objet = intval($id_objet))
		&& (
			($id_objet < 0 && $id_objet == -$GLOBALS['visiteur_session']['id_auteur'])
			|| autoriser('dissocierdocuments', $objet, $id_objet)
		)
	) {
		dissocier_document($document, $objet, $id_objet, $suppr, $check);
	} else {
		spip_log("Interdit de modifier $objet $id_objet", 'spip');
		spip_logger()->info("Interdit de modifier $objet $id_objet");
	}
}

@@ -82,7 +78,7 @@ function action_dissocier_document_dist($arg = null) {
 * @return bool
 */
function supprimer_lien_document($id_document, $objet, $id_objet, $supprime = false, $check = false) {
	if (!$id_document = intval($id_document)) {
	if (!($id_document = intval($id_document))) {
		return false;
	}

@@ -91,11 +87,11 @@ function supprimer_lien_document($id_document, $objet, $id_objet, $supprime = fa

	// D'abord on ne supprime pas, on dissocie
	include_spip('action/editer_liens');
	objet_dissocier(array('document' => $id_document), array($objet => $id_objet), array('role' => '*'));
	objet_dissocier(['document' => $id_document], [$objet => $id_objet], ['role' => '*']);

	// Si c'est une vignette, l'eliminer du document auquel elle appartient
	// cas tordu peu probable
	sql_updateq('spip_documents', array('id_vignette' => 0), 'id_vignette=' . $id_document);
	sql_updateq('spip_documents', ['id_vignette' => 0], 'id_vignette=' . $id_document);

	// verifier son statut apres une suppression de lien
	include_spip('action/editer_document');
@@ -103,21 +99,21 @@ function supprimer_lien_document($id_document, $objet, $id_objet, $supprime = fa

	// Invalider les caches
	include_spip('inc/invalideur');
	suivre_invalideur("id='id_document/$id_document'");
	suivre_invalideur("id='document/$id_document'");

	pipeline(
		'post_edition',
		array(
			'args' => array(
		[
			'args' => [
				'operation' => 'delier_document', // compat v<=2
				'action' => 'delier_document',
				'table' => 'spip_documents',
				'id_objet' => $id_document,
				'objet' => $objet,
				'id' => $id_objet
			),
			'data' => null
		)
				'id' => $id_objet,
			],
			'data' => null,
		]
	);

	if ($check) {
@@ -125,7 +121,7 @@ function supprimer_lien_document($id_document, $objet, $id_objet, $supprime = fa
		$spip_table_objet = table_objet_sql($objet);
		$table_objet = table_objet($objet);
		$id_table_objet = id_table_objet($objet, $serveur);
		$champs = sql_fetsel('*', $spip_table_objet, addslashes($id_table_objet) . '=' . intval($id_objet));
		$champs = sql_fetsel('*', $spip_table_objet, addslashes((string) $id_table_objet) . '=' . intval($id_objet));

		$marquer_doublons_doc = charger_fonction('marquer_doublons_doc', 'inc');
		$marquer_doublons_doc($champs, $id_objet, $objet, $id_table_objet, $table_objet, $spip_table_objet, '', $serveur);
@@ -134,11 +130,13 @@ function supprimer_lien_document($id_document, $objet, $id_objet, $supprime = fa
	// On supprime ensuite s'il est orphelin
	// et si demande
	// ici on ne bloque pas la suppression d'un document rattache a un autre
	if ($supprime and !sql_countsel('spip_documents_liens', "objet!='document' AND id_document=" . $id_document)) {
	if ($supprime && !sql_countsel('spip_documents_liens', "objet!='document' AND id_document=" . $id_document)) {
		$supprimer_document = charger_fonction('supprimer_document', 'action');

		return $supprimer_document($id_document);
	}

	return true;
}

/**
@@ -157,15 +155,14 @@ function supprimer_lien_document($id_document, $objet, $id_objet, $supprime = fa
 *   supprimer les documents orphelins apres dissociation
 * @param bool $check
 *   verifier le texte des documents et relier les documents references dans l'objet
 * @return void
 */
function dissocier_document($document, $objet, $id_objet, $supprime = false, $check = false) {
	if ($id_document = intval($document)) {
		supprimer_lien_document($id_document, $objet, $id_objet, $supprime, $check);
	} else {
		list($image, $mode) = explode('/', $document);
		[$image, $mode] = explode('/', $document);
		$image = ($image == 'I');
		$typdoc = sql_in('docs.extension', array('gif', 'jpg', 'png'), $image ? '' : 'NOT');
		$typdoc = sql_in('docs.extension', ['gif', 'jpg', 'png'], $image ? '' : 'NOT');

		$obj = 'id_objet=' . intval($id_objet) . ' AND objet=' . sql_quote($objet);

Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}


/**
 * Action editer_document
 *
@@ -23,7 +21,7 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 */
function action_editer_document_dist($arg = null) {

	if (is_null($arg)) {
	if ($arg === null) {
		$securiser_action = charger_fonction('securiser_action', 'inc');
		$arg = $securiser_action();
	}
@@ -34,12 +32,12 @@ function action_editer_document_dist($arg = null) {
	}

	if (!$id_document) {
		return array(0, '');
		return [0, ''];
	} // erreur

	$err = document_modifier($id_document);

	return array($id_document, $err);
	return [$id_document, $err];
}

/**
@@ -52,41 +50,37 @@ function action_editer_document_dist($arg = null) {
 */
function document_inserer($id_parent = null, $set = null) {

	$champs = array(
	$champs = [
		'statut' => 'prop',
		'date' => 'NOW()',
	);
	];

	if ($set) {
		$champs = array_merge($champs, $set);
	}

	// Envoyer aux plugins
	$champs = pipeline(
		'pre_insertion',
		array(
			'args' => array(
	$champs = pipeline('pre_insertion', [
		'args' => [
			'table' => 'spip_documents',
			),
			'data' => $champs
		)
	);
		],
		'data' => $champs,
	]);
	$id_document = sql_insertq('spip_documents', $champs);
	pipeline(
		'post_insertion',
		array(
			'args' => array(
		[
			'args' => [
				'table' => 'spip_documents',
				'id_objet' => $id_document
			),
			'data' => $champs
		)
				'id_objet' => $id_document,
			],
			'data' => $champs,
		]
	);

	return $id_document;
}


/**
 * Enregistre une revision de document.
 * $set est un contenu (par defaut on prend le contenu via _request())
@@ -105,12 +99,11 @@ function document_modifier($id_document, $set = null) {
		// white list
		objet_info('document', 'champs_editables'),
		// black list
		array('parents', 'ajout_parents'),
		['parents', 'ajout_parents'],
		// donnees eventuellement fournies
		$set
	);


	$invalideur = '';
	$indexation = false;

@@ -127,33 +120,36 @@ function document_modifier($id_document, $set = null) {
		$ancien_fichier = sql_getfetsel('fichier', 'spip_documents', 'id_document=' . intval($id_document));
	}

	if ($err = objet_modifier_champs(
	if (
		$err = objet_modifier_champs(
			'document',
			$id_document,
		array(
			[
				'data' => $set,
				'invalideur' => $invalideur,
			'indexation' => $indexation
		),
				'indexation' => $indexation,
			],
			$champs
	)) {
		)
	) {
		return $err;
	}

	// nettoyer l'ancien fichier si necessaire
	if (isset($champs['fichier']) // un plugin a pu interdire la modif du fichier en virant le champ
		and $champs['fichier']
		and $ancien_fichier // on avait bien note le nom du fichier avant la modif
		and $ancien_fichier !== $champs['fichier'] // et il a ete modifie
		and !tester_url_absolue($ancien_fichier)
		and @file_exists($f = get_spip_doc($ancien_fichier))
	if (
		isset($champs['fichier'])
		&& $champs['fichier']
		&& $ancien_fichier
		&& $ancien_fichier !== $champs['fichier']
		&& !tester_url_absolue($ancien_fichier)
		&& @file_exists($f = get_spip_doc($ancien_fichier))
	) {
		spip_unlink($f);
	}

	// Changer le statut du document ?
	// le statut n'est jamais fixe manuellement mais decoule de celui des objets lies
	$champs = collecter_requests(array('parents', 'ajouts_parents'), array(), $set);
	$champs = collecter_requests(['parents', 'ajouts_parents'], [], $set);
	if (document_instituer($id_document, $champs)) {
		//
		// Post-modifications
@@ -161,11 +157,10 @@ function document_modifier($id_document, $set = null) {

		// Invalider les caches
		include_spip('inc/invalideur');
		suivre_invalideur("id='id_document/$id_document'");
		suivre_invalideur("id='document/$id_document'");
	}
}


/**
 * determiner le statut d'un document : prepa/publie
 * si on trouve un element joint sans champ statut ou avec un statut='publie' alors le doc est publie aussi
@@ -174,10 +169,10 @@ function document_modifier($id_document, $set = null) {
 * @param array $champs
 * @return bool
 */
function document_instituer($id_document, $champs = array()) {
function document_instituer($id_document, $champs = []) {

	$statut = isset($champs['statut']) ? $champs['statut'] : null;
	$date_publication = isset($champs['date_publication']) ? $champs['date_publication'] : null;
	$statut = $champs['statut'] ?? null;
	$date_publication = $champs['date_publication'] ?? null;
	if (isset($champs['parents'])) {
		medias_revision_document_parents($id_document, $champs['parents']);
	}
@@ -189,10 +184,10 @@ function document_instituer($id_document, $champs = array()) {
	$statut_ancien = $row['statut'];
	$date_publication_ancienne = $row['date_publication'];

	$champs = array();
	$champs = [];

	/* Autodetermination du statut si non fourni */
	if (is_null($statut)) {
	if ($statut === null) {
		$determiner_statut_document = charger_fonction('determiner_statut_document', 'inc');
		$champs = $determiner_statut_document($id_document, $statut_ancien, $date_publication_ancienne);

@@ -200,35 +195,34 @@ function document_instituer($id_document, $champs = array()) {
		if ($champs === false) {
			return false;
		}

	}
	else {
	} else {
		if ($statut !== $statut_ancien) {
			$champs['statut'] = $statut;
		}
	}

	if (!is_null($date_publication)
		and empty($champs['date_publication'])
		and $date_publication != $date_publication_ancienne) {
	if (
		$date_publication !== null && empty($champs['date_publication']) && $date_publication != $date_publication_ancienne
	) {
		$champs['date_publication'] = $date_publication;
	}

	// Envoyer aux plugins
	$champs = pipeline('pre_edition',
		array(
			'args' => array(
	$champs = pipeline(
		'pre_edition',
		[
			'args' => [
				'table' => 'spip_documents',
				'id_objet' => $id_document,
				'action' => 'instituer',
				'statut_ancien' => $statut_ancien,
				'date_ancienne' => $date_publication_ancienne,
			),
			'data' => $champs
		)
			],
			'data' => $champs,
		]
	);

	if (!count($champs)) {
	if (!(is_countable($champs) ? count($champs) : 0)) {
		return false;
	}

@@ -239,10 +233,10 @@ function document_instituer($id_document, $champs = array()) {
			'spip_documents_liens',
			"objet='rubrique' AND id_document=" . intval($id_document)
		);
		if (count($publier_rubriques)) {
		if (is_countable($publier_rubriques) ? count($publier_rubriques) : 0) {
			include_spip('inc/rubriques');
			foreach ($publier_rubriques as $r) {
				calculer_rubriques_if($r['id_objet'], array('statut' => $champs['statut']), $statut_ancien, false);
				calculer_rubriques_if($r['id_objet'], ['statut' => $champs['statut']], $statut_ancien, false);
			}
		}
	}
@@ -251,23 +245,23 @@ function document_instituer($id_document, $champs = array()) {
	include_spip('inc/invalideur');
	suivre_invalideur("id='document/$id_document'");

	pipeline('post_edition',
		array(
			'args' => array(
	pipeline(
		'post_edition',
		[
			'args' => [
				'table' => 'spip_documents',
				'id_objet' => $id_document,
				'action' => 'instituer',
				'statut_ancien' => $statut_ancien,
				'date_ancienne' => $date_publication_ancienne,
			),
			'data' => $champs
		)
			],
			'data' => $champs,
		]
	);

	return true;
}


/**
 * Revision des parents d'un document
 * chaque parent est liste au format objet|id_objet
@@ -283,14 +277,18 @@ function medias_revision_document_parents($id_document, $parents = null, $ajout
		return;
	}

	$insertions = array();
	$objets_parents = array(); // array('article'=>array(12,23))
	$insertions = [];
	$objets_parents = []; // array('article'=>array(12,23))

	// au format objet|id_objet
	foreach ($parents as $p) {
		$p = explode('|', $p);
		if (preg_match('/^[a-z0-9_]+$/i', $objet = $p[0])
			and (($p[1] = intval($p[1])) or in_array($objet, ['site', 'rubrique']))
		$p = explode('|', (string) $p);
		if (
			preg_match('/^[a-z0-9_]+$/i', $objet = $p[0])
			&& (
				($p[1] = intval($p[1]))
				|| in_array($objet, ['site', 'rubrique'])
			)
		) { // securite
			$objets_parents[$p[0]][] = $p[1];
		}
@@ -298,14 +296,14 @@ function medias_revision_document_parents($id_document, $parents = null, $ajout

	include_spip('action/editer_liens');
	// les liens actuels
	$liens = objet_trouver_liens(array('document' => $id_document), '*');
	$deja_parents = array();
	$liens = objet_trouver_liens(['document' => $id_document], '*');
	$deja_parents = [];
	// si ce n'est pas un ajout, il faut supprimer les liens actuels qui ne sont pas dans $objets_parents
	if (!$ajout) {
		foreach ($liens as $k => $lien) {
			if (!isset($objets_parents[$lien['objet']]) or !in_array($lien['id_objet'], $objets_parents[$lien['objet']])) {
			if (!isset($objets_parents[$lien['objet']]) || !in_array($lien['id_objet'], $objets_parents[$lien['objet']])) {
				if (autoriser('dissocierdocuments', $lien['objet'], $lien['id_objet'])) {
					objet_dissocier(array('document' => $id_document), array($lien['objet'] => $lien['id_objet']));
					objet_dissocier(['document' => $id_document], [$lien['objet'] => $lien['id_objet']]);
				}
				unset($liens[$k]);
			} else {
@@ -317,15 +315,12 @@ function medias_revision_document_parents($id_document, $parents = null, $ajout
	// trier les objets à traiter : ne pas prendre en compte ceux qui sont déjà associés ou qu'on n'a pas le droit d'associer
	foreach ($objets_parents as $objet => $ids) {
		foreach ($ids as $k => $id) {
			if ((
					isset($deja_parents[$objet])
					and in_array($id, $deja_parents[$objet])
				)
				or !autoriser('associerdocuments', $objet, $id)
			if (
				isset($deja_parents[$objet]) && in_array($id, $deja_parents[$objet]) || !autoriser('associerdocuments', $objet, $id)
			) {
				unset($objets_parents[$objet][$k]);
			}
		}
	}
	objet_associer(array('document' => $id_document), $objets_parents);
	objet_associer(['document' => $id_document], $objets_parents);
}

action/editer_logo.php

0 → 100644
+316 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.
 */

/**
 * Gestion de l'API de modification/suppression des logos
 *
 * @package SPIP\Core\Logo\Edition
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

/**
 * Supprimer le logo d'un objet
 *
 * @param string $objet
 * @param int $id_objet
 * @param string $etat
 *     `on` ou `off`
 */
function logo_supprimer($objet, $id_objet, $etat) {
	$chercher_logo = charger_fonction('chercher_logo', 'inc');
	$objet = objet_type($objet);
	$primary = id_table_objet($objet);
	include_spip('inc/chercher_logo');

	// 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_logger('logo')->info('Supprimer ancien logo ' . json_encode($logo, JSON_THROW_ON_ERROR));
			spip_unlink($logo[0]);
		} elseif (
			($doc = $logo[5])
			&& isset($doc['id_document'])
			&& ($id_document = $doc['id_document'])
		) {
			include_spip('action/editer_liens');
			// supprimer le lien dans la base
			objet_dissocier(['document' => $id_document], [$objet => $id_objet], ['role' => '*']);

			// verifier si il reste des liens avec d'autres objets et sinon supprimer
			$liens = objet_trouver_liens(['document' => $id_document], '*');
			if ($liens === []) {
				$supprimer_document = charger_fonction('supprimer_document', 'action');
				$supprimer_document($doc['id_document']);
			}
		}
	}
}

/**
 * Modifier le logo d'un objet
 *
 * @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');

	$mode = preg_replace(',\W,', '', $etat);
	if (!$mode) {
		spip_logger('logo')->info("logo_modifier : etat $etat invalide");

		return 'etat invalide';
	}
	// chercher dans la base
	$mode_document = 'logo' . $mode;

	include_spip('inc/documents');
	$erreur = '';

	if (!$source) {
		spip_logger('logo')->info('spip_image_ajouter : source inconnue');

		return 'source inconnue';
	}

	// fichier dans upload/
	if (is_string($source)) {
		$tmp_name = false;
		if (file_exists($source)) {
			$tmp_name = $source;
		} elseif (file_exists($f = determine_upload() . $source)) {
			$tmp_name = $f;
		}
		if (!$tmp_name) {
			spip_logger('logo')->info('spip_image_ajouter : source inconnue');

			return 'source inconnue';
		}
		$source = [
			'tmp_name' => $tmp_name,
			'name' => basename($tmp_name),
		];
	} elseif ($erreur = check_upload_error($source['error'], '', true)) {
		return $erreur;
	}

	// supprimer le logo éventuel existant
	// TODO : si un logo existe, le modifier plutot que supprimer + reinserer
	// (mais il faut gerer le cas ou il est utilise par plusieurs objets, donc pas si simple)
	// mais de toute facon l'interface actuelle oblige a supprimer + reinserer
	// @see medias_upgrade_logo_objet()
	if (empty($GLOBALS['logo_migrer_en_base'])) {
		logo_supprimer($objet, $id_objet, $etat);
	}

	include_spip('inc/autoriser');
	$source['mode'] = $mode_document;
	$ajouter_documents = charger_fonction('ajouter_documents', 'action');
	autoriser_exception('associerdocuments', $objet, $id_objet);
	$ajoutes = $ajouter_documents('new', [$source], $objet, $id_objet, $mode_document);
	autoriser_exception('associerdocuments', $objet, $id_objet, false);

	$id_document = reset($ajoutes);

	if (!is_numeric($id_document)) {
		$erreur = ($id_document ?: 'Erreur inconnue');
		spip_logger('logo')
			->info("Erreur ajout logo : $erreur pour source=" . json_encode($source, JSON_THROW_ON_ERROR));
		return $erreur;
	}

	return ''; // tout est bon, pas d'erreur
}

/**
 * Migration des logos en documents.
 *
 * - avant dans IMG/artonXX.png
 * - après dans IMG/logo/... + enregistrés en document dans spip_documents
 *
 * Cette migration est effectuée à partir de SPIP 4.0
 * et la fonction doit être appelée pour chaque plugin qui aurait utilisé des logos
 * sur des objets éditoriaux.
 *
 * @since 4.0
 * @deprecated 5.0 Migrer le site & les logos / tables dans un SPIP 4.x ou 5.x
 * @param string $objet Type d’objet spip, tel que 'article'
 * @param int $time_limit
 */
function logo_migrer_en_base($objet, $time_limit) {

	$dir_logos_erreurs = sous_repertoire(_DIR_IMG, 'logo_erreurs');
	$dir_logos = sous_repertoire(_DIR_IMG, 'logo');
	include_spip('inc/filtres_images_lib_mini');
	$formats_logos = _image_extensions_logos(['objet' => $objet]);

	$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((string) $file)) . DIRECTORY_SEPARATOR . basename((string) $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 ($restant !== []) {
						foreach ($restant as $r) {
							$files[] = $filescheck[$r];
						}
					}
				}
				// 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;
				}
			}
		}

		$count = (is_countable($files) ? count($files) : 0);
		spip_logger('maj')
			->notice("logo_migrer_en_base $objet $mode : " . $count . ' logos restant');

		$deja = [];
		foreach ($files as $file) {
			$logo = substr((string) $file, strlen($dir . $nom_base));
			$logo = explode('.', $logo);
			if (
				is_numeric($logo[0])
				&& (($id_objet = (int) $logo[0]) || in_array($objet, ['site', 'rubrique']))
				&& !isset($deja[$id_objet])
			) {
				$logo = $chercher_logo($id_objet, $_id_objet, $mode);
				// if no logo in base
				if (!$logo || (is_countable($logo) ? count($logo) : 0) < 6) {
					foreach ($formats_logos as $format) {
						if (@file_exists($d = ($dir . ($nom = $nom_base . (int) $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 && file_exists($file)) {
				@rename($file, $dir_logos_erreurs . basename((string) $file));
			}

			$count--;
			if ($count % 250 === 0) {
				spip_logger('maj')->notice("logo_migrer_en_base $objet $mode : " . $count . ' logos restant');
			}

			if ($time_limit && time() > $time_limit) {
				effacer_meta('drapeau_edition');
				return;
			}
		}
	}

	if ($liste_objets_versionnes) {
		$GLOBALS['meta']['objets_versions'] = $liste_objets_versionnes;
	}
	$GLOBALS['meta']['articles_modif'] = $articles_modif;

	effacer_meta('drapeau_edition');
}

/**
 * Retourne le type de logo tel que `art` depuis le nom de clé primaire
 * de l'objet
 *
 * C'est par défaut le type d'objet, mais il existe des exceptions historiques
 * déclarées par la globale `$table_logos`
 *
 * @see logo_migrer_en_base()
 * @see medias_upgrade_logo_objet()
 *
 * @param string $_id_objet
 *     Nom de la clé primaire de l'objet
 * @return string
 *     Type du logo
 * @deprecated 4.0 MAIS NE PAS SUPPRIMER CAR SERT POUR L'UPGRADE des logos et leur mise en base
 */
function type_du_logo($_id_objet) {
	if ((debug_backtrace(0, 2)[1]['function'] ?? '') !== 'logo_migrer_en_base') {
		trigger_deprecation('spip', '4.0', 'Using "%s" is deprecated', __FUNCTION__);
	}
	$legacy_tables_logos = [
		'id_article' => 'art',
		'id_auteur' => 'aut',
		'id_rubrique' => 'rub',
		'id_groupe' => 'groupe',
	];
	return $legacy_tables_logos[$_id_objet] ?? objet_type(preg_replace(',^id_,', '', $_id_objet));
}
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -18,7 +18,6 @@ function action_ordonner_liens_documents_dist() {
	action_ordonner_liens_dist();
}


function action_ordonner_liens_dist() {
	include_spip('inc/autoriser');
	include_spip('base/objets');
@@ -34,7 +33,7 @@ function action_ordonner_liens_dist() {
	// ordre des éléments
	$ordre = _request('ordre');

	if (!$objet or !$objet_lie or !$id_objet_lie or !$ordre or !is_array($ordre) or !objet_associable($objet)) {
	if (!$objet || !$objet_lie || !$id_objet_lie || !$ordre || !is_array($ordre) || !objet_associable($objet)) {
		return envoyer_json_erreur(_T('medias:erreur_objet_absent') . ' ' . _T('medias:erreur_deplacement_impossible'));
	}

@@ -42,25 +41,23 @@ function action_ordonner_liens_dist() {
		return envoyer_json_erreur(_T('medias:erreur_autorisation') . ' ' . _T('medias:erreur_deplacement_impossible'));
	}

	list($_id_objet, $table_liens) = objet_associable($objet);
	[$_id_objet, $table_liens] = objet_associable($objet);

	$success = $errors = array();
	$success = $errors = [];

	$actuels = sql_allfetsel(
		array($_id_objet . ' AS id', 'rang_lien'),
		[$_id_objet . ' AS id', 'rang_lien'],
		$table_liens,
		array(
			sql_in($_id_objet, $ordre),
			'objet = ' . sql_quote($objet_lie),
			'id_objet = ' . sql_quote($id_objet_lie)
		)
		[sql_in($_id_objet, $ordre), 'objet = ' . sql_quote($objet_lie), 'id_objet = ' . sql_quote($id_objet_lie)]
	);

	$futurs = array_flip($ordre);
	// ordre de 1 à n (pas de 0 à n).
	array_walk($futurs, function(&$v) { $v++; });
	array_walk($futurs, function (&$v) {
		$v++;
	});

	$updates = array();
	$updates = [];

	foreach ($actuels as $l) {
		if ($futurs[$l['id']] !== $l['rang_lien']) {
@@ -72,32 +69,28 @@ function action_ordonner_liens_dist() {
		foreach ($updates as $id => $ordre) {
			sql_updateq(
				$table_liens,
				array('rang_lien' => $ordre),
				array(
					$_id_objet . ' = ' . $id,
					'objet = ' . sql_quote($objet_lie),
					'id_objet = ' . sql_quote($id_objet_lie)
				)
				['rang_lien' => $ordre],
				[$_id_objet . ' = ' . $id, 'objet = ' . sql_quote($objet_lie), 'id_objet = ' . sql_quote($id_objet_lie)]
			);
		}
	}

	return envoyer_json_envoi(array(
	return envoyer_json_envoi([
		'done' => true,
		'success' => $success,
		'errors' => $errors,
	));
	]);
}

function envoyer_json_envoi($data) {
	header('Content-Type: application/json; charset=' . $GLOBALS['meta']['charset']);
	echo json_encode($data);
	echo json_encode($data, JSON_THROW_ON_ERROR);
}

function envoyer_json_erreur($msg) {
	return envoyer_json_envoi(array(
	return envoyer_json_envoi([
		'done' => false,
		'success' => array(),
		'errors' => array($msg)
	));
		'success' => [],
		'errors' => [$msg],
	]);
}
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

// https://code.spip.net/@supprimer_document
function action_supprimer_document_dist($id_document = 0) {
	if (!$id_document) {
		$securiser_action = charger_fonction('securiser_action', 'inc');
@@ -30,7 +28,7 @@ function action_supprimer_document_dist($id_document = 0) {
	// si c'etait une vignette, modifier le document source !
	if ($source = sql_getfetsel('id_document', 'spip_documents', 'id_vignette=' . intval($id_document))) {
		include_spip('action/editer_document');
		document_modifier($source, array('id_vignette' => 0));
		document_modifier($source, ['id_vignette' => 0]);
	}

	include_spip('inc/documents');
@@ -46,7 +44,7 @@ function action_supprimer_document_dist($id_document = 0) {
	// Si c'est un document ayant une vignette, supprimer aussi la vignette
	if ($doc['id_vignette']) {
		action_supprimer_document_dist($doc['id_vignette']);
		objet_dissocier(array('document' => $doc['id_vignette']), '*');
		objet_dissocier(['document' => $doc['id_vignette']], '*');
	}
	// Si c'est un document ayant des documents annexes (sous-titre, ...)
	// les supprimer aussi
@@ -59,10 +57,9 @@ function action_supprimer_document_dist($id_document = 0) {
	}

	// dereferencer dans la base
	objet_dissocier(array('document' => $id_document), '*', array('role' => '*'));
	objet_dissocier(['document' => $id_document], '*', ['role' => '*']);
	sql_delete('spip_documents', 'id_document=' . intval($id_document));


	// Supprimer le fichier si le doc est local,
	// et la copie locale si le doc est distant
	if ($doc['distant'] == 'oui') {
@@ -76,16 +73,16 @@ function action_supprimer_document_dist($id_document = 0) {

	pipeline(
		'post_edition',
		array(
			'args' => array(
		[
			'args' => [
				'operation' => 'supprimer_document', // compat v<=2
				'action' => 'supprimer_document',
				'table' => 'spip_documents',
				'id_objet' => $id_document,
				'document' => $doc,
			),
			'data' => null
		)
			],
			'data' => null,
		]
	);

	return true;
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
@@ -22,9 +21,9 @@ function action_supprimer_tous_orphelins() {
	$arg = $securiser_action();

	//on recupere le contexte pour ne supprimer les orphelins que de ce dernier
	list($media, $distant, $statut, $sanstitre) = explode('/', $arg);
	[$media, $distant, $statut, $sanstitre] = explode('/', (string) $arg);

	$where = array();
	$where = [];
	//critere sur le media
	if ($media) {
		$select = 'media=' . sql_quote($media);
+27 −59
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
@@ -17,29 +16,26 @@ if (!defined('_ECRIRE_INC_VERSION')) {
/**
 * Tourner un document
 *
 * https://code.spip.net/@action_tourner_dist
 *
 * lorsque les arguments sont passes dans arg en GET :
 * id_document-angle
 *
 * @param int $id_document
 * @param int $angle
 *   angle de rotation en degre>0
 * @return void
 */
function action_tourner_dist($id_document = null, $angle = null) {
	if (is_null($id_document) or is_null($angle)) {
	if ($id_document === null || $angle === null) {
		$securiser_action = charger_fonction('securiser_action', 'inc');
		$arg = $securiser_action();

		if (!preg_match(',^\W*(\d+)\W?(-?\d+)$,', $arg, $r)) {
		if (!preg_match(',^\W*(\d+)\W?(-?\d+)$,', (string) $arg, $r)) {
			spip_log("action_tourner_dist $arg pas compris");
		} else {
			array_shift($r);
			list($id_document, $angle) = $r;
			[$id_document, $angle] = $r;
		}
	}
	if ($id_document and autoriser('modifier', 'document', $id_document)) {
	if ($id_document && autoriser('modifier', 'document', $id_document)) {
		action_tourner_post($id_document, $angle);
	}
}
@@ -47,12 +43,9 @@ function action_tourner_dist($id_document = null, $angle = null) {
/**
 * Tourner un document
 *
 * https://code.spip.net/@action_tourner_post
 *
 * @param int $id_document
 * @param int $angle
 *   angle de rotation en degre>0
 * @return
 */
function action_tourner_post($id_document, $angle) {
	$row = sql_fetsel('fichier,extension', 'spip_documents', 'id_document=' . intval($id_document));
@@ -90,7 +83,7 @@ function action_tourner_post($id_document, $angle) {
			$res = filtrer('image_format', $res, $row['extension']);
		}

		list($hauteur, $largeur) = taille_image($res);
		[$hauteur, $largeur] = taille_image($res);
		$res = extraire_attribut($res, 'src');

		include_spip('inc/getdocument');
@@ -103,13 +96,13 @@ function action_tourner_post($id_document, $angle) {
	}

	// succes !
	if ($largeur > 0 and $hauteur > 0) {
		$set = array(
	if ($largeur > 0 && $hauteur > 0) {
		$set = [
			'fichier' => set_spip_doc($dest),
			'largeur' => $largeur,
			'hauteur' => $hauteur,
			'distant' => 'non' // le document n'est plus distant apres une transformation
		);
			'distant' => 'non', // le document n'est plus distant apres une transformation
		];
		if ($taille = @filesize($dest)) {
			$set['taille'] = $taille;
		}
@@ -121,47 +114,22 @@ function action_tourner_post($id_document, $angle) {
		// pipeline pour les plugins
		pipeline(
			'post_edition',
			array(
				'args' => array(
			[
				'args' => [
					'table' => 'spip_documents',
					'table_objet' => 'documents',
					'spip_table_objet' => 'spip_documents',
					'type' => 'document',
					'id_objet' => $id_document,
					'champs' => array('rotation' => $angle, 'orientation' => $var_rot, 'fichier' => $row['fichier']),
					'champs' => [
						'rotation' => $angle,
						'orientation' => $var_rot,
						'fichier' => $row['fichier'],
					],
					'action' => 'tourner',
				),
				'data' => $set
			)
				],
				'data' => $set,
			]
		);
	}
}

// Appliquer l'EXIF orientation
// cf. http://trac.rezo.net/trac/spip/ticket/1494
// https://code.spip.net/@tourner_selon_exif_orientation
function tourner_selon_exif_orientation($id_document, $fichier) {

	if (function_exists('exif_read_data')
		and $exif = exif_read_data($fichier)
		and (
			$ort = $exif['IFD0']['Orientation']
			or $ort = $exif['Orientation'])
	) {
		spip_log("rotation: $ort");
		$rot = null;
		switch ($ort) {
			case 3:
				$rot = 180;
				// rotation à 180
			case 6:
				$rot = 90;
				// rotation à 90
			case 8:
				$rot = -90;
		}
		if ($rot) {
			action_tourner_post(array(null, $id_document, $rot));
		}
	}
}
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
@@ -16,7 +15,6 @@ if (!defined('_ECRIRE_INC_VERSION')) {

/**
 * Verifier tous les fichiers brises
 *
 */
function action_verifier_documents_brises_dist() {

@@ -29,7 +27,7 @@ function action_verifier_documents_brises_dist() {
		$res = sql_select('fichier,brise,id_document', 'spip_documents', "distant='non'");
		while ($row = sql_fetch($res)) {
			if (($brise = !@file_exists(get_spip_doc($row['fichier']))) != $row['brise']) {
				sql_updateq('spip_documents', array('brise' => $brise), 'id_document=' . intval($row['id_document']));
				sql_updateq('spip_documents', ['brise' => $brise], 'id_document=' . intval($row['id_document']));
			}
		}
	}
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

/**
 * Gestion de l'action verifier_documents_liens
 *
 * @package SPIP\Medias\Action
 **/

 */
if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}
@@ -29,12 +27,12 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 */
function action_verifier_documents_liens_dist($id_document = null) {

	if (is_null($id_document)) {
	if ($id_document === null) {
		$securiser_action = charger_fonction('securiser_action', 'inc');
		$id_document = $securiser_action();
	}

	$id_document = ($id_document == '*') ? '*' : intval($id_document);
	include_spip('action/editer_liens');
	objet_optimiser_liens(array('document' => $id_document), '*');
	objet_optimiser_liens(['document' => $id_document], '*');
}

balise/id_logo_.php

0 → 100644
+133 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.
 */

/**
 * Fonctions génériques pour les balises `#LOGO_XXXX`
 *
 * @package SPIP\Core\Compilateur\Balises
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

/**
 * Compile la balise dynamique `#ID_LOGO_xx` qui retourne l'identifiant du document utilisé comme logo
 * pour un objet éditorial de SPIP.
 *
 * Le type d'objet est récupéré dans le nom de la balise, tel que
 * `ID_LOGO_ARTICLE` ou `ID_LOGO_SITE`.
 *
 * Ces balises ont quelques options :
 *
 * - La balise peut aussi demander explicitement le logo normal ou de survol,
 *   avec `ID_LOGO_ARTICLE_NORMAL` ou `ID_LOGO_ARTICLE_SURVOL`.
 * - On peut demander un logo de rubrique en absence de logo sur l'objet éditorial
 *   demandé avec `ID_LOGO_ARTICLE_RUBRIQUE`
 *
 * @balise
 * @uses generer_code_logo()
 * @example
 *     ```
 *     #ID_LOGO_ARTICLE
 *     ```
 *
 * @param Spip\Compilateur\Noeud\Champ $p
 *     Pile au niveau de la balise
 * @return Spip\Compilateur\Noeud\Champ
 *     Pile complétée par le code à générer
 */
function balise_ID_LOGO__dist($p) {

	preg_match(',^ID_LOGO_([A-Z_]+?)(|_NORMAL|_SURVOL|_RUBRIQUE)$,i', $p->nom_champ, $regs);
	$type = strtolower($regs[1]);
	$suite_logo = $regs[2];

	// cas de #ID_LOGO_SITE_SPIP
	if ($type == 'site_spip') {
		$type = 'site';
		$_id_objet = "\"'0'\"";
	}

	$id_objet = id_table_objet($type);
	if (!isset($_id_objet)) {
		$_id_objet = champ_sql($id_objet, $p);
	}

	$connect = $p->id_boucle ? $p->boucles[$p->id_boucle]->sql_serveur : '';
	if ($type == 'document') {
		$qconnect = _q($connect);
		$doc = "quete_document($_id_objet, $qconnect)";
		$code = "table_valeur($doc, 'id_vignette')";
	} elseif ($connect) {
		$code = "''";
		spip_logger()
			->info('Les logos distants ne sont pas prevus');
	} else {
		$champ_logo = 'id';
		$code = generer_code_logo($id_objet, $_id_objet, $type, '', "''", $p, $suite_logo, $champ_logo);
	}

	$p->code = $code;
	$p->interdire_scripts = false;

	return $p;
}

/**
 * Calcule le code HTML pour l'image ou l'information sur un logo
 *
 * @uses quete_logo()
 * @uses quete_html_logo()
 *
 * @param string $id_objet
 *     Nom de la clé primaire de l'objet (id_article, ...)
 * @param string $_id_objet
 *     Code pour la compilation permettant de récupérer la valeur de l'identifiant
 * @param string $type
 *     Type d'objet
 * @param string $align
 *     Alignement demandé du logo
 * @param Spip\Compilateur\Noeud\Champ $p
 *     Pile au niveau de la balise
 * @param string $suite
 *     Suite éventuelle de la balise logo, telle que `_SURVOL`, `_NORMAL` ou `_RUBRIQUE`.
 * @param string $champ
 *     Indique un type de champ à retourner (fichier, src, titre, descriptif, credits, id, alt)
 * @return string
 *     Code compilé retournant le chemin du logo ou le code HTML du logo.
 */
function generer_code_logo($id_objet, $_id_objet, $type, $align, $_lien, $p, $suite, string $champ = ''): string {
	$onoff = 'ON';
	$_id_rubrique = "''";

	if ($type === 'rubrique') {
		$_id_rubrique = "quete_parent($_id_objet)";
	}

	if ($suite === '_SURVOL') {
		$onoff = 'off';
	} elseif ($suite === '_NORMAL') {
		$onoff = 'on';
	} elseif ($suite === '_RUBRIQUE') {
		$_id_rubrique = champ_sql('id_rubrique', $p);
	}

	$code = "quete_logo('$id_objet', '$onoff', $_id_objet, $_id_rubrique)";

	if ($champ) {
		return "table_valeur($code, '" . addslashes($champ) . "')";
	}

	$align = preg_replace(',\W,', '', $align);

	return "quete_html_logo($code, '$align', " . ($_lien ?: "''") . ')';
}

balise/logo_.php

0 → 100644
+142 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.
 */

/**
 * Fonctions génériques pour les balises `#LOGO_XXXX`
 *
 * @package SPIP\Core\Compilateur\Balises
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

/**
 * Compile la balise dynamique `#LOGO_xx` qui retourne le code HTML
 * pour afficher l'image de logo d'un objet éditorial de SPIP.
 *
 * Le type d'objet est récupéré dans le nom de la balise, tel que
 * `LOGO_ARTICLE` ou `LOGO_SITE`.
 *
 * Ces balises ont quelques options :
 *
 * - La balise peut aussi demander explicitement le logo normal ou de survol,
 *   avec `LOGO_ARTICLE_NORMAL` ou `LOGO_ARTICLE_SURVOL`.
 * - On peut demander un logo de rubrique en absence de logo sur l'objet éditorial
 *   demandé avec `LOGO_ARTICLE_RUBRIQUE`
 * - `LOGO_ARTICLE*` ajoute un lien sur l'image du logo vers l'objet éditorial
 * - `LOGO_ARTICLE**` retourne le nom du fichier de logo.
 * - `LOGO_ARTICLE{right}`. Valeurs possibles : top left right center bottom
 * - `LOGO_DOCUMENT{icone}`. Valeurs possibles : auto icone apercu vignette
 * - `LOGO_ARTICLE{200, 0}`. Redimensionnement indiqué
 *
 * Pour récupérer l’identifiant du document sous-jacent voir la balise `ID_LOGO_...`
 *
 * @balise
 * @uses generer_code_logo()
 * @example
 *     ```
 *     #LOGO_ARTICLE
 *     ```
 *
 * @param Spip\Compilateur\Noeud\Champ $p
 *     Pile au niveau de la balise
 * @return Spip\Compilateur\Noeud\Champ
 *     Pile complétée par le code à générer
 */
function balise_LOGO__dist($p) {

	preg_match(',^LOGO_([A-Z_]+?)(|_NORMAL|_SURVOL|_RUBRIQUE)$,i', $p->nom_champ, $regs);
	$type = strtolower($regs[1]);
	$suite_logo = $regs[2];

	// cas de #LOGO_SITE_SPIP
	if ($type == 'site_spip') {
		$type = 'site';
		$_id_objet = "\"'0'\"";
	}

	$id_objet = id_table_objet($type);
	if (!isset($_id_objet)) {
		$_id_objet = champ_sql($id_objet, $p);
	}

	$fichier = ($p->etoile === '**') ? -1 : 0;
	$coord = [];
	$align = $lien = '';
	$mode_logo = '';

	if ($p->param && !$p->param[0][0]) {
		$params = $p->param[0];
		array_shift($params);
		foreach ($params as $a) {
			if ($a[0]->type === 'texte') {
				$n = $a[0]->texte;
				if (is_numeric($n)) {
					$coord[] = $n;
				} elseif (in_array($n, ['top', 'left', 'right', 'center', 'bottom'])) {
					$align = $n;
				} elseif (in_array($n, ['auto', 'icone', 'apercu', 'vignette'])) {
					$mode_logo = $n;
				}
			} else {
				$lien = calculer_liste($a, $p->descr, $p->boucles, $p->id_boucle);
			}
		}
	}

	$coord_x = $coord ? (int) array_shift($coord) : 0;
	$coord_y = $coord ? (int) array_shift($coord) : 0;

	if ($p->etoile === '*') {
		include_spip('balise/url_');
		$lien = generer_generer_url_arg($type, $p, $_id_objet);
	}

	$connect = $p->id_boucle ? $p->boucles[$p->id_boucle]->sql_serveur : '';
	if ($type == 'document') {
		$qconnect = _q($connect);
		$doc = "quete_document($_id_objet, $qconnect)";
		if ($fichier) {
			$code = "quete_logo_file($doc, $qconnect)";
		} else {
			$code = "quete_logo_document($doc, " . ($lien ?: "''") . ", '$align', '$mode_logo', $coord_x, $coord_y, $qconnect)";
		}
		// (x=non-faux ? y : '') pour affecter x en retournant y
		if ($p->descr['documents']) {
			$code = '(($doublons["documents"] .= ",". '
				. $_id_objet
				. ") ? $code : '')";
		}
	} elseif ($connect) {
		$code = "''";
		spip_logger()
			->info('Les logos distants ne sont pas prevus');
	} else {
		// pour generer_code_logo
		include_spip('balise/id_logo_');
		$champ_logo = '';
		if ($fichier) {
			$champ_logo = 'fichier';
		}
		$code = generer_code_logo($id_objet, $_id_objet, $type, $align, $lien, $p, $suite_logo, $champ_logo);
	}

	// demande de reduction sur logo avec ecriture spip 2.1 : #LOGO_xxx{200, 0}
	if ($coord_x || $coord_y) {
		$code = "filtrer('image_graver',filtrer('image_reduire'," . $code . ", '$coord_x', '$coord_y'))";
	}

	$p->code = $code;
	$p->interdire_scripts = false;

	return $p;
}
+94 −85
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

/**
 * Déclarations relatives à la base de données
 *
 * @package SPIP\Medias\Pipelines
 **/

 */
if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}
@@ -30,21 +28,20 @@ function medias_declarer_tables_interfaces($interfaces) {
	$interfaces['table_des_tables']['documents'] = 'documents';
	$interfaces['table_des_tables']['types_documents'] = 'types_documents';

	$interfaces['exceptions_des_tables']['documents']['type_document'] = array('types_documents', 'titre');
	$interfaces['exceptions_des_tables']['documents']['extension_document'] = array('types_documents', 'extension');
	$interfaces['exceptions_des_tables']['documents']['mime_type'] = array('types_documents', 'mime_type');
	$interfaces['exceptions_des_tables']['documents']['media_document'] = array('types_documents', 'media');
	$interfaces['exceptions_des_tables']['documents']['type_document'] = ['types_documents', 'titre'];
	$interfaces['exceptions_des_tables']['documents']['extension_document'] = ['types_documents', 'extension'];
	$interfaces['exceptions_des_tables']['documents']['mime_type_extension'] = ['types_documents', 'mime_type'];
	$interfaces['exceptions_des_tables']['documents']['media_document'] = ['types_documents', 'media_defaut'];

	$interfaces['exceptions_des_jointures']['spip_documents']['id_forum'] = array('spip_documents_liens', 'id_forum');
	$interfaces['exceptions_des_jointures']['spip_documents']['vu'] = array('spip_documents_liens', 'vu');
	$interfaces['exceptions_des_jointures']['spip_documents']['id_forum'] = ['spip_documents_liens', 'id_forum'];
	$interfaces['exceptions_des_jointures']['spip_documents']['vu'] = ['spip_documents_liens', 'vu'];
	$interfaces['table_date']['types_documents'] = 'date';

	$interfaces['table_des_traitements']['FICHIER'][] = 'get_spip_doc(%s)';

	$interfaces['table_des_traitements']['CREDITS']['documents'] = _TRAITEMENT_TYPO;
	return $interfaces;
}


/**
 * Table principale spip_documents et spip_types_documents
 *
@@ -53,7 +50,7 @@ function medias_declarer_tables_interfaces($interfaces) {
 */
function medias_declarer_tables_principales($tables_principales) {

	$spip_types_documents = array(
	$spip_types_documents = [
		'extension' => "varchar(10) DEFAULT '' NOT NULL",
		'titre' => "text DEFAULT '' NOT NULL",
		'descriptif' => "text DEFAULT '' NOT NULL",
@@ -61,16 +58,16 @@ function medias_declarer_tables_principales($tables_principales) {
		'inclus' => "ENUM('non', 'image', 'embed') DEFAULT 'non'  NOT NULL",
		'upload' => "ENUM('oui', 'non') DEFAULT 'oui'  NOT NULL",
		'media_defaut' => "varchar(10) DEFAULT 'file' NOT NULL",
		'maj' => 'TIMESTAMP'
	);
		'maj' => 'TIMESTAMP',
	];

	$spip_types_documents_key = array(
	$spip_types_documents_key = [
		'PRIMARY KEY' => 'extension',
		'KEY inclus' => 'inclus'
	);
		'KEY inclus' => 'inclus',
	];

	$tables_principales['spip_types_documents'] =
		array('field' => &$spip_types_documents, 'key' => &$spip_types_documents_key);
		['field' => &$spip_types_documents, 'key' => &$spip_types_documents_key];

	return $tables_principales;
}
@@ -83,25 +80,25 @@ function medias_declarer_tables_principales($tables_principales) {
 */
function medias_declarer_tables_auxiliaires($tables_auxiliaires) {

	$spip_documents_liens = array(
	$spip_documents_liens = [
		'id_document' => "bigint(21) DEFAULT '0' NOT NULL",
		'id_objet' => "bigint(21) DEFAULT '0' NOT NULL",
		'objet' => "VARCHAR (25) DEFAULT '' NOT NULL",
		'vu' => "ENUM('non', 'oui') DEFAULT 'non' NOT NULL",
		'rang_lien' => "int(4) DEFAULT '0' NOT NULL"
	);
		'rang_lien' => "int(4) DEFAULT '0' NOT NULL",
	];

	$spip_documents_liens_key = array(
	$spip_documents_liens_key = [
		'PRIMARY KEY' => 'id_document,id_objet,objet',
		'KEY id_document' => 'id_document',
		'KEY id_objet' => 'id_objet',
		'KEY objet' => 'objet',
	);
	];

	$tables_auxiliaires['spip_documents_liens'] = array(
	$tables_auxiliaires['spip_documents_liens'] = [
		'field' => &$spip_documents_liens,
		'key' => &$spip_documents_liens_key
	);
		'key' => &$spip_documents_liens_key,
	];

	return $tables_auxiliaires;
}
@@ -121,9 +118,9 @@ function medias_declarer_tables_objets_surnoms($surnoms) {

function medias_declarer_tables_objets_sql($tables) {
	$tables['spip_articles']['champs_versionnes'][] = 'jointure_documents';
	$tables['spip_documents'] = array(
		'table_objet_surnoms' => array('doc', 'img', 'emb'),
		'type_surnoms' => array(),
	$tables['spip_documents'] = [
		'table_objet_surnoms' => ['doc', 'img', 'emb'],
		'type_surnoms' => [],
		'url_voir' => 'document_edit',
		'url_edit' => 'document_edit',
		'page' => '',
@@ -137,7 +134,7 @@ function medias_declarer_tables_objets_sql($tables) {
		'titre' => "CASE WHEN length(titre)>0 THEN titre ELSE fichier END as titre, '' AS lang",
		'date' => 'date',
		'principale' => 'oui',
		'field' => array(
		'field' => [
			'id_document' => 'bigint(21) NOT NULL',
			'id_vignette' => "bigint(21) DEFAULT '0' NOT NULL",
			'extension' => "VARCHAR(10) DEFAULT '' NOT NULL",
@@ -157,35 +154,35 @@ function medias_declarer_tables_objets_sql($tables) {
			'alt' => "text DEFAULT '' NOT NULL",
			'date_publication' => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL",
			'brise' => 'tinyint DEFAULT 0',
			'maj' => 'TIMESTAMP'
		),
		'key' => array(
			'maj' => 'TIMESTAMP',
		],
		'key' => [
			'PRIMARY KEY' => 'id_document',
			'KEY id_vignette' => 'id_vignette',
			'KEY mode' => 'mode',
			'KEY extension' => 'extension'
		),
		'join' => array(
			'KEY extension' => 'extension',
		],
		'join' => [
			'id_document' => 'id_document',
			'extension' => 'extension'
		),
		'statut' => array(
			array(
			'extension' => 'extension',
		],
		'statut' => [
			[
				'champ' => 'statut',
				'publie' => 'publie',
				'previsu' => 'publie,prop,prepa',
				'post_date' => 'date_publication',
				'exception' => array('statut', 'tout')
			)
		),
		'tables_jointures' => array('types_documents'),
		'rechercher_champs' => array(
				'exception' => ['statut', 'tout'],
			],
		],
		'tables_jointures' => ['types_documents'],
		'rechercher_champs' => [
			'titre' => 3,
			'descriptif' => 1,
			'fichier' => 1,
			'credits' => 1,
		),
		'champs_editables' => array(
		],
		'champs_editables' => [
			'titre',
			'descriptif',
			'date',
@@ -200,9 +197,9 @@ function medias_declarer_tables_objets_sql($tables) {
			'distant',
			'extension',
			'id_vignette',
			'media'
		),
		'champs_versionnes' => array(
			'media',
		],
		'champs_versionnes' => [
			'id_vignette',
			'titre',
			'descriptif',
@@ -213,18 +210,18 @@ function medias_declarer_tables_objets_sql($tables) {
			'mode',
			'credits',
			'fichier',
			'distant'
		),
		'modeles' => array('document', 'doc', 'img', 'emb', 'image', 'video', 'audio', 'file'),
			'distant',
		],
		'modeles' => ['document', 'doc', 'img', 'emb', 'image', 'video', 'audio', 'file'],
		'modeles_styliser' => 'medias_modeles_styliser',
	);
	];

	// jointures sur les forum pour tous les objets
	$tables[]['tables_jointures'][] = 'documents_liens';

	// recherche jointe sur les documents pour les articles et rubriques
	$tables['spip_articles']['rechercher_jointures']['document'] = array('titre' => 2, 'descriptif' => 1);
	$tables['spip_rubriques']['rechercher_jointures']['document'] = array('titre' => 2, 'descriptif' => 1);
	$tables['spip_articles']['rechercher_jointures']['document'] = ['titre' => 2, 'descriptif' => 1];
	$tables['spip_rubriques']['rechercher_jointures']['document'] = ['titre' => 2, 'descriptif' => 1];

	return $tables;
}
@@ -234,7 +231,6 @@ function medias_declarer_tables_objets_sql($tables) {
 *
 * @param string $serveur
 * @param string $champ_media
 * @return void
 */
function creer_base_types_doc($serveur = '', $champ_media = 'media_defaut') {
	global $tables_images, $tables_sequences, $tables_documents, $tables_mime;
@@ -242,14 +238,23 @@ function creer_base_types_doc($serveur = '', $champ_media = 'media_defaut') {
	include_spip('base/abstract_sql');

	// charger en memoire tous les types deja definis pour limiter les requettes
	$rows = sql_allfetsel('mime_type,titre,inclus,extension,' . $champ_media . ',upload,descriptif', 'spip_types_documents', '', '', '', '', '', $serveur);
	$deja = array();
	$rows = sql_allfetsel(
		'mime_type,titre,inclus,extension,' . $champ_media . ',upload,descriptif',
		'spip_types_documents',
		'',
		'',
		'',
		'',
		'',
		$serveur
	);
	$deja = [];
	foreach ($rows as $k => $row) {
		$deja[$row['extension']] = &$rows[$k];
	}

	$insertions = array();
	$updates = array();
	$insertions = [];
	$updates = [];

	foreach ($tables_mime as $extension => $type_mime) {
		if (isset($tables_images[$extension])) {
@@ -269,20 +274,22 @@ function creer_base_types_doc($serveur = '', $champ_media = 'media_defaut') {
			}
		}

		// type de media
		// type de media (par defaut)
		$media = 'file';
		if (preg_match(',^image/,', $type_mime) or in_array($type_mime, array('application/illustrator'))) {
		if (preg_match(',^image/,', (string) $type_mime) || in_array($type_mime, ['application/illustrator'])) {
			$media = 'image';
		} elseif (preg_match(',^audio/,', $type_mime)) {
		} elseif (preg_match(',^audio/,', (string) $type_mime)) {
			$media = 'audio';
		} elseif (preg_match(',^video/,', $type_mime) or in_array(
		} elseif (
			preg_match(',^video/,', (string) $type_mime) || in_array(
				$type_mime,
			array('application/ogg', 'application/x-shockwave-flash', 'application/mp4')
		)) {
				['application/ogg', 'application/x-shockwave-flash', 'application/mp4']
			)
		) {
			$media = 'video';
		}

		$set = array(
		$set = [
			'mime_type' => $type_mime,
			'titre' => $titre,
			'inclus' => $inclus,
@@ -290,7 +297,7 @@ function creer_base_types_doc($serveur = '', $champ_media = 'media_defaut') {
			$champ_media => $media,
			'upload' => 'oui',
			'descriptif' => '',
		);
		];
		if (!isset($deja[$extension])) {
			$insertions[] = $set;
		} elseif (array_diff($deja[$extension], $set)) {
@@ -305,11 +312,10 @@ function creer_base_types_doc($serveur = '', $champ_media = 'media_defaut') {
	}

	if ($insertions) {
		sql_insertq_multi('spip_types_documents', $insertions, '', $serveur);
		sql_insertq_multi('spip_types_documents', $insertions, [], $serveur);
	}
}


/**
 * Optimiser la base de données en supprimant les liens orphelins
 *
@@ -322,18 +328,21 @@ function medias_optimiser_base_disparus($flux) {
	// optimiser les liens morts :
	// entre documents vers des objets effaces
	// depuis des documents effaces
	$flux['data'] += objet_optimiser_liens(array('document' => '*'), '*');
	$flux['data'] += objet_optimiser_liens(['document' => '*'], '*');

	// on ne nettoie volontairement pas automatiquement les documents orphelins
	// mais il faut nettoyer les logos qui ne sont plus liés à rien
	$res = sql_select("D.id_document",
		"spip_documents AS D
	$res = sql_select(
		'D.id_document',
		'spip_documents AS D
						LEFT JOIN spip_documents_liens AS L
							ON (L.id_document=D.id_document)",
		sql_in('D.mode', ['logoon', 'logooff']) . " AND L.id_document IS NULL");
							ON (L.id_document=D.id_document)',
		sql_in('D.mode', ['logoon', 'logooff']) . ' AND L.id_document IS NULL'
	);

	$supprimer_document = charger_fonction('supprimer_document', 'action');
	while ($row = sql_fetch($res)) {
		autoriser_exception('supprimer', 'document', $row['id_document']);
		$supprimer_document($row['id_document']);
		$flux['data']++;
	}
+28 −25
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
@@ -16,21 +15,22 @@ if (!defined('_ECRIRE_INC_VERSION')) {

global $tables_images, $tables_sequences, $tables_documents, $tables_mime, $mime_alias;

$tables_images = array(
$tables_images = [
	// Images reconnues par PHP
	'jpg' => 'JPEG',
	'png' => 'PNG',
	'gif' => 'GIF',
	'webp' => 'WEBP',
	'avif' => 'AVIF',

	// Autres images (peuvent utiliser le tag <img>)
	'bmp' => 'BMP',
	'svg' => 'SVG',
);
];

// Multimedia (peuvent utiliser le tag <embed>)

$tables_sequences = array(
$tables_sequences = [
	'aac' => 'Advanced Audio Coding',
	'ac3' => 'AC-3 Compressed Audio',
	'aifc' => 'Compressed AIFF Audio',
@@ -85,11 +85,11 @@ $tables_sequences = array(
	'wmv' => 'Windows Media Video',
	'y4m' => 'YUV4MPEG2',
	'3ga' => '3GP Audio File',
	'3gp' => '3rd Generation Partnership Project'
);
	'3gp' => '3rd Generation Partnership Project',
];

// Documents varies
$tables_documents = array(
$tables_documents = [
	'7z' => '7 Zip',
	'abw' => 'Abiword',
	'ai' => 'Adobe Illustrator',
@@ -114,6 +114,7 @@ $tables_documents = array(
	'epub' => 'EPUB',
	'eps' => 'PostScript',
	'gpx' => 'GPS eXchange Format',
	'geojson' => 'GeoJSON',
	'gz' => 'GZ',
	'h' => 'C header',
	'html' => 'HTML',
@@ -189,7 +190,6 @@ $tables_documents = array(
	'ots' => 'OpenDocument Spreadsheet-template',
	'ott' => 'OpenDocument Text-template',


	// Open XML File Formats
	'docm' => 'Word',
	'docx' => 'Word',
@@ -209,15 +209,16 @@ $tables_documents = array(
	'xlsm' => 'Excel',
	'xlsx' => 'Excel',
	'xltm' => 'Excel template',
	'xltx' => 'Excel template'
);
	'xltx' => 'Excel template',
];

$tables_mime = array(
$tables_mime = [
	// Images reconnues par PHP
	'jpg' => 'image/jpeg',
	'png' => 'image/png',
	'gif' => 'image/gif',
	'webp' => 'image/webp',
	'avif' => 'image/avif',

	// Autres images (peuvent utiliser le tag <img>)
	'bmp' => 'image/x-ms-bmp', // pas enregistre par IANA, variante: image/bmp
@@ -304,6 +305,7 @@ $tables_mime = array(
	'ens' => 'application/octet-stream',
	'eps' => 'application/postscript',
	'epub' => 'application/epub+zip', // pas enregistre par IANA
	'geojson' => 'application/json',
	'gpx' => 'application/gpx+xml', // pas enregistre par IANA
	'gz' => 'application/x-gzip',
	'h' => 'text/x-chdr',
@@ -398,17 +400,18 @@ $tables_mime = array(
	'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
	'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
	'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
	'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template'
);

	'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
];

$mime_alias = array(
$mime_alias = [
	'application/x-ogg' => 'application/ogg',
	'audio/3gpp' => 'video/3gpp',
	'audio/x-m4a' => 'audio/mp4a-latm',
	'audio/x-mpeg' => 'audio/mpeg',
	'audio/x-musepack' => 'audio/musepack',
	'audio/webm' => 'video/webm',
	'video/flv' => 'video/x-flv',
	'video/mp4' => 'application/mp4',
	'image/jpg' => 'image/jpeg'
);
	'audio/mp4' => 'application/mp4',
	'image/jpg' => 'image/jpeg',
];

composer.json

0 → 100644
+72 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
{
    "name": "spip/medias",
    "description": "Gestion des medias dans SPIP",
    "license": "GPL-3.0-or-later",
    "type": "spip-plugin",
    "authors": [
        {
            "name": "Collectif SPIP",
            "homepage": "https://discuter.spip.net/c/spip-dev/5",
            "role": "Maintainer"
        }
    ],
    "require": {
        "php": "^8.2",
        "james-heinrich/getid3": "^1.9",
        "spip/archiviste": "^3.0"
    },
    "require-dev": {
        "rector/rector": "^2.0",
        "spip-league/easy-coding-standard": "^1.1",
        "spip-league/sdk": "^1.0",
        "symfony/console": "^7.2"
    },
    "repositories": {
        "spip": {
            "type": "composer",
            "url": "https://get.spip.net/composer"
        }
    },
    "autoload-dev": {
        "files": [
            "vendor/spip-league/sdk/src/Stub/functions_autoloading.php",
            "vendor/spip-league/sdk/src/Stub/functions_cache.php",
            "vendor/spip-league/sdk/src/Stub/functions_compiler.php",
            "vendor/spip-league/sdk/src/Stub/functions_config.php",
            "vendor/spip-league/sdk/src/Stub/functions_event_dispatching.php",
            "vendor/spip-league/sdk/src/Stub/functions_filesystem.php",
            "vendor/spip-league/sdk/src/Stub/functions_http_client.php",
            "vendor/spip-league/sdk/src/Stub/functions_http_server.php",
            "vendor/spip-league/sdk/src/Stub/functions_i18n.php",
            "vendor/spip-league/sdk/src/Stub/functions_image_processing.php",
            "vendor/spip-league/sdk/src/Stub/functions_logger.php",
            "vendor/spip-league/sdk/src/Stub/functions_metas.php",
            "vendor/spip-league/sdk/src/Stub/functions_objects_base.php",
            "vendor/spip-league/sdk/src/Stub/functions_objects_documents.php",
            "vendor/spip-league/sdk/src/Stub/functions_objects_rubriques.php",
            "vendor/spip-league/sdk/src/Stub/functions_path.php",
            "vendor/spip-league/sdk/src/Stub/functions_plugin_management.php",
            "vendor/spip-league/sdk/src/Stub/functions_sql_query.php",
            "vendor/spip-league/sdk/src/Stub/functions_templating.php",
            "vendor/spip-league/sdk/src/Stub/functions_text_processing.php",
            "vendor/spip-league/sdk/src/Stub/functions_user_management.php"
        ]
    },
    "config": {
        "platform": {
            "php": "8.2.26"
        }
    },
    "extra": {
        "branch-alias": {
            "dev-master": "5.0.x-dev"
        }
    },
    "scripts": {
        "analyse": "vendor/bin/phpstan --memory-limit=-1",
        "check-cs": "vendor/bin/ecs check --ansi",
        "fix-cs": "vendor/bin/ecs check --fix --ansi",
        "rector": "vendor/bin/rector process --ansi",
        "rector-dry-run": "vendor/bin/rector process --dry-run --ansi"
    }
}

ecs.php

0 → 100644
+11 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?php

use SpipLeague\EasyCodingStandard\Set\SetList;
use Symplify\EasyCodingStandard\Config\ECSConfig;

return ECSConfig::configure()
	->withSets([SetList::SPIP])
	->withPaths([__DIR__])
	->withRootFiles()
	->withSkip([__DIR__ . '/lang', __DIR__ . '/vendor', __DIR__ . '/lib'])
;
+0 −24
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<div class='formulaire_spip formulaire_changer_fichier_document' id='formulaire_changer_fichier_document-#ENV{id,new}'>
	[<p class="reponse_formulaire reponse_formulaire_ok" role="status">(#ENV*{message_ok})</p>]
	[<p class="reponse_formulaire reponse_formulaire_erreur" role="alert">(#ENV*{message_erreur})</p>]
	[(#ENV{editable})
	<form action="#ENV{action}#formulaire_changer_fichier_document-#ENV{id,new}" method="post" enctype='multipart/form-data'><div>
		#ACTION_FORMULAIRE
		<div class="editer-groupe">
			<div class="editer editer_fichier[ (#ENV**{erreurs}|table_valeur{fichier}|oui)erreur]">
				<label for="fichier"><:medias:label_fichier:></label>[
				<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{fichier})</span>
				]
				[(#ENV{fichier}) ] 
				<p class='actions'>
				[(#ENV{distant}|=={oui}|oui)<input type='submit' class='btn submit' name='copier_local' value='<:medias:bouton_copier_local|attribut_html:>' />]
				&#91;<a href='#' onclick='jQuery("#changer_fichier_document").toggle("fast");return false;'><:bouton_changer:></a>&#93;
				</p>
				<div id='changer_fichier_document' style='display:none;'>
				[(#INCLURE{fond=formulaires/inc-upload_document, env})]
				</div>
		</div>
		</div>
	</div></form>
	]
</div>
 No newline at end of file
+0 −63
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

function formulaires_changer_fichier_document_charger_dist($id_document) {
	$valeurs = sql_fetsel('id_document,fichier,distant', 'spip_documents', 'id_document=' . intval($id_document));
	if (!$valeurs) {
		return array('editable' => false);
	}

	$charger = charger_fonction('charger', 'formulaires/joindre_document');
	$valeurs = array_merge($valeurs, $charger($id_document, 0, '', 'choix'));

	$valeurs['_hidden'] .= "<input name='id_document' value='$id_document' type='hidden' />";

	return $valeurs;
}

function formulaires_changer_fichier_document_verifier_dist($id_document) {
	$erreurs = array();
	if (_request('copier_local')) {
	} else {
		$verifier = charger_fonction('verifier', 'formulaires/joindre_document');
		$erreurs = $verifier($id_document);
	}

	return $erreurs;
}

function formulaires_changer_fichier_document_traiter_dist($id_document) {
	if (_request('copier_local')) {
		$copier_local = charger_fonction('copier_local', 'action');
		$res = array('editable' => true);
		if (($err = $copier_local($id_document)) === true) {
			$res['message_ok'] = _T('medias:document_copie_locale_succes');
		} else {
			$res['message_erreur'] = $err;
		}
	} else {
		// liberer le nom de l'ancien fichier pour permettre le remplacement par un fichier du meme nom
		if ($ancien_fichier = sql_getfetsel('fichier', 'spip_documents', 'id_document=' . intval($id_document))
			and @file_exists($f = get_spip_doc($ancien_fichier))
		) {
			spip_unlink($f);
		}
		$traiter = charger_fonction('traiter', 'formulaires/joindre_document');
		$res = $traiter($id_document);
	}

	return $res;
}
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<div class="formulaire_spip formulaire_configurer formulaire_#FORM formulaire_#FORM-#ENV{id,nouveau}">
<h3 class='titrem'><img src="#CHEMIN_IMAGE{document-24.png}" class="cadre-icone" /><:medias:titre_documents_joints:></h3>
	[<p class="reponse_formulaire reponse_formulaire_ok" role="status">(#ENV*{message_ok})</p>]
	[<p class="reponse_formulaire reponse_formulaire_erreur" role="alert">(#ENV*{message_erreur})</p>]
	[<div class="reponse_formulaire reponse_formulaire_ok" role="status">(#ENV*{message_ok})</div>]
	[<div class="reponse_formulaire reponse_formulaire_erreur" role="alert">(#ENV*{message_erreur})</div>]
	[(#ENV{editable})
	<p><:medias:texte_documents_joints:></p>
	<p class="explication"><:medias:texte_documents_joints_2:></p>
@@ -10,13 +10,13 @@
		parametre : url d'action ]
		#ACTION_FORMULAIRE
		<div class="editer-groupe">
			#SET{name,documents_objets}#SET{erreurs,#ENV**{erreurs}|table_valeur{#GET{name}}}
			#SET{name,documents_objets}#SET{erreurs,#ENV*{erreurs/#GET{name}}}
			<div class="editer long_label editer_[(#GET{name})][ (#GET{obli})][ (#GET{erreurs}|oui)erreur]">
				<label><:medias:label_activer_document_objets:></label>[
				<span class='erreur_message'>(#GET{erreurs})</span>
				]#INCLURE{fond=formulaires/inc-choisir-objets,name=#GET{name},selected=#ENV**{#GET{name}},exclus=spip_documents}
				]#INCLURE{fond=formulaires/inc-choisir-objets,name=#GET{name},selected=#ENV{#GET{name}},exclus=spip_documents}
			</div>
			#SET{name,documents_date}#SET{erreurs,#ENV**{erreurs}|table_valeur{#GET{name}}}
			#SET{name,documents_date}#SET{erreurs,#ENV*{erreurs/#GET{name}}}
			<div class="editer pleine_largeur editer_[(#GET{name})][ (#GET{obli})][ (#GET{erreurs}|oui)erreur]">
				[
				<span class='erreur_message'>(#GET{erreurs})</span>
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

/**
 * Gestion du formulaire de configuration des documents
 *
 * @package SPIP\Medias\Formulaires
 **/

 */
if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}
@@ -25,16 +23,15 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 *
 * @return array
 *     Environnement du formulaire
 **/
 */
function formulaires_configurer_documents_charger_dist() {
	$valeurs = array();
	foreach (array(
		'documents_objets',
		'documents_date',
	) as $m) {
		$valeurs[$m] = isset($GLOBALS['meta'][$m]) ? $GLOBALS['meta'][$m] : '';
	$valeurs = [];
	foreach (
		['documents_objets', 'documents_date'] as $m
	) {
		$valeurs[$m] = $GLOBALS['meta'][$m] ?? '';
	}
	$valeurs['documents_objets'] = explode(',', $valeurs['documents_objets']);
	$valeurs['documents_objets'] = explode(',', (string) $valeurs['documents_objets']);

	return $valeurs;
}
@@ -44,13 +41,13 @@ function formulaires_configurer_documents_charger_dist() {
 *
 * @return array
 *     Retours du traitement
 **/
 */
function formulaires_configurer_documents_traiter_dist() {
	$res = array('editable' => true);
	if (!is_null($v = _request($m = 'documents_date'))) {
	$res = ['editable' => true];
	if (null !== ($v = _request($m = 'documents_date'))) {
		ecrire_meta($m, $v == 'oui' ? 'oui' : 'non');
	}
	if (!is_null($v = _request($m = 'documents_objets'))) {
	if (null !== ($v = _request($m = 'documents_objets'))) {
		ecrire_meta($m, is_array($v) ? implode(',', $v) : '');
	}

Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<div class='formulaire_spip formulaire_editer formulaire_editer_document formulaire_editer_document-#ENV{id_document,nouveau}'>
	[<p class="reponse_formulaire reponse_formulaire_ok" role="status">(#ENV**{message_ok})</p>]
	[<p class="reponse_formulaire reponse_formulaire_erreur" role="alert">(#ENV*{message_erreur})</p>]
	[<div class="reponse_formulaire reponse_formulaire_ok" role="status">(#ENV**{message_ok})</div>]
	[<div class="reponse_formulaire reponse_formulaire_erreur" role="alert">(#ENV*{message_erreur})</div>]
	[(#ENV{editable})
	<form method='post' action='#ENV{action}' enctype='multipart/form-data'><div>
		[(#REM) declarer les hidden qui declencheront le service du formulaire
@@ -12,26 +12,38 @@
		]
		<div style="position:absolute;#LANG_LEFT:-10000px;" class="invisible-first-save-button"><input type='submit' class='btn submit' tabindex="-1" value='<:bouton_enregistrer:>' /></div>
		<div class="editer-groupe">
			<div class="editer editer_titre[ (#ENV**{erreurs}|table_valeur{titre}|oui)erreur]">
			<div class="editer editer_titre[ (#ENV*{erreurs/titre}|oui)erreur]">
				<label for="titre">[(#ENV{mode}|=={document}|?{<:medias:entree_titre_document:>,<:medias:entree_titre_image:>})]</label>[
				<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{titre})</span>
				]<input type='text' class='text' name='titre' id='titre' value="[(#ENV**{titre,''})]" />
				<span class='erreur_message'>(#ENV*{erreurs/titre})</span>
				]<input type='text' class='text' name='titre' id='titre' value="[(#ENV{titre,''})]" />
			</div>
			<div class='editer editer_parent[ (#ENV**{erreurs}|table_valeur{parents}|oui)erreur]'>
			<div class='editer editer_parent[ (#ENV*{erreurs/parents}|oui)erreur]'>
				<label for="parents"><:medias:label_parents:></label>[
				<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{parents})</span>
				<span class='erreur_message'>(#ENV*{erreurs/parents})</span>
				]<INCLURE{fond=formulaires/selecteur/articles, selected=#ENV{parents}, name=parents, rubriques=1, articles=1} />
			</div>
			[<div class="editer editer_fichier[ (#ENV**{erreurs}|table_valeur{fichier}|oui)erreur]">
			[<div class="editer editer_fichier[ (#ENV*{erreurs/fichier}|oui)erreur]">
				<label for="fichier"><:medias:label_fichier:></label>[
				<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{fichier})</span>
				<span class='erreur_message'>(#ENV*{erreurs/fichier})</span>
				]
				(#ENV{fichier})
				<p class='actions right'>
				[(#ENV{distant}|=={oui}|et{#TAILLE|<{#CONST{_COPIE_LOCALE_MAX_SIZE}}}|oui)<input type='submit' class='btn submit btn_mini' name='copier_local' value='<:medias:bouton_copier_local|attribut_html:>' />]
				[(#PIPELINE{editer_document_actions,#ARRAY{args,#ARRAY{id_document,#ENV{id_document,nouveau}},data,''}})]
				<a class="btn btn_secondaire btn_mini" href='#' onclick='jQuery("#changer_fichier_document").toggle("fast");return false;'><:bouton_changer:></a>
				<a class="btn btn_secondaire btn_mini" name="bouton_changer_fichier_document"><:bouton_changer:></a>
				</p>
				[<!--(#REM) TODO : remplacer par une fonction générique de type bouton_toggle -->]
				<script type="module">
					import { slideToggle , debounce } from 'ajaxCallback.js';
					const btn = document.querySelector('.formulaire_editer_document .btn[name="bouton_changer_fichier_document"]');
					btn.addEventListener('click', debounce(
						async (e) => {
							e.preventDefault();
							await slideToggle(document.getElementById('changer_fichier_document'),200);
						},
						200)
					);
				</script>
				#SET{upload,#INCLURE{fond=formulaires/inc-upload_document, env, joindre_upload=oui, multi=non}}
				<div id='changer_fichier_document' class="[(#GET{upload}|match{erreur}|non)none-js]">
					#GET{upload}
@@ -66,41 +78,41 @@
				][(#ENV{_taille_modif}|taille_en_octets|texte_backend)]</div>]
				[(#PIPELINE{afficher_metas_document,#ARRAY{args,#ARRAY{'quoi','editer_document','id_document',#ENV{id_document}},data,''}})]
			</div>
			<div class="editer editer_descriptif[ (#ENV**{erreurs}|table_valeur{descriptif}|oui)erreur]">
				<label for="descriptif"><:info_description:></label>[
				<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{descriptif})</span>
				]<textarea name='descriptif' id='descriptif'[ lang='(#LANGUE)'] rows='2' cols='40'>[(#ENV**{descriptif})]</textarea>
			<div class="editer editer_descriptif[ (#ENV*{erreurs/descriptif}|oui)erreur]">
				<label for="descriptif"><:medias:descriptif:></label>[
				<span class='erreur_message'>(#ENV*{erreurs/descriptif})</span>
				]<textarea name='descriptif' id='descriptif'[ lang='(#LANGUE)'] rows='2' cols='40'>[(#ENV{descriptif})]</textarea>
			</div>
			[(#ENV{_editer_date})
			<div class="editer editer_date[ (#ENV**{erreurs}|table_valeur{saisie_date}|oui)erreur][ (#ENV**{erreurs}|table_valeur{saisie_heure}|oui)erreur]">
			<div class="editer editer_date[ (#ENV*{erreurs/saisie_date}|oui)erreur][ (#ENV*{erreurs/saisie_heure}|oui)erreur]">
				<label for="saisie_date" class='date'><:date:></label>[
				<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{saisie_date})</span>
				<span class='erreur_message'>(#ENV*{erreurs/saisie_date})</span>
				]<input type='text' class='text date' name='saisie_date' id='saisie_date' size="10" maxlength="10" value="[(#ENV{saisie_date})]" aria-describedby="format_date_doc_#ENV{id_document,nouveau}"/>
				<span class='choix heure'>
					<label for='saisie_heure' class='heure'><:medias:info_heure:></label>[
					<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{saisie_heure})</span>]
					<span class='erreur_message'>(#ENV*{erreurs/saisie_heure})</span>]
					<input type='text' class='text heure' name='saisie_heure' id='saisie_heure' size="5" maxlength="5" value="[(#ENV{saisie_heure})]"  aria-describedby="format_heure_doc_#ENV{id_document,nouveau}"/>
				</span>
				<p hidden id="format_date_doc_#ENV{id_document,nouveau}"><:format_date_attendu:></p>
				<p hidden id="format_heure_doc_#ENV{id_document,nouveau}"><:format_heure_attendu:></p>
			</div>]
			<div class="editer editer_credits[ (#ENV**{erreurs}|table_valeur{credits}|oui)erreur]">
			<div class="editer editer_credits[ (#ENV*{erreurs/credits}|oui)erreur]">
				<label for="credits"><:medias:label_credits:></label>[
				<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{credits})</span>
				]<input type='text' class='text' name='credits' id='credits' value="#ENV**{credits,''}" />
				<span class='erreur_message'>(#ENV*{erreurs/credits})</span>
				]<input type='text' class='text' name='credits' id='credits' value="#ENV{credits,''}" />
			</div>
			[(#MEDIA|=={image}|oui)
				<div class="editer editer_alt[ (#ENV**{erreurs}|table_valeur{alt}|oui)erreur]">
				<div class="editer editer_alt[ (#ENV*{erreurs/alt}|oui)erreur]">
					<label for="alt"><:medias:label_alt:></label>[
					<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{alt})</span>
					<span class='erreur_message'>(#ENV*{erreurs/alt})</span>
					]<p class="explication"><:medias:info_alt:></p>
					<input type='text' class='text' name='alt' id='alt' value="#ENV**{alt,''}" />
					<input type='text' class='text' name='alt' id='alt' value="#ENV{alt,''}" />
				</div>
			]
			[(#ENV{_editer_dimension})
			<div class="editer editer_dimensions[ (#ENV**{erreurs}|table_valeur{dimensions}|oui)erreur]">
			<div class="editer editer_dimensions[ (#ENV*{erreurs/dimensions}|oui)erreur]">
				<label><:medias:entree_dimensions:></label>[
				<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{dimensions})</span>]
				<span class='erreur_message'>(#ENV*{erreurs/dimensions})</span>]
				<span class='choix largeur'>
					<label for='largeur' class='largeur'><:medias:info_largeur:></label>
					<input type='text' class='text' name='largeur' id='largeur' value="[(#ENV{largeur})]" />
@@ -115,5 +127,5 @@
		<!--extra-->
		<p class="boutons"><span class='image_loading'>&nbsp;</span><input type='submit' class='btn submit' value='<:bouton_enregistrer:>' /></p>
	</div></form>
	#INCLURE{fond=formulaires/dateur/inc-dateur}]
	#INCLURE{fond=formulaires/dateur/inc-dateur}
</div>
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
@@ -25,22 +24,30 @@ function formulaires_editer_document_charger_dist(
	$retour = '',
	$lier_trad = 0,
	$config_fonc = 'documents_edit_config',
	$row = array(),
	$row = [],
	$hidden = ''
) {
	$valeurs = formulaires_editer_objet_charger('document', $id_document, $id_parent, $lier_trad, $retour, $config_fonc, $row, $hidden);

	$valeurs = formulaires_editer_objet_charger(
		'document',
		$id_document,
		$id_parent,
		$lier_trad,
		$retour,
		$config_fonc,
		$row,
		$hidden
	);

	if (intval($id_document) and !autoriser('modifier', 'document', intval($id_document))) {
	if (intval($id_document) && !autoriser('modifier', 'document', intval($id_document))) {
		$valeurs['editable'] = '';
	}

	// relier les parents
	$valeurs['parents'] = array();
	$valeurs['parents'] = [];
	$valeurs['_hidden'] = '';
	$parents = sql_allfetsel('objet,id_objet', 'spip_documents_liens', 'id_document=' . intval($id_document));
	foreach ($parents as $p) {
		if (in_array($p['objet'], array('article', 'rubrique')) and $p['id_objet'] > 0) {
		if (in_array($p['objet'], ['article', 'rubrique']) && $p['id_objet'] > 0) {
			$valeurs['parents'][] = $p['objet'] . '|' . $p['id_objet'];
		} else {
			$valeurs['_hidden'] .= "<input type='hidden' name='parents[]' value='" . $p['objet'] . '|' . $p['id_objet'] . "' />";
@@ -66,7 +73,8 @@ function formulaires_editer_document_charger_dist(
	);
	$valeurs['type_document'] = $row['type_document'];
	$valeurs['_inclus'] = $row['inclus'];
	if (in_array($valeurs['extension'], array('jpg', 'gif', 'png', 'svg'))) {
	include_spip('inc/filtres_images_lib_mini');
	if (in_array($valeurs['extension'], _image_extensions_acceptees_en_entree())) {
		$valeurs['apercu'] = get_spip_doc($valeurs['fichier']);
	}

@@ -75,10 +83,11 @@ function formulaires_editer_document_charger_dist(
	if ($valeurs['distant'] !== 'oui') {
		include_spip('inc/renseigner_document');
		$infos = renseigner_taille_dimension_image(get_spip_doc($valeurs['fichier']), $valeurs['extension']);
		if ($infos and is_array($infos) and isset($infos['taille'])) {
			if ($infos['taille'] != $valeurs['taille']
				or ($infos['type_image'] && ($infos['largeur'] != $valeurs['largeur']))
				or ($infos['type_image'] && ($infos['hauteur'] != $valeurs['hauteur']))
		if ($infos && is_array($infos) && isset($infos['taille'])) {
			if (
				$infos['taille'] != $valeurs['taille']
				|| $infos['type_image'] && $infos['largeur'] != $valeurs['largeur']
				|| $infos['type_image'] && $infos['hauteur'] != $valeurs['hauteur']
			) {
				$valeurs['_taille_modif'] = $infos['taille'];
				$valeurs['_largeur_modif'] = $infos['largeur'];
@@ -91,7 +100,6 @@ function formulaires_editer_document_charger_dist(
		}
	}


	// pour l'upload d'un nouveau doc
	if ($valeurs['fichier']) {
		$charger = charger_fonction('charger', 'formulaires/joindre_document');
@@ -106,7 +114,7 @@ function formulaires_editer_document_charger_dist(
function documents_edit_config($row) {
	global $spip_lang;

	$config = array();//$GLOBALS['meta'];
	$config = []; //$GLOBALS['meta'];
	$config['lignes'] = 8;
	$config['langue'] = $spip_lang;

@@ -121,13 +129,13 @@ function formulaires_editer_document_verifier_dist(
	$retour = '',
	$lier_trad = 0,
	$config_fonc = 'documents_edit_config',
	$row = array(),
	$row = [],
	$hidden = ''
) {
	$erreurs = formulaires_editer_objet_verifier('document', $id_document, is_numeric($id_document) ? array() : array('titre'));
	$erreurs = formulaires_editer_objet_verifier('document', $id_document, is_numeric($id_document) ? [] : ['titre']);

	// verifier l'upload si on a demande a changer le document
	if (_request('joindre_upload') or _request('joindre_ftp') or _request('joindre_distant')) {
	if (_request('joindre_upload') || _request('joindre_ftp') || _request('joindre_distant')) {
		if (_request('copier_local')) {
		} else {
			$verifier = charger_fonction('verifier', 'formulaires/joindre_document');
@@ -137,8 +145,9 @@ function formulaires_editer_document_verifier_dist(

	// On ne vérifie la date que si on avait le droit de la modifier
	if (lire_config('documents_date') == 'oui') {
		if (!$date = recup_date(_request('saisie_date') . ' ' . _request('saisie_heure') . ':00')
			or !($date = mktime($date[3], $date[4], 0, $date[1], $date[2], $date[0]))
		if (
			!($date = recup_date(_request('saisie_date') . ' ' . _request('saisie_heure') . ':00'))
			|| !($date = mktime($date[3], $date[4], 0, $date[1], $date[2], $date[0]))
		) {
			$erreurs['saisie_date'] = _T('medias:format_date_incorrect');
		} else {
@@ -151,41 +160,48 @@ function formulaires_editer_document_verifier_dist(
	return $erreurs;
}

// https://code.spip.net/@inc_editer_article_dist
function formulaires_editer_document_traiter_dist(
	$id_document = 'new',
	$id_parent = '',
	$retour = '',
	$lier_trad = 0,
	$config_fonc = 'documents_edit_config',
	$row = array(),
	$row = [],
	$hidden = ''
) {
	if (is_null(_request('parents'))) {
		set_request('parents', array());
	$rename = null;
	if (_request('parents') === null) {
		set_request('parents', []);
	}

	// verifier les infos de taille et dimensions sur les fichiers locaux
	// cas des maj de fichier directes par ftp
	foreach (array('taille', 'largeur', 'hauteur') as $c) {
		if (($v = _request("_{$c}_modif")) and !_request($c)) {
	foreach (['taille', 'largeur', 'hauteur'] as $c) {
		if (($v = _request("_{$c}_modif")) && !_request($c)) {
			set_request($c, $v);
		}
	}

	$res = formulaires_editer_objet_traiter('document', $id_document, $id_parent, $lier_trad, $retour, $config_fonc, $row, $hidden);
	$res = formulaires_editer_objet_traiter(
		'document',
		$id_document,
		$id_parent,
		$lier_trad,
		$retour,
		$config_fonc,
		$row,
		$hidden
	);
	set_request('parents');
	$autoclose = "<script type='text/javascript'>if (window.jQuery) jQuery.modalboxclose();</script>";
	if (_request('copier_local')
		or _request('joindre_upload')
		or _request('joindre_ftp')
		or _request('joindre_distant')
		or _request('joindre_zip')
	$autoclose = '<script>if (window.jQuery) jQuery.modalboxclose();</script>';
	$mode = sql_getfetsel('mode', 'spip_documents', "id_document = $id_document");
	if (
		_request('copier_local') || _request('joindre_upload') || _request('joindre_ftp') || _request('joindre_distant') || _request('joindre_zip')
	) {
		$autoclose = '';
		if (_request('copier_local')) {
			$copier_local = charger_fonction('copier_local', 'action');
			$res = array('editable' => true);
			$res = ['editable' => true];
			if (($err = $copier_local($id_document)) === true) {
				$res['message_ok'] = (isset($res['message_ok']) ? $res['message_ok'] . '<br />' : '') . _T('medias:document_copie_locale_succes');
			} else {
@@ -194,22 +210,22 @@ function formulaires_editer_document_traiter_dist(
			set_request('credits'); // modifie par la copie locale
		} else {
			// liberer le nom de l'ancien fichier pour permettre le remplacement par un fichier du meme nom
			if ($ancien_fichier = sql_getfetsel('fichier', 'spip_documents', 'id_document=' . intval($id_document))
				and !tester_url_absolue($ancien_fichier)
				and @file_exists($rename = get_spip_doc($ancien_fichier))
			if (
				($ancien_fichier = sql_getfetsel('fichier', 'spip_documents', 'id_document=' . intval($id_document)))
				&& !tester_url_absolue($ancien_fichier)
				&& @file_exists($rename = get_spip_doc($ancien_fichier))
			) {
				@rename($rename, "$rename--.old");
			}
			$traiter = charger_fonction('traiter', 'formulaires/joindre_document');
			$res2 = $traiter($id_document);
			$res2 = $traiter($id_document, 0, '', $mode);
			if (isset($res2['message_erreur'])) {
				$res['message_erreur'] = $res2['message_erreur'];
				// retablir le fichier !
				if ($rename) {
					@rename("$rename--.old", $rename);
				}
			} else // supprimer vraiment le fichier initial
			{
			} else { // supprimer vraiment le fichier initial
				spip_unlink("$rename--.old");
			}
		}
@@ -220,13 +236,13 @@ function formulaires_editer_document_traiter_dist(
		// regarder si une demande de rotation a eu lieu
		// c'est un bouton image, dont on a pas toujours le name en request, on fait avec
		$angle = 0;
		if (_request('tournerL90') or _request('tournerL90_x')) {
		if (_request('tournerL90') || _request('tournerL90_x')) {
			$angle = -90;
		}
		if (_request('tournerR90') or _request('tournerR90_x')) {
		if (_request('tournerR90') || _request('tournerR90_x')) {
			$angle = 90;
		}
		if (_request('tourner180') or _request('tourner180_x')) {
		if (_request('tourner180') || _request('tourner180_x')) {
			$angle = 180;
		}
		if ($angle) {
@@ -244,7 +260,11 @@ function formulaires_editer_document_traiter_dist(
	}

	if ($res['message_ok']) {
		$res['message_ok'] .= '<script type="text/javascript">if (window.jQuery) ajaxReload("document_infos");</script>';
		if (!str_contains((string) $mode, 'logo')) {
			$res['message_ok'] .= '<script>ajaxReload("document_infos");</script>';
		} else {
			$res['message_ok'] .= '<script>ajaxReload("navigation");</script>';
		}
	}

	return $res;
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<div class='formulaire_spip formulaire_illustrer_document' id='formulaire_illustrer_document-#ENV{id,new}'>
	[<p class="reponse_formulaire reponse_formulaire_ok" role="status">(#ENV*{message_ok})</p>]
	[<p class="reponse_formulaire reponse_formulaire_erreur" role="alert">(#ENV*{message_erreur})</p>]
	[<div class="reponse_formulaire reponse_formulaire_ok" role="status">(#ENV*{message_ok})</div>]
	[<div class="reponse_formulaire reponse_formulaire_erreur" role="alert">(#ENV*{message_erreur})</div>]
	[(#ENV{editable})
	<form action="#ENV{action}#formulaire_illustrer_document-#ENV{id,new}" method="post" enctype='multipart/form-data'><div>
		#ACTION_FORMULAIRE
		<div class="editer-groupe">
			<div class="editer editer_fichier[ (#ENV**{erreurs}|table_valeur{fichier}|oui)erreur]">
			<div class="editer editer_fichier[ (#ENV*{erreurs/fichier}|oui)erreur]">
				<label for="fichier"><:medias:label_fichier_vignette:></label>[
				<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{fichier})</span>
				<span class='erreur_message'>(#ENV*{erreurs/fichier})</span>
				][<tt>(#ENV{vignette}|set_spip_doc)</tt><br />][
				(#CONFIG{taille_preview}|intval|?{#ENV*{vignette}|image_reduire{#CONFIG{taille_preview}},#ENV*{vignette}|balise_img})
				][(#ENV*{vignette}|non)<:medias:aucune_vignette:>
@@ -15,7 +15,9 @@
				]
				<p class='actions float-end'>
				[(#ENV{id_vignette}|oui|et{#AUTORISER{supprimer,document,#ENV{id_vignette}}}) <input type='submit' class='btn btn_mini btn_secondaire submit' name='supprimer' value='<:medias:bouton_supprimer|attribut_html:>' />]
				[(#ENV{id_vignette}|non|ou{#AUTORISER{modifier,document,#ENV{id_vignette}}}) <a class="btn btn_mini btn_secondaire" href='#' onclick='jQuery("#illustrer_document").toggle("fast");return false;'><:bouton_changer:></a>]
				[(#ENV{id_vignette}|non|ou{#AUTORISER{modifier,document,#ENV{id_vignette}}}) 
				[<!--(#REM) TODO : remplacer par une fonction générique de type bouton_toggle -->]
				<a class="btn btn_mini btn_secondaire" href='javascript:' onclick='jQuery("#illustrer_document").toggle("fast");return false;'><:bouton_changer:></a>]
				<span class='image_loading'>&nbsp;</span>
				</p>
				<div id='illustrer_document' style='display:none;'>
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
@@ -16,15 +15,25 @@ if (!defined('_ECRIRE_INC_VERSION')) {

function formulaires_illustrer_document_charger_dist($id_document) {
	include_spip('inc/documents');
	$valeurs = sql_fetsel('id_document,mode,id_vignette,extension,media', 'spip_documents', 'id_document=' . intval($id_document));
	if (!$valeurs /*OR in_array($valeurs['extension'],array('jpg','gif','png'))*/) {
		return array('editable' => false, 'id' => $id_document);
	$valeurs = sql_fetsel(
		'id_document,mode,id_vignette,extension,media',
		'spip_documents',
		'id_document=' . intval($id_document)
	);
	if (
		!$valeurs || in_array($valeurs['mode'], ['logoon', 'logooff'])
	) {
		return ['editable' => false, 'id' => $id_document];
	}

	$valeurs['id'] = $id_document;
	$valeurs['_hidden'] = "<input name='id_document' value='$id_document' type='hidden' />";
	$valeurs['mode'] = 'vignette'; // pour les id dans le dom
	$vignette = sql_fetsel('fichier,largeur,hauteur,id_document', 'spip_documents', 'id_document=' . $valeurs['id_vignette']);
	$vignette = sql_fetsel(
		'fichier,largeur,hauteur,id_document',
		'spip_documents',
		'id_document=' . $valeurs['id_vignette']
	);
	if ($vignette) {
		$valeurs['vignette'] = get_spip_doc($vignette['fichier']);
		$valeurs['hauteur'] = $vignette['hauteur'];
@@ -36,9 +45,9 @@ function formulaires_illustrer_document_charger_dist($id_document) {
		$valeurs['largeur'] = null;
		$valeurs['id_vignette'] = null;
	}
	$valeurs['_pipeline'] = array('editer_contenu_objet', array('type' => 'illustrer_document', 'id' => $id_document));
	$valeurs['_pipeline'] = ['editer_contenu_objet', ['type' => 'illustrer_document', 'id' => $id_document]];

	if (intval($id_document) and !autoriser('modifier', 'document', intval($id_document))) {
	if (intval($id_document) && !autoriser('modifier', 'document', intval($id_document))) {
		$valeurs['editable'] = '';
	}

@@ -46,7 +55,7 @@ function formulaires_illustrer_document_charger_dist($id_document) {
}

function formulaires_illustrer_document_verifier_dist($id_document) {
	$erreurs = array();
	$erreurs = [];
	if (_request('supprimer')) {
	} else {
		$id_vignette = sql_getfetsel('id_vignette', 'spip_documents', 'id_document=' . intval($id_document));
@@ -59,10 +68,10 @@ function formulaires_illustrer_document_verifier_dist($id_document) {

function formulaires_illustrer_document_traiter_dist($id_document) {
	$id_vignette = sql_getfetsel('id_vignette', 'spip_documents', 'id_document=' . intval($id_document));
	$res = array('editable' => true);
	$res = ['editable' => true];
	if (_request('supprimer')) {
		$supprimer_document = charger_fonction('supprimer_document', 'action');
		if ($id_vignette and $supprimer_document($id_vignette)) {
		if ($id_vignette && $supprimer_document($id_vignette)) {
			$res['message_ok'] = _T('medias:vignette_supprimee');
		} else {
			$res['message_erreur'] = _T('medias:erreur_suppression_vignette');
@@ -75,11 +84,11 @@ function formulaires_illustrer_document_traiter_dist($id_document) {

		$ajoute = $ajouter_documents($id_vignette, $files, '', 0, 'vignette');

		if (is_numeric(reset($ajoute))
			and $id_vignette = reset($ajoute)
		if (
			is_numeric(reset($ajoute)) && ($id_vignette = reset($ajoute))
		) {
			include_spip('action/editer_document');
			document_modifier($id_document, array('id_vignette' => $id_vignette, 'mode' => 'document'));
			document_modifier($id_document, ['id_vignette' => $id_vignette, 'mode' => 'document']);
			$res['message_ok'] = _T('medias:document_installe_succes');
		} else {
			$res['message_erreur'] = reset($ajoute);
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
#SET{domid,_#ENV{mode}|concat{'_',#ENV{id,new}}}
#SET{methode,upload}
[(#ENV{joindre_mediatheque}|oui)#SET{methode,mediatheque}]
[(#ENV{joindre_distant}|oui)#SET{methode,distant}]
[(#ENV{joindre_ftp}|oui)#SET{methode,ftp}]

[(#REM) On récupère la liste des méthodes disponibles ]
#SET{methodes_upload,#ENV**|medias_lister_methodes_upload}
[(#ENV{methode_focus}|et{#GET{methodes_upload}|is_array}|et{#ENV{methode_focus}|array_key_exists{#GET{methodes_upload}}}|oui)#SET{methode,#ENV{methode_focus}}]

[(#REM) On ouvre par défaut sur la première méthode de la liste ]
#SET{methode, #GET{methodes_upload}|key}

[(#REM) Veut-on forcer l'ouverture sur une méthode précise ? ]
[(#ENV{joindre_mediatheque}|oui)#SET{methode_focus,mediatheque}]
[(#ENV{joindre_distant}|oui)#SET{methode_focus,distant}]
[(#ENV{joindre_ftp}|oui)#SET{methode_focus,ftp}]
[(#ENV{methode_focus}|oui)#SET{methode_focus, #ENV{methode_focus}}]

[(#GET{methode_focus}|et{#GET{methodes_upload}|is_array}|et{#GET{methode_focus}|array_key_exists{#GET{methodes_upload}}}|oui)#SET{methode,#GET{methode_focus}}]

<div id="defaultsubmit#GET{domid}" class="none"></div>
<BOUCLE_methodes(DATA){source tableau,#GET{methodes_upload}}>
@@ -22,31 +29,69 @@
					#VALEUR{label_lien}
				]
				[(#GET{methode_upload}|=={#CLE}|non)
					<a href='#' onclick="change_methode('#GET{domid}','#CLE');return false;">#VALEUR{label_lien}</a>
					<a href="javascript:" class="bouton_choix_joindre"[ data-methode='(#ARRAY{domid,#GET{domid},methode,#CLE}|json_encode|attribut_html)']>#VALEUR{label_lien}</a>
				]
			</BOUCLE_methodes_liens>
		</div>
		]
		<p class='boutons'><input class='btn submit' type="submit" name="joindre_#CLE" value="#VALEUR{label_bouton}"/></p>
		<p class="boutons"><input class='btn submit' type="submit" name="joindre_#CLE" value="#VALEUR{label_bouton}"/></p>
	</div>
</BOUCLE_methodes>

[(#REM) Formulaire pour deballer un zip]
[<div class="editer-groupe"><div class='fieldset deballer_zip'>(#ENV**{erreurs}|table_valeur{lister_contenu_archive})</div></div>]

<script type='text/javascript'>/*<!\[CDATA\[*/
if (window.jQuery){
function change_methode(domid,methode){
	var id = "#joindre_"+methode+domid;
	if (jQuery(id).is(':hidden')) {
		jQuery('div.joindre_mode'+domid+':visible').slideUp('fast');
		jQuery(id).slideDown('fast');
[<div class="editer-groupe"><div class='fieldset deballer_zip'>(#ENV**{erreurs/lister_contenu_archive})</div></div>]

<script type="module">

import { onAjaxLoad, slideDown, slideUp  } from "ajaxCallback.js";

const change_methode = (domid, methode) => {

	const id = document.getElementById(`joindre_${methode}${domid}`);
	if (id && window.getComputedStyle(id).display === "none") {
		for (const section of [...document.querySelectorAll('[id^="joindre_"]')]) {
			if (section.id.indexOf(`joindre_${methode}`) === -1) {
				section.slideUp(200);
			}
	// placer en haut du formulaire les boutons submit par defaut correspondant a la methode active
	jQuery("#defaultsubmit"+domid).html('').append(jQuery(id).find('.boutons').eq(-1).find('input').clone(true));
	var joindre = jQuery(id).find('.boutons').eq(-1).find('input').prop('name').replace('joindre_', '');
	jQuery("#defaultsubmit"+domid).append($('<input>').attr({type: 'hidden', id: 'methode_focus', name: 'methode_focus', value: joindre}));
		}
jQuery(function(){change_methode('#GET{domid}','#GET{methode}');});
		id.slideDown(200);
	}
/*\]\]>*/</script>
	// placer en haut du formulaire les boutons submit par defaut correspondant a la methode active
	const id__btn = [...id.querySelectorAll(".boutons")].splice(-1)[0];
	const submit_defaut = document.getElementById(`defaultsubmit${domid}`);

	const submit_on = id__btn.querySelector("input");
	submit_on.name = submit_on.name.replace("joindre_", ""); //desactiver

	const hidden_focus = document.createElement("input");
	hidden_focus.type = "hidden";
	hidden_focus.name = "methode_focus";
	hidden_focus.id = hidden_focus.name;
	hidden_focus.value = "joindre";

	const hidden_on = document.createElement("input");
	hidden_on.type = "hidden";
	hidden_on.name = `joindre_${methode}`;
	hidden_on.value = submit_on.name ?? 1;

	submit_defaut.innerHTML = "";
	submit_defaut.appendChild(hidden_focus);
	submit_defaut.appendChild(hidden_on);
};

const init_boutons_choix_joindre_document = () => {
	for (const btn of [
		...document.querySelectorAll(".bouton_choix_joindre:not([data-loaded])"),
	]) {
		const data = JSON.parse(btn?.dataset?.methode);
		btn.addEventListener("click", (e) => {
			change_methode(data.domid, data.methode);
		});
		btn.setAttribute("data-loaded", true); // une seule fois
	}
};

init_boutons_choix_joindre_document();
onAjaxLoad(init_boutons_choix_joindre_document);

</script>
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -9,7 +9,7 @@
	]
	<span class="image_loading"></span>
	[<div class="reponse_formulaire reponse_formulaire_ok" role="status">(#ENV**{message_ok})</div>]
	[<p class="reponse_formulaire reponse_formulaire_erreur" role="alert">(#ENV**{message_erreur})</p>]
	[<div class="reponse_formulaire reponse_formulaire_erreur" role="alert">(#ENV**{message_erreur})</div>]
	
	<form action="#ENV{action}#formulaire_joindre_document-#ENV{id,new}" method="post" enctype='multipart/form-data'><div>
		#ACTION_FORMULAIRE
@@ -18,6 +18,7 @@
		
	</div></form>
</div>]
[(#ENV{_galerie,''}|oui)
		[(#INCLURE{fond=#ENV{_galerie}|spip_sanitize_from_request{_galerie,vide}, env, ajax})]
[(#REM) @deprecated 4.0 - SPIP 4.1 ]
[(#ENV{_galerie,''}|joindre_document_galerie_valide|oui)
		[(#INCLURE{fond=#ENV{_galerie}, env, ajax})]
]
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

/**
 * Gestion du formulaire de téléversement de documents
@@ -28,7 +27,7 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 *    L'identifiant numérique du document à remplacer ou "new" par défaut
 * @param string $objet
 *    Le type d'objet sur lequel ajouter le document
 * @return string $mode
 * @return string
 *    Le mode définitif
 */
function joindre_determiner_mode($mode, $id_document, $objet) {
@@ -36,10 +35,11 @@ function joindre_determiner_mode($mode, $id_document, $objet) {
		if (intval($id_document)) {
			$mode = sql_getfetsel('mode', 'spip_documents', 'id_document=' . intval($id_document));
		}
		if (!in_array($mode, array('choix', 'document', 'image'))) {
		if (!in_array($mode, ['choix', 'document', 'image'])) {
			$mode = 'choix';
			if ($objet
				and !in_array(table_objet_sql($objet), explode(',', $GLOBALS['meta']['documents_objets']))) {
			if (
				$objet && !in_array(table_objet_sql($objet), explode(',', (string) $GLOBALS['meta']['documents_objets']))
			) {
				$mode = 'image';
			}
		}
@@ -48,6 +48,21 @@ function joindre_determiner_mode($mode, $id_document, $objet) {
	return $mode;
}

/**
 * Indique si une galerie demandée est valide
 *
 * @deprecated 4.0 (SPIP 4.1) L’inclusion de galerie est déprécié (non utilisé depuis SPIP 3.0). Préferez ajax_reload() après upload.
 * @global array medias_deprecated_liste_galeries Liste de chemins de fichiers depuis la racine SPIP autorisés.
 * @param string|null $galerie Le fichier de galerie désiré
 */
function joindre_document_galerie_valide(?string $galerie): bool {
	$galeries = [];
	if (isset($GLOBALS['medias_deprecated_liste_galeries']) && is_array($GLOBALS['medias_deprecated_liste_galeries'])) {
		$galeries = $GLOBALS['medias_deprecated_liste_galeries'];
	}
	return in_array($galerie, $galeries);
}

/**
 * Chargement du formulaire
 *
@@ -60,6 +75,7 @@ function joindre_determiner_mode($mode, $id_document, $objet) {
 * @param string $mode
 *    Le mode du document (auto,choix,document,image,vignette...), par défaut auto
 * @param string $galerie
 *    Deprecated 4.0 (SPIP 4.1)
 *    Passer optionnellement une galerie jointe au form, plus utilise nativement,
 *    on prefere la mise a jour apres upload par ajaxReload('documents')
 * @param bool|string $proposer_media
@@ -68,7 +84,7 @@ function joindre_determiner_mode($mode, $id_document, $objet) {
 * @param bool|string $proposer_ftp
 *    Doit on afficher le ftp ? par défaut oui
 *    Valeurs possibles si string : false,'non','no'.
 * @return array $valeurs
 * @return array
 *    Les valeurs chargées dans le formulaire
 */
function formulaires_joindre_document_charger_dist(
@@ -80,10 +96,9 @@ function formulaires_joindre_document_charger_dist(
	$proposer_media = true,
	$proposer_ftp = true
) {
	$valeurs = array();
	$valeurs = [];
	$mode = joindre_determiner_mode($mode, $id_document, $objet);


	$valeurs['id'] = $id_document;
	$valeurs['_mode'] = $mode;

@@ -107,12 +122,7 @@ function formulaires_joindre_document_charger_dist(

	# regarder si un choix d'upload FTP est vraiment possible
	if (
		$valeurs['proposer_ftp']
		and test_espace_prive() # ??
		and ($mode != 'image') and ($mode != 'vignette') # si c'est pour un document
		//AND !$vignette_de_doc
		// pas pour une vignette (NB: la ligne precedente suffit, mais si on la supprime il faut conserver ce test-ci)
		and $GLOBALS['flag_upload']
		$valeurs['proposer_ftp'] && test_espace_prive() && $mode != 'image' && $mode != 'vignette' # si c'est pour un document
	) {
		include_spip('inc/documents');
		if ($dir = determine_upload('documents')) {
@@ -120,21 +130,22 @@ function formulaires_joindre_document_charger_dist(
			$valeurs['_options_upload_ftp'] = joindre_options_upload_ftp($dir, $mode);
			// s'il n'y en a pas, on affiche un message d'aide
			// en mode document, mais pas en mode image
			if ($valeurs['_options_upload_ftp'] or ($mode == 'document' or $mode == 'choix')) {
			if ($valeurs['_options_upload_ftp'] || ($mode == 'document' || $mode == 'choix')) {
				$valeurs['_dir_upload_ftp'] = '<b>' . joli_repertoire($dir) . '</b>';
			}
		}
	}
	// On ne propose le FTP que si on a des choses a afficher
	$valeurs['proposer_ftp'] = ($valeurs['_options_upload_ftp'] or $valeurs['_dir_upload_ftp']);
	$valeurs['proposer_ftp'] = ($valeurs['_options_upload_ftp'] || $valeurs['_dir_upload_ftp']);

	if ($galerie) {
	/** @deprecated 4.0 (SPIP 4.1). Utiliser ajaxReload('documents') après upload */
	if ($galerie && joindre_document_galerie_valide($galerie)) {
		# passer optionnellement une galerie jointe au form
		# plus utilise nativement, on prefere la mise a jour
		# apres upload par ajaxReload('documents')
		$valeurs['_galerie'] = $galerie;
	}
	if ($objet and $id_objet) {
	if ($objet && $id_objet) {
		$valeurs['id_objet'] = $id_objet;
		$valeurs['objet'] = $objet;
		$valeurs['refdoc_joindre'] = '';
@@ -159,6 +170,7 @@ function formulaires_joindre_document_charger_dist(
 * @param string $mode
 *    Le mode du document (auto,choix,document,image,vignette...), par défaut auto
 * @param string $galerie
 *    Deprecated 4.0 (SPIP 4.1)
 *    Passer optionnellement une galerie jointe au form, plus utilise nativement,
 *    on prefere la mise a jour apres upload par ajaxReload('documents')
 * @param bool|string $proposer_media
@@ -167,7 +179,7 @@ function formulaires_joindre_document_charger_dist(
 * @param bool|string $proposer_ftp
 *    Doit on afficher le ftp ? par défaut oui
 *    Valeurs possibles si string : false,'non','no'.
 * @return array $erreurs
 * @return array
 *    Les erreurs éventuelles dans un tableau
 */
function formulaires_joindre_document_verifier_dist(
@@ -181,10 +193,10 @@ function formulaires_joindre_document_verifier_dist(
) {
	include_spip('inc/joindre_document');

	$erreurs = array();
	$erreurs = [];
	// on joint un document deja dans le site
	if (_request('joindre_mediatheque')) {
		$refdoc_joindre = intval(preg_replace(',^(doc|document|img),', '', _request('refdoc_joindre')));
		$refdoc_joindre = intval(preg_replace(',^(doc|document|img),', '', (string) _request('refdoc_joindre')));
		if (!sql_getfetsel('id_document', 'spip_documents', 'id_document=' . intval($refdoc_joindre))) {
			$erreurs['message_erreur'] = _T('medias:erreur_aucun_document');
		}
@@ -200,8 +212,9 @@ function formulaires_joindre_document_verifier_dist(
			} else {
				// regarder si on a eu une erreur sur l'upload d'un fichier
				foreach ($files as $file) {
					if (isset($file['error'])
						and $test = joindre_upload_error($file['error'])
					if (
						isset($file['error'])
						&& ($test = joindre_upload_error($file['error']))
					) {
						if (is_string($test)) {
							$erreurs['message_erreur'] = $test;
@@ -213,22 +226,23 @@ function formulaires_joindre_document_verifier_dist(

				// si ce n'est pas deja un post de zip confirme
				// regarder si il faut lister le contenu du zip et le presenter
				if (!count($erreurs)
					and !_request('joindre_zip')
					and $contenu_zip = joindre_verifier_zip($files)
				if (
					!count($erreurs)
					&& !_request('joindre_zip')
					&& ($contenu_zip = joindre_verifier_zip($files))
				) {
					list($fichiers, $erreurs, $tmp_zip) = $contenu_zip;
					[$fichiers, $erreurs, $tmp_zip] = $contenu_zip;
					if ($fichiers) {
						// on passe le md5 du fichier uniquement, on le retrouvera dans zip_to_clean de la session
						$token_zip = md5($tmp_zip);
						$token_zip = md5((string) $tmp_zip);
						$erreurs['message_erreur'] = '';
						$erreurs['lister_contenu_archive'] = recuperer_fond(
							'formulaires/inc-lister_archive_jointe',
							array(
							[
								'chemin_zip' => $token_zip,
								'liste_fichiers_zip' => $fichiers,
								'erreurs_fichier_zip' => $erreurs
							)
								'erreurs_fichier_zip' => $erreurs,
							]
						);
					} else {
						$erreurs['message_erreur'] = _T('medias:erreur_aucun_fichier');
@@ -237,7 +251,7 @@ function formulaires_joindre_document_verifier_dist(
			}
		}

		if (count($erreurs) and defined('_TMP_DIR')) {
		if (count($erreurs) && defined('_TMP_DIR')) {
			effacer_repertoire_temporaire(_TMP_DIR);
		}
	}
@@ -257,6 +271,7 @@ function formulaires_joindre_document_verifier_dist(
 * @param string $mode
 *    Le mode du document (auto,choix,document,image,vignette...), par défaut auto
 * @param string $galerie
 *    Deprecated 4.0 (SPIP 4.1)
 *    Passer optionnellement une galerie jointe au form, plus utilise nativement,
 *    on prefere la mise a jour apres upload par ajaxReload('documents')
 * @param bool|string $proposer_media
@@ -265,7 +280,7 @@ function formulaires_joindre_document_verifier_dist(
 * @param bool|string $proposer_ftp
 *    Doit on afficher le ftp ? par défaut oui
 *    Valeurs possibles si string : false,'non','no'.
 * @return array $res
 * @return array
 *    Le tableau renvoyé par les CVT avec le message et editable
 */
function formulaires_joindre_document_traiter_dist(
@@ -277,24 +292,24 @@ function formulaires_joindre_document_traiter_dist(
	$proposer_media = true,
	$proposer_ftp = true
) {
	$res = array('editable' => true);
	$res = ['editable' => true];
	$ancre = '';
	// on joint un document deja dans le site
	if (_request('joindre_mediatheque')) {
		$sel = array();
		$sel = [];
		$refdoc_joindre = _request('refdoc_joindre');
		$refdoc_joindre = strtr($refdoc_joindre, ';,', '  ');
		$refdoc_joindre = preg_replace(',\b(doc|document|img),', '', $refdoc_joindre);
		// expliciter les intervales xxx-yyy
		while (preg_match(",\b(\d+)-(\d+)\b,", $refdoc_joindre, $m)) {
		while (preg_match(",\b(\d+)-(\d+)\b,", (string) $refdoc_joindre, $m)) {
			$refdoc_joindre = str_replace($m[0], implode(' ', range($m[1], $m[2])), $refdoc_joindre);
		}
		$refdoc_joindre = explode(' ', $refdoc_joindre);
		$refdoc_joindre = explode(' ', (string) $refdoc_joindre);
		include_spip('action/editer_document');
		foreach ($refdoc_joindre as $j) {
			if ($j = intval(preg_replace(',^(doc|document|img),', '', $j))) {
				// lier le parent en plus
				$champs = array('ajout_parents' => array("$objet|$id_objet"));
				$champs = ['ajout_parents' => ["$objet|$id_objet"]];
				document_modifier($j, $champs);
				if (!$ancre) {
					$ancre = $j;
@@ -329,14 +344,14 @@ function formulaires_joindre_document_traiter_dist(
		}

		// checker les erreurs eventuelles
		$messages_erreur = array();
		$sel = array();
		$messages_erreur = [];
		$sel = [];
		foreach ($nouveaux_doc as $doc) {
			if (!is_numeric($doc)) {
				$messages_erreur[] = $doc;
			} // cas qui devrait etre traite en amont
			elseif (!$doc) {
				$messages_erreur[] = _T('medias:erreur_insertion_document_base', array('fichier' => '<em>???</em>'));
				$messages_erreur[] = _T('medias:erreur_insertion_document_base', ['fichier' => '<em>???</em>']);
			} else {
				if (!$ancre) {
					$ancre = $doc;
@@ -358,7 +373,7 @@ function formulaires_joindre_document_traiter_dist(
			$res['redirect'] = "#doc$ancre";
		}
	}
	if (count($sel) or isset($res['message_ok'])) {
	if (count($sel) || isset($res['message_ok'])) {
		$callback = '';
		if ($ancre) {
			$callback .= "jQuery('#doc$ancre a.editbox').eq(0).focus();";
@@ -389,21 +404,21 @@ function formulaires_joindre_document_traiter_dist(
 *    Le répertoire de recherche des documents
 * @param string $mode
 *    Le mode d'ajout de document
 * @return string $texte
 * @return string
 *    Le contenu HTML du selecteur de documents
 */
function joindre_options_upload_ftp($dir, $mode = 'document') {
	$fichiers = preg_files($dir);
	$exts = $dirs = $texte_upload = array();
	$exts = $dirs = $texte_upload = [];

	// en mode "charger une image", ne proposer que les inclus
	$inclus = ($mode == 'image' or $mode == 'vignette')
	$inclus = ($mode == 'image' || $mode == 'vignette')
		? " AND inclus='image'"
		: '';

	foreach ($fichiers as $f) {
		$f = preg_replace(",^$dir,", '', $f);
		if (preg_match(',\.([^.]+)$,', $f, $match)) {
		if (preg_match(',\.([^.]+)$,', (string) $f, $match)) {
			$ext = strtolower($match[1]);
			if (!isset($exts[$ext])) {
				include_spip('action/ajouter_documents');
@@ -415,17 +430,17 @@ function joindre_options_upload_ftp($dir, $mode = 'document') {
				}
			}

			$k = 2 * substr_count($f, '/');
			$n = strrpos($f, '/');
			$k = 2 * substr_count((string) $f, '/');
			$n = strrpos((string) $f, '/');
			if ($n === false) {
				$lefichier = $f;
			} else {
				$lefichier = substr($f, $n + 1, strlen($f));
				$ledossier = substr($f, 0, $n);
				$lefichier = substr((string) $f, $n + 1, strlen((string) $f));
				$ledossier = substr((string) $f, 0, $n);
				if (!in_array($ledossier, $dirs)) {
					$texte_upload[] = "\n<option value=\"$ledossier\">"
					$texte_upload[] = "\n<option value=\"$ledossier/\">"
						. str_repeat('&nbsp;', $k)
						. _T('medias:tout_dossier_upload', array('upload' => $ledossier))
						. _T('medias:tout_dossier_upload', ['upload' => $ledossier])
						. '</option>';
					$dirs[] = $ledossier;
				}
@@ -450,13 +465,12 @@ function joindre_options_upload_ftp($dir, $mode = 'document') {
	return $texte;
}


/**
 * Lister les fichiers contenus dans un zip
 *
 * @param array $files
 *    La liste des fichiers
 * @return string $res
 * @return string
 *    La liste HTML des fichiers <li>...</li>
 */
function joindre_liste_contenu_tailles_archive($files) {
@@ -481,7 +495,7 @@ function joindre_liste_contenu_tailles_archive($files) {
 *
 * @param array $erreurs
 *    La liste des erreurs
 * @return string $res
 * @return string
 *    Le code HTML des erreurs
 */
function joindre_liste_erreurs_to_li($erreurs) {
@@ -496,7 +510,7 @@ function joindre_liste_erreurs_to_li($erreurs) {
	if (count($erreurs) > 4) {
		$res = "<p style='cursor:pointer;' onclick='jQuery(this).siblings(\"ul\").toggle();return false;'>" . _T(
			'medias:erreurs_voir',
			array('nb' => count($erreurs))
			['nb' => count($erreurs)]
		) . '</p><ul class="spip none-js">' . $res . '</ul>';
	} else {
		$res = "<ul class=\"spip\">$res</ul>";
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<div class="editer-groupe">
    <div class='editer editer_url[ (#ENV**{erreurs}|table_valeur{url}|oui)erreur]'>
    <div class='editer editer_url[ (#ENV*{erreurs/url}|oui)erreur]'>
        <label for='url#ENV{domid}'><:medias:info_referencer_doc_distant:></label>[
        <span class='erreur_message'>(#ENV**{erreurs}|table_valeur{url})</span>
        ]<input class='text' placeholder="http://" type="text" name="url" value='#ENV{url}' id="url#ENV{domid}"/>
        <span class='erreur_message'>(#ENV*{erreurs/url})</span>
        ]<input class='text' placeholder="https://" type="text" name="url" value='#ENV{url}' id="url#ENV{domid}"/>
        <!--editer_url-->
    </div>
</div>
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<div class="editer-groupe">
    [<div class='editer editer_cheminftp[ (#ENV**{erreurs}|table_valeur{cheminftp}|oui)erreur]'>
    [<div class='editer editer_cheminftp[ (#ENV*{erreurs/cheminftp}|oui)erreur]'>
        <label for='cheminftp#ENV{domid}'>[(#VAL{info_selectionner_fichier}|_T{#ARRAY{upload,#ENV*{_dir_upload_ftp}}})]</label>[
        <span class='erreur_message'>(#ENV**{erreurs}|table_valeur{cheminftp})</span>
        <span class='erreur_message'>(#ENV*{erreurs/cheminftp})</span>
        ]<select name='cheminftp' id='cheminftp#ENV{domid}' size='1'>
        <option value=''>&gt;&gt;</option>
        (#ENV*{_options_upload_ftp})
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<div class="editer-groupe">
    <div class='editer editer_refdoc_joindre[ (#ENV**{erreurs}|table_valeur{refdoc_joindre}|oui)erreur]'>
    <div class='editer editer_refdoc_joindre[ (#ENV*{erreurs/refdoc_joindre}|oui)erreur]'>
        <label for='refdoc_joindre#ENV{domid}'><:medias:label_refdoc_joindre:></label>[
        <span class='erreur_message'>(#ENV**{erreurs}|table_valeur{refdoc_joindre})</span>
        <span class='erreur_message'>(#ENV*{erreurs/refdoc_joindre})</span>
        ]<input class='text' type="text" name="refdoc_joindre" value='#ENV{refdoc_joindre}' id="refdoc_joindre#ENV{domid}"/>
        <input class='btn submit' type="button" name="parcourir" value="<:medias:bouton_parcourir:>"
            onclick="jQuery.modalboxload('#URL_ECRIRE{popin-choisir_document,var_zajax=contenu&selectfunc=mediaselect#ENV{domid}}',{autoResize: true});"
@@ -9,6 +9,6 @@
        <!--editer_refdoc_joindre-->
    </div>
</div>
<script type="text/javascript">/*<!\[CDATA\[*/
<script>
function mediaselect#ENV{domid}(id){jQuery.modalboxclose();jQuery("#refdoc_joindre#ENV{domid}").attr('value','doc'+id).focus();jQuery('#joindre_mediatheque#ENV{domid}>.boutons input').get(0).click();}
/*\]\]>*/</script>
 No newline at end of file
</script>
 No newline at end of file
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<div class="editer-groupe">
    <div class='editer editer_fichier_upload[ (#ENV**{erreurs}|table_valeur{fichier_upload}|oui)erreur]'>
    <div class='editer editer_fichier_upload[ (#ENV*{erreurs/fichier_upload}|oui)erreur]'>
        <label for='fichier_upload#ENV{domid}'><:bouton_upload:></label>[
        <span class='erreur_message'>(#ENV**{erreurs}|table_valeur{fichier_upload})</span>
        <span class='erreur_message'>(#ENV*{erreurs/fichier_upload})</span>
        ]<input class='file[(#ENV{multi}|=={non}|non) multi]' type="file" name="fichier_upload[]" value='[(#ENV{fichier_upload}|is_array|?{'', #ENV{fichier_upload}})]' id="fichier_upload#ENV{domid}" size='11' />
        <!--editer_fichier_upload-->
    </div>
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?php

/**
 * Tache de nettoyages du répertoire tmp/upload
 *
 * @plugin     Medias
 * @licence    GNU/GPL
 * @package    SPIP\Medias\Genie
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

/**
 * Enlève les fichiers trop vieux du répertoire tmp/upload
 *
 * @param int $last
 * @return int
 **/
function genie_medias_nettoyer_repertoire_upload_dist($last) {
	include_spip('inc/invalideur');
	purger_repertoire(_DIR_TMP . 'upload', [
		'mtime' => time() - 180 * 24 * 3600,
		'subdir' => true,
	]);
	return 1;
}
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.
 */

/**
 * Gestion des modes de documents
 *
 * @package SPIP\Medias\Mime_type
 */
if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

function inc_calculer_mime_type_application_mp4_dist(int $id_document, string $extension, string $mime_type) {

	$media = sql_getfetsel('media', 'spip_documents', 'id_document=' . intval($id_document));
	if (in_array($media, ['audio', 'video'])) {
		$mime_type = str_replace('application/', $media . '/', $mime_type);
		return $mime_type;
	}
	return null;
}

inc/chercher_logo.php

0 → 100644
+61 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.
 */

/**
 * Recherche de logo
 *
 * @package SPIP\Core\Logos
 */
if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

/**
 * Cherche le logo d'un élément d'objet
 *
 * @param int $id
 *     Identifiant de l'objet
 * @param string $_id_objet
 *     Nom de la clé primaire de l'objet
 * @param string $mode
 *     Mode de survol du logo désiré (on ou off)
 * @param bool $compat_old_logos (unused) @deprecated 5.0
 * @return array
 *     - Liste (chemin complet du fichier, répertoire de logos, nom du logo, extension du logo, date de modification[, doc])
 *     - array vide aucun logo trouvé.
 */
function inc_chercher_logo_dist(
	int $id,
	string $_id_objet,
	string $mode = 'on',
	bool $compat_old_logos = false
): array {

	$mode = preg_replace(',\W,', '', $mode);
	if ($mode) {
		// chercher dans la base
		$mode_document = 'logo' . $mode;
		$objet = objet_type($_id_objet);
		$doc = sql_fetsel(
			'D.*',
			'spip_documents AS D JOIN spip_documents_liens AS L ON L.id_document=D.id_document',
			'D.mode=' . sql_quote($mode_document) . ' AND L.objet=' . sql_quote($objet) . ' AND id_objet=' . $id
		);
		if ($doc) {
			include_spip('inc/documents');
			$d = get_spip_doc($doc['fichier']);
			return [$d, _DIR_IMG, basename($d), $doc['extension'], @filemtime($d), $doc];
		}
	}

	# coherence de type pour servir comme filtre (formulaire_login)
	return [];
}
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

/**
 * Gestion des modes de documents
@@ -34,16 +33,15 @@ if (!defined('_ECRIRE_INC_VERSION')) {
function inc_choisir_mode_document($infos, $type_inclus_image, $objet) {

	// si ce n'est pas une image, c'est forcement un document
	if (!$infos['type_image'] or !$type_inclus_image) {
	if (!$infos['type_image'] || !$type_inclus_image) {
		return 'document';
	}

	// si on a pas le droit d'ajouter de document a l'objet, c'est donc un mode image
	if ($objet and isset($GLOBALS['meta']["documents_$objet"]) and ($GLOBALS['meta']["documents_$objet"] == 'non')) {
	if ($objet && isset($GLOBALS['meta']["documents_$objet"]) && $GLOBALS['meta']["documents_$objet"] == 'non') {
		return 'image';
	}


	// _INTERFACE_DOCUMENTS
	// en fonction de la taille de l'image
	// par defaut l'affectation en fonction de la largeur de l'image
@@ -57,11 +55,11 @@ function inc_choisir_mode_document($infos, $type_inclus_image, $objet) {
		return 'image';
	}

	if ($infos['largeur'] > 0
		and $infos['largeur'] < _LARGEUR_MODE_IMAGE
	if (
		$infos['largeur'] > 0 && $infos['largeur'] < _LARGEUR_MODE_IMAGE
	) {
		return 'image';
	} else {
		return 'document';
	}
	return 'document';

}
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

/**
 * Gestion des modes de documents
@@ -42,34 +41,32 @@ function inc_determiner_statut_document($id_document, $statut_ancien, $date_publ
	while ($row = sql_fetch($res)) {
		if (
			// si ce n'est pas un logo
			!in_array($row['mode'], array('logoon','logooff'))
			and (
				// cas particulier des rubriques qui sont publiees des qu'elles contiennent un document !
				$row['objet'] == 'rubrique'
				// ou si objet publie selon sa declaration
				or objet_test_si_publie($row['objet'], $row['id_objet'])
			)
			!in_array($row['mode'], ['logoon', 'logooff']) && ($row['objet'] == 'rubrique' || objet_test_si_publie(
				$row['objet'],
				$row['id_objet']
			))
		) {
			$statut = 'publie';
			$date_publication = 0;
			continue;
		} // si pas publie, et article, il faut checker la date de post-publi eventuelle
		elseif ($row['objet'] == 'article'
			and $row2 = sql_fetsel(
		elseif (
			$row['objet'] == 'article'
			&& ($row2 = sql_fetsel(
				'date',
				'spip_articles',
				'id_article=' . intval($row['id_objet']) . " AND statut='publie'"
			)
			))
		) {
			$statut = 'publie';
			$date_publication = min($date_publication, strtotime($row2['date']));
			$date_publication = min($date_publication, strtotime((string) $row2['date']));
		}
	}
	$date_publication = date('Y-m-d H:i:s', $date_publication);
	if ($statut == 'publie' and $statut_ancien == 'publie' and $date_publication == $date_publication_ancienne) {
	if ($statut == 'publie' && $statut_ancien == 'publie' && $date_publication == $date_publication_ancienne) {
		return false;
	}
	if ($statut != 'publie' and $statut_ancien != 'publie' and $statut_ancien != '0') {
	if ($statut != 'publie' && $statut_ancien != 'publie' && $statut_ancien != '0') {
		return false;
	}

Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

/**
 * Calcul du portfolio / liste de documents de l'espace privé
 *
 * @package SPIP\Medias\Fonctions
 **/

 */
if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}
@@ -31,7 +29,7 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 * @param int $id Identifiant de l'objet
 * @param string $type Type d'objet
 * @return string code HTML
 **/
 */
function inc_documenter_objet_dist($id, $type) {
	$serveur = '';

@@ -39,12 +37,16 @@ function inc_documenter_objet_dist($id, $type) {
	$spip_table_objet = table_objet_sql($type);
	$table_objet = table_objet($type);
	$id_table_objet = id_table_objet($type, $serveur);
	$champs = sql_fetsel('*', $spip_table_objet, addslashes($id_table_objet) . '=' . intval($id));
	$champs = sql_fetsel('*', $spip_table_objet, addslashes((string) $id_table_objet) . '=' . intval($id));

	$marquer_doublons_doc = charger_fonction('marquer_doublons_doc', 'inc');
	$marquer_doublons_doc($champs, $id, $type, $id_table_objet, $table_objet, $spip_table_objet, '', $serveur);

	$contexte = array('objet' => $type, 'id_objet' => $id);
	$contexte = [
		'objet' => $type,
		'id_objet' => $id,
		'espace_prive' => test_espace_prive(),
	];

	return recuperer_fond('prive/objets/contenu/portfolio_document', array_merge($_GET, $contexte));
}
+170 −50
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
@@ -25,10 +24,137 @@ if (!defined('CHARSET_JOINT')) {
	define('CHARSET_JOINT', 'iso-8859-1');
}

/**
 * Donne le chemin du fichier relatif à `_DIR_IMG`
 * pour stockage 'tel quel' dans la base de données
 *
 * @uses _DIR_IMG
 */
function set_spip_doc(?string $fichier): string {
	if ($fichier && str_starts_with($fichier, (string) _DIR_IMG)) {
		return substr($fichier, strlen((string) _DIR_IMG));
	}
	// ex: fichier distant
	return $fichier ?? '';

}

/**
 * Donne le chemin complet du fichier
 *
 * @uses _DIR_IMG
 *
 * @return bool|string
 */
function get_spip_doc(?string $fichier) {
	$fichier_demande = $fichier;

	if ($fichier === null) {
		return false;
	}

	// fichier distant
	if (tester_url_absolue($fichier)) {
		return $fichier;
	}

	// gestion d'erreurs, fichier=''
	if (!strlen($fichier)) {
		return false;
	}

	if (!str_starts_with($fichier, (string) _DIR_IMG)) {
		$fichier = _DIR_IMG . $fichier;
	}

	$fichier = pipeline('get_spip_doc', [
		'args' => [
			'fichier' => $fichier_demande,
		],
		'data' => $fichier,
	]);

	// fichier normal
	return $fichier;
}

/**
 * Copier un document `$source`
 * dans un dossier `IMG/$ext/$orig.$ext` ou `IMG/$subdir/$orig.$ext` si `$subdir` est fourni
 * en numérotant éventuellement si un fichier de même nom existe déjà
 *
 * @param string $ext
 * @param string $orig
 * @param string $source
 * @param string $subdir
 * @return bool|mixed|string
 */
function copier_document($ext, $orig, $source, $subdir = null) {

	$orig = preg_replace(',\.\.+,', '.', $orig); // pas de .. dans le nom du doc
	$dir = creer_repertoire_documents($subdir ?: $ext);

	$dest = preg_replace('/<[^>]*>/', '', basename($orig));
	$dest = preg_replace('/\.([^.]+)$/', '', $dest);
	$dest = translitteration($dest);
	$dest = preg_replace('/[^.=\w-]+/', '_', (string) $dest);

	// ne pas accepter de noms de la forme -r90.jpg qui sont reserves
	// pour les images transformees par rotation (action/documenter)
	$dest = preg_replace(',-r(90|180|270)$,', '', $dest);

	while (preg_match(',\.(\w+)$,', $dest, $m)) {
		if (
			!function_exists('verifier_upload_autorise')
			|| !($r = verifier_upload_autorise($dest))
			|| !empty($r['autozip'])
		) {
			$dest = substr($dest, 0, -strlen($m[0])) . '_' . $m[1];
			break;
		}
		$dest = substr($dest, 0, -strlen($m[0]));
		$ext = $m[1] . '.' . $ext;

	}

	// Si le document "source" est deja au bon endroit, ne rien faire
	if ($source == ($dir . $dest . '.' . $ext)) {
		return $source;
	}

	// sinon tourner jusqu'a trouver un numero correct
	$n = 0;
	while (@file_exists($newFile = $dir . $dest . ($n++ ? ('-' . $n) : '') . '.' . $ext)) {

	}

	return deplacer_fichier_upload($source, $newFile);
}

/**
 * Efface le répertoire de manière récursive !
 *
 * @param string $nom
 */
function effacer_repertoire_temporaire($nom) {
	if ($d = opendir($nom)) {
		while (($f = readdir($d)) !== false) {
			if (is_file("$nom/$f")) {
				spip_unlink("$nom/$f");
			} else {
				if ($f != '.' && $f != '..' && is_dir("$nom/$f")) {
					effacer_repertoire_temporaire("$nom/$f");
				}
			}
		}
	}
	closedir($d);
	@rmdir($nom);
}

// Filtre pour #FICHIER permettant d'incruster le contenu d'un document
// Si 2e arg fourni, conversion dans le charset du site si possible

// https://code.spip.net/@contenu_document
function contenu_document($arg, $charset = '') {
	include_spip('inc/distant');
	if (is_numeric($arg)) {
@@ -53,7 +179,7 @@ function contenu_document($arg, $charset = '') {
		include_spip('inc/charsets');
		if ($charset !== 'auto') {
			$r = importer_charset($r, $charset);
		} elseif ($GLOBALS['meta']['charset'] == 'utf-8' and !is_utf8($r)) {
		} elseif ($GLOBALS['meta']['charset'] == 'utf-8' && !is_utf8($r)) {
			$r = importer_charset($r, CHARSET_JOINT);
		}
	}
@@ -61,11 +187,11 @@ function contenu_document($arg, $charset = '') {
	return $r;
}

// https://code.spip.net/@generer_url_document_dist
function generer_url_document_dist($id_document, $args = '', $ancre = '') {

	include_spip('inc/autoriser');
	if (!autoriser('voir', 'document', $id_document)) {
	// si on a pas le droit de voir le document, meme via le htaccess
	if (!autoriser('voir', 'document', $id_document, null, ['htaccess' => true])) {
		return '';
	}

@@ -81,10 +207,9 @@ function generer_url_document_dist($id_document, $args = '', $ancre = '') {
		return $f;
	}

	// Si droit de voir tous les docs, pas seulement celui-ci
	// Si droit de voir tous les docs, sans htaccess, pas seulement celui-ci
	// il est inutilement couteux de rajouter une protection
	$r = (autoriser('voir', 'document'));
	if (($r and $r !== 'htaccess')) {
	if (autoriser('voir', 'document')) {
		return get_spip_doc($f);
	}

@@ -97,7 +222,7 @@ function generer_url_document_dist($id_document, $args = '', $ancre = '') {
			. 'arg=' . $id_document
			. ($ancre ? "&ancre=$ancre" : '')
			. '&cle=' . calculer_cle_action($id_document . ',' . $f)
			. '&file=' . rawurlencode($f),
			. '&file=' . rawurlencode((string) $f),
		true,
		true
	);
@@ -116,38 +241,32 @@ function vignette_automatique($img, $doc, $lien, $x = 0, $y = 0, $align = '', $c
	include_spip('inc/distant');
	include_spip('inc/texte');
	include_spip('inc/filtres_images_mini');
	if (is_null($class)) {
	if ($class === null) {
		$class = 'spip_logo spip_logos';
	}
	$e = $doc['extension'];
	$e = $doc['extension'] ?? null;
	if (!$img) {
		if ($img = image_du_document($doc, $connect)) {
			if (!$x and !$y) {
				// eviter une double reduction
				$img = image_reduire($img);
		$img = image_du_document($doc, $connect);
	}
		} else {
	if (!$img) {
		$f = charger_fonction('vignette', 'inc');
			$img = $f($e, false);
			$size = @spip_getimagesize($img);
			$img = "<img src='$img' " . $size[3] . ' />';
			$class .= " spip_document_icone";
		$img = $f($e, $doc['media'] ?? '');
		$class .= ' spip_document_icone';
	}
	} else {
	$size = @spip_getimagesize($img);
		$img = "<img src='$img' " . $size[3] . ' />';
	}
	$img = "<img src='".attribut_url(timestamp($img))."' " . ($size[3] ?? '') . ' />';

	// on appelle image_reduire independamment de la presence ou non
	// des librairies graphiques
	// la fonction sait se debrouiller et faire de son mieux dans tous les cas
	if ($x or $y) {
	if ($x || $y) {
		$img = image_reduire($img, $x, $y);
	}
	$img = inserer_attribut($img, 'alt', '');
	$img = inserer_attribut($img, 'class', trim($class));
	if ($align) {
		$img = inserer_attribut($img, 'align', $align);
		$class .= " spip_logo_$align";
	}
	$img = inserer_attribut($img, 'class', trim((string) $class));

	if (!$lien) {
		return $img;
@@ -162,7 +281,7 @@ function vignette_automatique($img, $doc, $lien, $x = 0, $y = 0, $align = '', $c
	$mime = $type['mime_type'];
	$titre = attribut_html(couper($type['titre'] . $titre, 80));

	return "<a href='$lien' type='$mime' title='$titre'>$img</a>";
	return "<a href='".attribut_url($lien)."' type='$mime' title='$titre'>$img</a>";
}

/**
@@ -180,12 +299,13 @@ function vignette_automatique($img, $doc, $lien, $x = 0, $y = 0, $align = '', $c
 * @return string Chemin de l’image
 */
function image_du_document($document, $connect = null) {
	if ($e = $document['extension']
		and in_array($e, formats_image_acceptables())
		and (!test_espace_prive() or $GLOBALS['meta']['creer_preview'] == 'oui')
		and $document['fichier']
	if (
		($e = $document['extension'] ?? null)
		&& in_array($e, formats_image_acceptables())
		&& (!test_espace_prive() || $GLOBALS['meta']['creer_preview'] == 'oui')
		&& $document['fichier']
	) {
		include_spip('inc/quete');
		include_spip('public/quete_document');
		if ($document['distant'] == 'oui') {
			$image = _DIR_RACINE . copie_locale($document['fichier']);
		} elseif ($image = document_spip_externe($document['fichier'], $connect)) {
@@ -218,7 +338,7 @@ function image_du_document($document, $connect = null) {
 *
 * @return string
 *    Texte du raccourcis
 **/
 */
function affiche_raccourci_doc($doc, $id, $align = '', $short = false) {

	$pipe = '';
@@ -229,16 +349,16 @@ function affiche_raccourci_doc($doc, $id, $align = '', $short = false) {
	$model = "&lt;$doc$id$pipe&gt;";
	$text = $model;
	if ($short) {
		$text = $align ? $align : $model;
		$text = $align ?: $model;
	}

	$classes = "btn btn_link btn_mini";
	$classes = 'btn btn_link btn_mini';
	$classes = " class=\"$classes\"";

	$styles = '';
	if ($align && !$short) {
		// a priori ne sert plus de toutes façons…
		$styles = "text-align: " . ($align ?: 'center') . ";";
		$styles = 'text-align: ' . ($align ?: 'center') . ';';
		$styles = " style=\"$styles\"";
	}

Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

/**
 * Gère un cas d'upload trop gros
@@ -17,7 +16,7 @@
 * Mais fonction utilisée encore dans medias_detecter_fond_par_defaut()
 *
 * @package SPIP\Medias\Upload
 **/
 */

#
# Fichier obsolete, a supprimer
@@ -32,7 +31,6 @@ include_once _DIR_RESTREINT . 'inc/documents.php';

include_spip('inc/minipres');


/**
 * Traite l'erreur d'un upload trop gros
 *
@@ -40,8 +38,8 @@ include_spip('inc/minipres');
 * et affiche un minipres avec la taille limite de documents possibles
 *
 * @see minipres()
 **/
function erreur_upload_trop_gros() {
 */
function erreur_upload_trop_gros(): never {
	include_spip('inc/filtres');

	$msg = '<p>'
@@ -49,7 +47,7 @@ function erreur_upload_trop_gros() {
		. '<br />'
		. _T(
			'medias:upload_limit',
			array('max' => ini_get('upload_max_filesize'))
			['max' => ini_get('upload_max_filesize')]
		)
		. '</p>';

Fichier modifié.

La taille limite d'aperçu a été dépassée, l'affichage des modifications a donc été réduit.

Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/
/**
 * 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.
 */

/**
 * Analyse des textes pour trouver et marquer comme vu les documents utilisés dedans
 *
 * @package SPIP\Medias\Fonctions
 **/

 */
if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}
@@ -58,7 +56,7 @@ $GLOBALS['medias_liste_champs'][] = 'chapo';
 * @param string $serveur
 *     Serveur sql utilisé.
 * @return void|null
 **/
 */
function inc_marquer_doublons_doc_dist(
	$champs,
	$id,
@@ -66,7 +64,7 @@ function inc_marquer_doublons_doc_dist(
	$id_table_objet,
	$table_objet,
	$spip_table_objet,
	$desc = array(),
	$desc = [],
	$serveur = ''
) {

@@ -84,11 +82,11 @@ function inc_marquer_doublons_doc_dist(
	// Il faut récupérer toutes les données qui impactent les liens de documents vus
	// afin de savoir lesquels sont présents dans les textes, et pouvoir actualiser avec
	// les liens actuellement enregistrés.
	$absents = array();
	$absents = [];

	// Récupérer chaque champ impactant qui existe dans la table de l'objet et qui nous manque
	foreach ($GLOBALS['medias_liste_champs'] as $champ) {
		if (isset($desc['field'][$champ]) and !isset($champs[$champ])) {
		if (isset($desc['field'][$champ]) && !isset($champs[$champ])) {
			$absents[] = $champ;
		}
	}
@@ -111,24 +109,24 @@ function inc_marquer_doublons_doc_dist(
	$modeles = $modeles['modeles'];

	// liste d'id_documents trouvés dans les textes
	$GLOBALS['doublons_documents_inclus'] = array();
	$GLOBALS['doublons_documents_inclus'] = [];

	// detecter les doublons dans ces textes
	traiter_modeles(implode(' ', $champs), array('documents' => $modeles), '', '', null, array(
	traiter_modeles(implode(' ', $champs), ['documents' => $modeles], '', '', null, [
		'objet' => $type,
		'id_objet' => $id,
		$id_table_objet => $id
	));
		$id_table_objet => $id,
	]);

	$texte_documents_vus = $GLOBALS['doublons_documents_inclus'];

	// on ne modifie les liaisons que si c'est nécessaire
	$bdd_documents_vus = array(
		'oui' => array(),
		'non' => array()
	);
	$bdd_documents_vus = [
		'oui' => [],
		'non' => [],
	];

	$liaisons = objet_trouver_liens(array('document' => '*'), array($type => $id));
	$liaisons = objet_trouver_liens(['document' => '*'], [$type => $id]);
	foreach ($liaisons as $l) {
		$bdd_documents_vus[$l['vu']][] = $l['id_document'];
	}
@@ -145,12 +143,12 @@ function inc_marquer_doublons_doc_dist(
		$ids = array_column($ids, 'id_document');
		if ($ids) {
			// Creer le lien s'il n'existe pas déjà
			objet_associer(array('document' => $ids), array($type => $id), array('vu' => 'oui'));
			objet_qualifier_liens(array('document' => $ids), array($type => $id), array('vu' => 'oui'));
			objet_associer(['document' => $ids], [$type => $id], ['vu' => 'oui']);
			objet_qualifier_liens(['document' => $ids], [$type => $id], ['vu' => 'oui']);
		}
	}

	if ($anciens) {
		objet_qualifier_liens(array('document' => $anciens), array($type => $id), array('vu' => 'non'));
		objet_qualifier_liens(['document' => $anciens], [$type => $id], ['vu' => 'non']);
	}
}

Fichier modifié.

La taille limite d'aperçu a été dépassée, l'affichage des modifications a donc été réduit.

Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/

/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
@@ -17,12 +17,12 @@ function inc_verifier_document_mode_image_dist($infos) {

	// Si on veut uploader une image, il faut qu'elle ait ete bien lue
	if ($infos['inclus'] != 'image') {
		return _T('medias:erreur_format_fichier_image', array('nom' => $infos['fichier']));
		return _T('medias:erreur_format_fichier_image', ['nom' => $infos['fichier']]);
	}

	if (isset($infos['largeur']) and isset($infos['hauteur'])) {
		if (!($infos['largeur'] or $infos['hauteur'])) {
			return _T('medias:erreur_upload_vignette', array('nom' => $infos['fichier']));
	if (isset($infos['largeur']) && isset($infos['hauteur'])) {
		if (!($infos['largeur'] || $infos['hauteur'])) {
			return _T('medias:erreur_upload_vignette', ['nom' => $infos['fichier']]);
		}
	}

Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?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.   *
\***************************************************************************/

/**
 * 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.
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
@@ -17,12 +17,12 @@ function inc_verifier_document_mode_vignette_dist($infos) {

	// Si on veut uploader une vignette, il faut qu'elle ait ete bien lue
	if ($infos['inclus'] != 'image') {
		return _T('medias:erreur_format_fichier_image', array('nom' => $infos['fichier']));
		return _T('medias:erreur_format_fichier_image', ['nom' => $infos['fichier']]);
	}

	if (isset($infos['largeur']) and isset($infos['hauteur'])) {
		if (!($infos['largeur'] or $infos['hauteur'])) {
			return _T('medias:erreur_upload_vignette', array('nom' => $infos['fichier']));
	if (isset($infos['largeur']) && isset($infos['hauteur'])) {
		if (!($infos['largeur'] || $infos['hauteur'])) {
			return _T('medias:erreur_upload_vignette', ['nom' => $infos['fichier']]);
		}
	}

+43 −36

Fichier modifié.

La taille limite d'aperçu a été dépassée, l'affichage des modifications a donc été réduit.

javascript/jquery.multifile.js

supprimé100644 → 0
+0 −539

Fichier supprimé.

La taille limite d'aperçu a été dépassée, l'affichage des modifications a donc été réduit.

javascript/medias_edit.js

supprimé100644 → 0
+0 −20

Fichier supprimé.

La taille limite d'aperçu a été dépassée, l'affichage des modifications a donc été réduit.

Fichier modifié.

La taille limite d'aperçu a été dépassée, l'affichage des modifications a donc été réduit.

Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
var mejsloader;
(function(){var a=mejsloader;"undefined"==typeof a&&(mejsloader=a={gs:null,plug:{},css:{},init:null,c:0,cssload:null});a.init||(a.cssload=function(c){if("undefined"==typeof a.css[c]){a.css[c]=!0;var b=document.createElement("link");b.href=c;b.rel="stylesheet";b.type="text/css";document.getElementsByTagName("head")[0].appendChild(b)}},a.init=function(){!0===a.gs&&function(c){jQuery("audio.mejs,video.mejs").not(".done,.mejs__player").each(function(){function b(){var e=!0,h;for(h in d.css)a.cssload(d.css[h]);for(var f in d.plugins)"undefined"==
typeof a.plug[f]?(e=!1,a.plug[f]=!1,jQuery.getScript(d.plugins[f],function(){a.plug[f]=!0;b()})):0==a.plug[f]&&(e=!1);e&&jQuery("#"+c).mediaelementplayer(jQuery.extend(d.options,{success:function(a,c){function b(){var b=jQuery(a).closest(".mejs__inner");a.paused?(b.addClass("pausing"),setTimeout(function(){b.filter(".pausing").removeClass("playing").removeClass("pausing").addClass("paused")},100)):b.removeClass("paused").removeClass("pausing").addClass("playing")}b();a.addEventListener("play",b,!1);
a.addEventListener("playing",b,!1);a.addEventListener("pause",b,!1);a.addEventListener("paused",b,!1);g.attr("autoplay")&&a.play()}}))}var g=jQuery(this).addClass("done"),c;(c=g.attr("id"))||(c="mejs-"+g.attr("data-id")+"-"+a.c++,g.attr("id",c));var d={options:{},plugins:{},css:[]},e,h;for(e in d)if(h=g.attr("data-mejs"+e))d[e]=jQuery.parseJSON(h);b()})}(jQuery)});a.gs||("undefined"!==typeof mejscss&&a.cssload(mejscss),a.gs=jQuery.getScript(mejspath,function(){a.gs=!0;a.init();jQuery(a.init);onAjaxLoad(a.init)}))})();
 No newline at end of file
var mejsloader;!function(){var e=mejsloader;void 0===e&&(mejsloader=e={gs:null,plug:{},css:{},init:null,c:0,cssload:null}),e.init||(e.cssload=function(s){if(void 0===e.css[s]){e.css[s]=!0;var t=document.createElement("link");t.href=s,t.rel="stylesheet",t.type="text/css",document.getElementsByTagName("head")[0].appendChild(t)}},e.getScript=function(e,s){var t=document.createElement("script"),n=document.getElementsByTagName("script")[0];t.async=1,t.onload=t.onreadystatechange=function(e,n){(n||!t.readyState||/loaded|complete/.test(t.readyState))&&(t.onload=t.onreadystatechange=null,t=void 0,!n&&s&&setTimeout(s,0))},t.src=e,n.parentNode.insertBefore(t,n)},e.init=function(){!0===e.gs&&document.querySelectorAll("audio.mejs,video.mejs").forEach((function(s){if(!s.classList.contains("done")&&!s.classList.contains("mejs__player")){var t;s.classList.add("done"),(t=s.id)||(t="mejs-"+s.dataset.id+"-"+e.c++,s.id=t);var n,a,i={options:{},plugins:{},css:[]};for(n in i)(a=s.dataset["mejs"+n])&&(i[n]=JSON.parse(a));function o(s){e.getScript(i.plugins[s],(function(){e.plug[s]=!0,d()}))}function d(){var s=!0;for(var n in i.css)e.cssload(i.css[n]);for(var a in i.plugins)void 0===e.plug[a]?(s=!1,e.plug[a]=!1,o(a)):!1===e.plug[a]&&(s=!1);if(s){i.options.success=function(e,s){function t(){var s=e.closest(".mejs__inner");e.paused?(s.classList.add("pausing"),setTimeout((function(){s.classList.contains("pausing")&&(s.classList.remove("playing"),s.classList.remove("pausing"),s.classList.add("paused"))}),100)):(s.classList.remove("paused"),s.classList.remove("pausing"),s.classList.add("playing"))}t(),e.addEventListener("play",t,!1),e.addEventListener("playing",t,!1),e.addEventListener("pause",t,!1),e.addEventListener("paused",t,!1),s.autoplay&&(e.muted=!0)};new MediaElementPlayer(t,i.options)}}d()}}))}),e.gs||("undefined"!=typeof mejscss&&e.cssload(mejscss),e.gs=e.getScript(mejspath,(function(){e.gs=!0,e.init(),"loading"===document.readyState&&document.addEventListener("DOMContentLoaded",e.init),onAjaxLoad(e.init)})))}();