Valider cb88904c rédigé par marcimat's avatar marcimat
Parcourir les fichiers

Le formulaire qui veut profiter du chargement des uploads doit déclarer

dans le charger le paramètre `_rechercher_uploads` à true.

Ce faisant, il y a une recherche des fichiers uploadés pour ce formulaire (par l'auteur en cours)
et la liste est à la fois ajouté dans $_FILES et aussi dans l'environnement _fichiers

Une question subsiste : comment $_FILES est géré avec les input multiple de type file.

On n'a a priori plus / pas besoin de pipeline de déclaration des champs d'uploads.
Un champ upload est autorisé avec le token calculé avec `#BIGUP_TOKEN`.
parent b014336c
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+1 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -21,6 +21,7 @@ if (!defined('_ECRIRE_INC_VERSION')) return;
if (_request('bigup_token')) {
	include_spip('inc/Bigup');
	$Bigup = new \SPIP\Bigup\Bigup();
	$Bigup->recuperer_parametres();
	$Bigup->repondre();
	exit;
}
+18 −20
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -53,35 +53,33 @@ function bigup_header_prive($flux) {
}

/**
 * Si des fichiers d'upload sont déclarés, gérer la mécanique de déclaration et stockage
 * Recherche de fichiers uploadés pour ce formulaire
 *
 * La recherche est conditionné par la présence dans le contexte
 * de la clé `_rechercher_uploads`. Ceci permet d'éviter de chercher
 * des fichiers pour les formulaires qui n'en ont pas besoin.
 * 
 * @param array $flux
 * @return array
**/
function bigup_formulaire_charger($flux) {
/*
	// S'il y a des champs fichiers de déclarés
	if ($fichiers = bigup_lister_fichiers_formulaire($flux['args']['form'], $flux['args']['args'])) {
		$flux['data']['_fichiers'] = $fichiers;
	}*/
/*

	if (empty($flux['data']['_rechercher_uploads'])) {
		return $flux;
	}

	// il nous faut le nom du formulaire et son hash
	// et pas de bol, le hash est pas envoyé dans le pipeline chargé.
	// (il est calculé après). Alors on se recrée un hash pour nous.
	$form = $flux['args']['form'];
	$args = $flux['args']['args'];
	array_unshift($args, $GLOBALS['spip_lang']);
	$formulaire_args = encoder_contexte_ajax($args, $form);
*/
	// Si le formulaire est considéré posté (en get ou post)
	// Tester voir si c'est pas un morceaux de fichier qui est envoyé
	if (!empty($flux['args']['je_suis_poste'])) {
		/*
		include_spip('inc/flow');
		$Flow = new \SPIP\Bigup\Flow();
		$key = $Flow->run();
		if ($key) {
			spip_log("Fichier reçu dans $key", 'test_upl');
			spip_log($_FILES[$key], 'test_upl');
		}
		*/

	include_spip('inc/Bigup');
	$bigup = new \Spip\Bigup\Bigup($form, $formulaire_args);
	if ($fichiers = $bigup->reinserer_fichiers()) {
		$flux['data']['_fichiers'] = $fichiers;
	}

	return $flux;
+2 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -5,6 +5,8 @@
	[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>]
	[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]

[<pre>(#ENV{_fichiers}|print_r{1})</pre>]

	<div class="explication">
		Ce formulaire vise à montrer le fonctionnement d'un CVT traditionnel,
		auquel on ajoute des champs de type fichier.
+3 −14
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -18,20 +18,6 @@
 * @package SPIP\Bigup\Formulaires
**/

function formulaires_tester_bigup_declarer_fichiers_dist($id = 0) {
	$fichiers = [
		'file' => [],
		'files' => [
			'multiple' => true,
			'max' => 3,
		],
		'autre' => [],
	];

	spip_log('declarer_fichiers', "test_upl");

	return $fichiers;
}


function formulaires_tester_bigup_charger_dist($id = 0) {
@@ -40,6 +26,9 @@ function formulaires_tester_bigup_charger_dist($id = 0) {
		'texte' => '',
	];

	// demander la gestion de fichiers d'upload
	$valeurs['_rechercher_uploads'] = true;

	return $valeurs;
}

+106 −19
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -79,19 +79,27 @@ class Bigup {

	/**
	 * Constructeur
	 *
	 * @param string $formulaire Nom du formulaire
	 * @param string $formulaire_args Hash du formulaire
	 * @param string $token Jeton d'autorisation
	**/
	public function __construct() {
		$this->trouver_parametres();
	public function __construct($formulaire = '', $formulaire_args = '', $token = '') {
		$this->token = $token;
		$this->formulaire = $formulaire;
		$this->formulaire_args = $formulaire_args;
		$this->identifier_auteur();
		$this->identifier_formulaire();
	}

	/**
	 * Retrouve les paramètres pertinents pour gérer le test ou la réception de fichiers.
	**/
	public function trouver_parametres() {
	public function recuperer_parametres() {
		$this->token           = _request('bigup_token');
		$this->formulaire      = _request('formulaire_action');
		$this->formulaire_args = _request('formulaire_action_args');
		$this->identifier_formulaire();
	}

	/**
@@ -137,6 +145,63 @@ class Bigup {
	}


	/**
	 * Retrouve les fichiers qui ont été téléchargés et sont en attente pour ce formulaire
	 * et les réaffecte à $_FILES au passage.
	 *
	 * @return array
	**/
	public function reinserer_fichiers() {
		$this->calculer_chemin_repertoires();
		$liste = $this->trouver_fichiers_complets();

		foreach ($liste as $champ => $fichiers) {
			foreach ($fichiers as $description) {
				// TODO: Bug ici, si 2 fichiers sur 1 seul champ (input file multiple).
				// découvrir comment gère html/php d'habitude pour ce cas.
				$this->integrer_fichier($champ, $description);
			}
		}

		return $liste;
	}

	/**
	 * Retourne la liste des fichiers complets, classés par champ
	 *
	 * @return array Liste [ champ => [ chemin ]]
	**/
	public function trouver_fichiers_complets() {
		// la théorie veut ce rangement :
		// $dir/{champ}/{identifiant_fichier}/{nom du fichier.extension}
		$directory = $this->dir_final;

		// pas de répertoire… pas de fichier… simple comme bonjour :)
		if (!is_dir($directory)) {
			return [];
		}

		$liste = [];

		$files = new \RecursiveIteratorIterator(
			new \RecursiveDirectoryIterator($directory)
		);

		foreach ($files as $filename) {
			if ($filename->isDir()) continue; // . ..
			if ($filename->getFilename()[0] == '.') continue; // .ok

			$chemin = $filename->getPathname();
			$champ  = basename(dirname(dirname($chemin)));

			$liste[$champ][] = $this->decrire_fichier($chemin);
			$this->debug("Fichier retrouvé : $chemin");
		}

		return $liste;
	}


	/**
	 * Vérifier le token utilisé
	 *
@@ -187,12 +252,9 @@ class Bigup {
			return false;
		}

		// Renseigner le formulaire et champ utilisé.
		$identifiant = substr($this->formulaire_args, 0, 6);
		$this->formulaire_identifiant = $identifiant;
		$this->champ = $champ;

		$this->debug("Token OK : formulaire $this->formulaire, champ $champ, identifiant $identifiant");
		$this->debug("Token OK : formulaire $this->formulaire, champ $champ, identifiant $this->formulaire_identifiant");

		return true;
	}
@@ -238,25 +300,50 @@ class Bigup {
		return $this->auteur = $identifiant;
	}

	/**
	 * Calcule un identifiant de formulaire en fonction de son hash
	 *
	 * @return string l'identifiant
	**/
	public function identifier_formulaire() {
		return $this->formulaire_identifiant = substr($this->formulaire_args, 0, 6);
	}

	/**
	 * Intégrer le fichier indiqué dans `$FILES`
	 *
	 * @param string $key Clé d'enregistrement
	 * @param string $key
	 *     Clé d'enregistrement
	 * @param string|array $description
	 *     array : Description déjà calculée
	 *     string : chemin du fichier
	 * @return array
	 *     Description du fichier
	**/
	public function integrer_fichier($key, $description) {
		if (!is_array($description)) {
			$description = $this->decrire_fichier($description); 
		}
		return $_FILES[$key] = $description;
	}

	/**
	 * Décrire un fichier (comme dans `$_FILES`)
	 *
	 * @param string $chemin
	 * @return string Clé d'enregistrement
	 * @return array
	**/
	public function integrer_fichier($key, $chemin) {
	public function decrire_fichier($chemin) {
		$filename = basename($chemin);

		// on réécrit $_FILES avec les valeurs du fichier complet
		$_FILES[$key]['name'] = $filename;
		$_FILES[$key]['tmp_name'] = $chemin;
		$_FILES[$key]['size'] = filesize($chemin);
		$finfo = finfo_open(FILEINFO_MIME_TYPE);
		$_FILES[$key]['type'] = finfo_file($finfo, $chemin);

		// fichier complété
		return $key;
		$desc = [
			'name' => $filename,
			'pathname' => $chemin, // celui là n'y est pas normalement dans $_FILES
			'tmp_name' => $chemin,
			'size' => filesize($chemin),
			'type' => finfo_file($finfo, $chemin),
		];
		return $desc;
	}