Overview
Comment: | Modernisation objet fichiers |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | dev |
Files: | files | file ages | folders |
SHA1: |
18ca9332f51e1970591ae5dab4eca976 |
User & Date: | bohwaz on 2017-05-17 07:08:19 |
Other Links: | branch diff | manifest | tags |
Context
2017-05-18
| ||
07:29 | Modernisation admin wiki et fichiers check-in: 9f46f9067f user: bohwaz tags: dev | |
2017-05-17
| ||
07:08 | Modernisation objet fichiers check-in: 18ca9332f5 user: bohwaz tags: dev | |
07:07 | Ajout méthode openBlob check-in: 2b37df9aad user: bohwaz tags: dev | |
Changes
Modified src/include/lib/Garradin/Fichiers.php from [6317211824] to [249ae8890d].
︙ | ︙ | |||
69 70 71 72 73 74 75 | * Constructeur de l'objet pour un fichier * @param integer $id Numéro unique du fichier */ public function __construct($id, $data = null) { if (is_null($data)) { | | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | * Constructeur de l'objet pour un fichier * @param integer $id Numéro unique du fichier */ public function __construct($id, $data = null) { if (is_null($data)) { $data = DB::getInstance()->first('SELECT fichiers.*, fc.hash, fc.taille, strftime(\'%s\', datetime) AS datetime FROM fichiers INNER JOIN fichiers_contenu AS fc ON fc.id = fichiers.id_contenu WHERE fichiers.id = ?;', (int)$id); } if (!$data) { throw new \InvalidArgumentException('Ce fichier n\'existe pas.'); } |
︙ | ︙ | |||
112 113 114 115 116 117 118 119 | $check = [self::LIEN_MEMBRES, self::LIEN_WIKI, self::LIEN_COMPTA]; if (!in_array($type, $check)) { throw new \LogicException('Type de lien de fichier inconnu.'); } unset($check[array_search($type, $check)]); | > | > > > | > > | > | > > | | | < | > > | | > | | | | | | | | | | | | | | | | | | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | $check = [self::LIEN_MEMBRES, self::LIEN_WIKI, self::LIEN_COMPTA]; if (!in_array($type, $check)) { throw new \LogicException('Type de lien de fichier inconnu.'); } // Ne pas chercher dans le type qu'on veut lier unset($check[array_search($type, $check)]); // Vérifier que le fichier n'est pas déjà lié à un autre type $query = []; foreach ($check as $type) { $query[] = sprintf('SELECT 1 FROM fichiers_%s WHERE fichier = %d', $type, $this->id); } $query = implode(' UNION ', $query) . ';'; if ($db->firstColumn($query)) { throw new \LogicException('Ce fichier est déjà lié à un autre contenu : ' . $check_type); } return $db->query('INSERT OR IGNORE INTO fichiers_' . $type . ' (fichier, id) VALUES (?, ?);', (int)$this->id, (int)$foreign_id); } /** * Vérifie que l'utilisateur a bien le droit d'accéder à ce fichier * @param mixed $user Tableau contenant les infos sur l'utilisateur connecté, provenant de Membres::getLoggedUser, ou false * @return boolean TRUE si l'utilisateur a le droit d'accéder au fichier, sinon FALSE */ public function checkAccess($user = false) { $db = DB::getInstance(); // On regarde déjà si le fichier n'est pas lié au wiki $query = sprintf('SELECT wp.droit_lecture FROM fichiers_%s AS link INNER JOIN wiki_pages AS wp ON wp.id = link.id WHERE link.fichier = ? LIMIT 1;', self::LIEN_WIKI); $wiki = $db->firstColumn($query, (int)$this->id); // Page wiki publique, aucune vérification à faire, seul cas d'accès à un fichier en dehors de l'espace admin if ($wiki !== false && $wiki == Wiki::LECTURE_PUBLIC) { return true; } // Pas d'utilisateur connecté, pas d'accès aux fichiers de l'espace admin if (empty($user->droits)) { return false; } if ($wiki !== false) { // S'il n'a même pas droit à accéder au wiki c'est mort if ($user->droits->wiki < Membres::DROIT_ACCES) { return false; } // On renvoie à l'objet Wiki pour savoir si l'utilisateur a le droit de lire ce fichier $_w = new Wiki; $_w->setRestrictionCategorie($user->id_categorie, $user->droits->wiki); return $_w->canReadPage($wiki); } // On regarde maintenant si le fichier est lié à la compta $query = sprintf('SELECT 1 FROM fichiers_%s WHERE fichier = ? LIMIT 1;', self::LIEN_COMPTA); $compta = $db->firstColumn($query, (int)$this->id); if ($compta && $user->droits->compta >= Membres::DROIT_ACCES) { // OK si accès à la compta return true; } // Enfin, si le fichier est lié à un membre $query = sprintf('SELECT id FROM fichiers_%s WHERE fichier = ? LIMIT 1;', self::LIEN_MEMBRES); $membre = $db->firstColumn($query, (int)$this->id); if ($membre !== false) { // De manière évidente, l'utilisateur a le droit d'accéder aux fichiers liés à son profil if ((int)$membre == $user->id) { return true; } // Pour voir les fichiers des membres il faut pouvoir les gérer if ($user->droits->membres >= Membres::DROIT_ECRITURE) { return true; } } return false; } /** * Supprime le fichier * @return boolean TRUE en cas de succès */ public function remove() { $db = DB::getInstance(); $db->begin(); $db->delete('fichiers_compta_journal', 'fichier = ?', (int)$this->id); $db->delete('fichiers_wiki_pages', 'fichier = ?', (int)$this->id); $db->delete('fichiers_membres', 'fichier = ?', (int)$this->id); $db->delete('fichiers', 'id = ?', (int)$this->id); // Suppression du contenu s'il n'est pas utilisé par un autre fichier if (!$db->firstColumn('SELECT 1 FROM fichiers WHERE id_contenu = ? AND id != ? LIMIT 1;', (int)$this->id_contenu, (int)$this->id)) { $db->delete('fichiers_contenu', 'id = ?', (int)$this->id_contenu); } $cache_id = 'fichiers.' . $this->id_contenu; Static_Cache::remove($cache_id); foreach (self::$allowed_thumb_sizes as $size) |
︙ | ︙ | |||
351 352 353 354 355 356 357 | * Vérifie si le hash fourni n'est pas déjà stocké * Utile pour par exemple reconnaître un ficher dont le contenu est déjà stocké, et éviter un nouvel upload * @param string $hash Hash SHA1 * @return boolean TRUE si le hash est déjà présent dans fichiers_contenu, FALSE sinon */ static public function checkHash($hash) { | | < < | < | | < | > | < | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | * Vérifie si le hash fourni n'est pas déjà stocké * Utile pour par exemple reconnaître un ficher dont le contenu est déjà stocké, et éviter un nouvel upload * @param string $hash Hash SHA1 * @return boolean TRUE si le hash est déjà présent dans fichiers_contenu, FALSE sinon */ static public function checkHash($hash) { return (boolean) DB::getInstance()->firstColumn( 'SELECT 1 FROM fichiers_contenu WHERE hash = ?;', trim(strtolower($hash)) ); } /** * Retourne un tableau de hash trouvés dans la DB parmi une liste de hash fournis * @param array $list Liste de hash à vérifier * @return array Liste des hash trouvés */ static public function checkHashList($list) { $db = DB::getInstance(); array_walk($list, function ($a) use ($db) { return $db->quote($a); }); $query = sprintf('SELECT hash, 1 FROM fichiers_contenu WHERE hash IN (%s);', $list); return $db->getAssoc($query); } /** * Récupération du message d'erreur * @param integer $error Code erreur du $_FILE * @return string Message d'erreur */ |
︙ | ︙ | |||
453 454 455 456 457 458 459 | $size = filesize($file['tmp_name']); $db = DB::getInstance(); $db->begin(); // Il peut arriver que l'on renvoie ici un fichier déjà stocké, auquel cas, ne pas le re-stocker | | | | | 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 | $size = filesize($file['tmp_name']); $db = DB::getInstance(); $db->begin(); // Il peut arriver que l'on renvoie ici un fichier déjà stocké, auquel cas, ne pas le re-stocker if (!($id_contenu = $db->firstColumn('SELECT id FROM fichiers_contenu WHERE hash = ?;', $hash))) { $db->insert('fichiers_contenu', [ 'hash' => $hash, 'taille' => (int)$size, 'contenu' => [\SQLITE3_BLOB, file_get_contents($file['tmp_name'])], ]); $id_contenu = $db->lastInsertRowID(); } $db->insert('fichiers', [ 'id_contenu' => (int)$id_contenu, 'nom' => $name, 'type' => $type, 'image' => (int)$is_image, ]); $db->commit(); |
︙ | ︙ | |||
487 488 489 490 491 492 493 | * @return object Un objet Fichiers en cas de succès */ static public function uploadExistingHash($name, $hash) { $db = DB::getInstance(); $name = preg_replace('/[^\d\w._-]/ui', '', $name); | | | | | | | | | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 | * @return object Un objet Fichiers en cas de succès */ static public function uploadExistingHash($name, $hash) { $db = DB::getInstance(); $name = preg_replace('/[^\d\w._-]/ui', '', $name); $file = $db->first('SELECT * FROM fichiers INNER JOIN fichiers_contenu AS fc ON fc.id = fichiers.id_contenu AND fc.hash = ?;', trim($hash)); if (!$file) { throw new UserException('Le fichier à copier n\'existe pas (aucun hash ne correspond à '.$hash.').'); } $db->insert('fichiers', [ 'id_contenu' => (int)$file->id_contenu, 'nom' => $name, 'type' => $file->type, 'image' => (int)$file->image, ]); return new Fichiers($db->lastInsertRowID()); } /** * Récupère la liste des fichiers liés à une ressource |
︙ | ︙ | |||
525 526 527 528 529 530 531 | if (!in_array($type, $check)) { throw new \LogicException('Type de lien de fichier inconnu.'); } $images = is_null($images) ? '' : ' AND image = ' . (int)$images; | | | | | | | 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 | if (!in_array($type, $check)) { throw new \LogicException('Type de lien de fichier inconnu.'); } $images = is_null($images) ? '' : ' AND image = ' . (int)$images; $files = DB::getInstance()->get('SELECT fichiers.*, c.hash, c.taille FROM fichiers INNER JOIN fichiers_'.$type.' AS fwp ON fwp.fichier = fichiers.id INNER JOIN fichiers_contenu AS c ON c.id = fichiers.id_contenu WHERE fwp.id = ? '.$images.' ORDER BY fichiers.nom COLLATE NOCASE;', (int)$id); foreach ($files as &$file) { $file->url = self::_getURL($file->id, $file->nom); $file->thumb = $file->image ? self::_getURL($file->id, $file->nom, 200) : false; } return $files; } /** * Enlève d'une liste de fichiers ceux qui sont mentionnés dans un texte wiki * @param array $files Liste de fichiers * @param string $text texte wiki * @return array Un tableau qui ne contient pas les fichiers mentionnés dans $text */ static public function filterFilesUsedInText($files, $text) { $used = self::listFilesUsedInText($text); return array_filter($files, function ($row) use ($used) { return !in_array($row->id, $used); }); } /** * Renvoie une liste d'ID de fichiers mentionnées dans un texte wiki * @param string $text Texte wiki * @return array Liste des IDs de fichiers mentionnés |
︙ | ︙ |