web-dev-qa-db-fra.com

Comment rendre les fichiers publics existants privés?

Disons que j'ai un type de nœud "Article" qui a un champ "Fichier" qui est configuré pour gérer les fichiers publics. De nombreux articles et fichiers sont ajoutés.

Maintenant, les spécifications changent soudainement et l '"article" se déplacera derrière une connexion et par conséquent, les fichiers joints doivent être modifiés pour ne plus être accessibles au public.

J'ai déjà découvert comment changer le système de fichiers pour le champ de fichiers de public à privé assez facilement en réimportant le field.storage.node.field_file.yml config. Mais: cela n'affecte que les nouveaux fichiers qui seront ajoutés après le changement. Cela ne fonctionne pas pour les fichiers existants. Ils sont toujours accessibles au public. Plusieurs milliers de fichiers existants devraient être téléchargés manuellement pour les rendre également privés.

Est-ce que quelqu'un d'entre vous a déjà résolu cela en D8? Si oui, alors comment?

Comme tout ce à quoi je peux penser en ce moment, c'est d'interroger par programme tous les nœuds "Article", puis de parcourir tous les nœuds, d'obtenir les fichiers, de les stocker temporairement ailleurs, de vider le champ, puis d'essayer de retélécharger les fichiers par programme (probablement mon prochain question), puis réenregistrez chaque nœud.

Cela vous semble-t-il raisonnable? Ou pouvez-vous penser à une autre approche qui pourrait fonctionner ici (en D8)?

8
leymannx

Merci beaucoup pour les réponses! FileField Paths est définitivement la voie à suivre.

  1. Mettez à jour le stockage de champ du champ de fichier pour gérer les fichiers privés.
  2. Exécutez FileField Paths ' Mise à jour rétroactive sur le champ de fichier de votre type de contenu.

Étape 1. peut être effectuée à partir de hook_update_N (si vous utilisez la gestion de la configuration, faites-le localement, puis exportez la configuration mise à jour et déployez le *.yml):

$field_type = 'file';
$field_name = 'field_file';

if (!$field_storage_configs = \Drupal::entityManager()
  ->getStorage('field_storage_config')
  ->loadByProperties(['type' => $field_type])) {
  return;
}

foreach ($field_storage_configs as $field_storage) {
  // Note: These settings apply to the field_file field everywhere it is
  // used.
  if ($field_storage->getName() == $field_name) {
    $field_storage->setSetting('uri_scheme', 'private');
    $field_storage->enforceIsNew(FALSE);
    $field_storage->save();
  }
}

Sinon, suivez la mise à jour manuelle de la configuration et réimportez comme suggéré dans la question.


Étape 2. consiste à accéder à l'écran d'édition de votre champ de fichier et à déclencher la mise à jour rétroactive lors de l'enregistrement du formulaire:

enter image description here

5
leymannx

Je l'ai fait pour Drupal 7, mais je ne l'ai pas essayé dans Drupal 8.

Je pense que cela devrait fonctionner de la même manière car il existe déjà une version D8 pour le module requis: FileField Paths . J'ai d'abord installé et activé le module avant de suivre les étapes ci-dessous:

juste au cas où quelqu'un chercherait à le faire, voici les étapes:

  1. sauvegarder votre site et db
  2. copiez la table de votre champ pour faire une sauvegarde (dans mon cas, j'ai copié: field_data_field_attachments vers field_data_field_attachments_bk)
  3. table vide field_data_field_attachments
  4. allez à drupal et l'option de changer le système de fichiers devrait être disponible, alors changez-le
  5. copier toutes les données de field_data_field_attachments_bk vers field_data_field_attachments
  6. allez à drupal, sélectionnez votre type de contenu, sélectionnez votre champ de fichier, dans les paramètres de chemin de fichier, sélectionnez la mise à jour rétroactive
  7. cliquez sur enregistrer et il déplacera tous vos fichiers au bon endroit dans le système de fichiers et mettra à jour votre base de données vers le nouveau chemin

- A Romka

Fil complet

3
Chris Happy

C'est assez simple, je l'ai testé moi-même et ça marche.

1) Avec PHPMyAdmin ou une application de gestion de base de données, vous devrez regarder node__field_NAME qui contient vos fichiers. Enregistrez tous les numéros field_NAME_target_id qui appartiennent à votre type de contenu.

2) Allez à file_managed table.

3) Exporter la table en tant que fichier .sql

4) Ouvrez le fichier .sql avec une application d'édition de texte. Renommer tous public:// à private:// pour ceux qui ont le numéro fid que vous avez enregistré.

5) Importez .sql et remplacez la table file_managed. OR vous pouvez effacer la table puis importer.

6) Déplacez les fichiers vers le dossier privé.

  • Important: assurez-vous qu'il a la même structure de dossier parent. S'il était auparavant sous /files/2018-06/some.jpg, en privé, il doit être /private/2018-06/some.jpg

    • De plus, pas besoin de déplacer les fichiers d'image de style d'image, ceux-ci seront créés automatiquement. Ainsi, il vous suffit de saisir l'original.

7) Videz tous les caches.


Je suis sûr que vous pouvez utiliser la requête SQL pour faire 1 à 5. Fondamentalement, tout ce que vous devez faire est de mettre à jour les valeurs spécifiques de la colonne uri dans le field_managed table.

3
No Sssweat

Avec mon Drupal 8.6.3 la mise à jour rétro-active ne fonctionne pas.

Vous devez encore réaliser l'étape 1, pour mettre à jour le stockage sur le terrain de votre champ.

Ensuite, vous devez mettre à jour tous les fichiers existants via la base de données avec:

UPDATE file_managed SET uri = REPLACE( 
    uri,
    'public://',
    'private://'
)
WHERE filemime like 'application%';

Dans mon cas, je ne mets à jour que les fichiers, c'est pourquoi j'utilise cette clause where.

N'oubliez pas de vider le cache après cette requête SQL.

2
Denis Kolmerschlag