Est-il acceptable de modifier la colonne vid d'un terme par programme dans la base de données?

8

J'ai besoin de déplacer certains termes d'un vocabulaire à un autre en conservant toutes leurs données: traductions, alias et références de nœuds.

Est-il acceptable de modifier sa vidvaleur de colonne directement dans la base de données? Les termes n'ont pas de relations hiérarchiques qui doivent être traitées.

Molfar
la source

Réponses:

11

Base de données

Il est possible de faire beaucoup de choses dans Drupal simplement en faisant des requêtes SQL, soit via Drupal soit en externe. Généralement, vous ne voulez jamais adopter cette approche. Il y a des cas où cela peut très bien fonctionner, mais la plupart du temps il n'y a aucune raison de le faire de cette façon.

API

Drupal possède une API riche, cela est vrai pour Drupal 6, 7 et 8, car ils ont toujours été une caractéristique clé de Drupal. Dans votre exemple concré, vous pourriez utiliser taxonomy_term_loadet taxonomy_term_savepour faciliter la mise à jour d'un terme. De cette façon, vous pouvez modifier n'importe quelle partie de données, y compris le vid. Tout simplement parce que vous le faites avec des API faisant des choses interdites, cela ne fonctionnera pas automatiquement, mais les chances que les choses se passent bien sont considérablement améliorées.

Dans cet exemple concret, l'API ne fait rien de nécessaire. Il définit certaines données internes sur le terme et appelle le module de lettre des crochets sachant qu'il a été mis à jour.

Vous devez noter que les choses peuvent se casser si le terme que vous souhaitez modifier fait partie d'une hiérarchie. Les choses peuvent également se briser pour les nœuds référençant le terme, si le champ n'est pas autorisé à référencer des termes dans le nouveau vocabulaire.

Migration

La migration des données est la solution à toute épreuve, et à moins que vous n'ayez un énorme ensemble de données, il peut être développé et exécuté assez facilement. L'idée est de créer un nouveau terme et de migrer le contenu que vous souhaitez migrer, puis de supprimer l'ancien terme. En tant que hook de mise à jour, un exemple de code pourrait ressembler à ceci:

/**
 * Put in modules .install file, replace xxxx with 7000 or higher
 */
function MODULE_NAME_update_XXXX(&$sandbox) {
  $term = taxonomy_term_load(CONSTANT_WITH_TID);
  $new_term = clone $term;
  unset($new_term->tid);
  unset($new_term->tid);
  $new_term->vid = CONSTANT_WITH_VID;
  taxonomy_term_save($term);
  // Find all nodes we want to update and update them.
  // If there is a lot of nodes, can use $sandbox to make this a batch job.
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
    ->fieldCondition('field_which_is_term_reference', 'tid', $term->tid);
  $result = $query->execute();
  foreach (node_load_multiple(array_keys($result['node'])) as $node) {
    $node->field_which_is_term_reference[LANGUAGE_NONE][0]['tid'] = $term->tid;
    node_save($node);
  }
  // Migration all done - delete the old term.
  taxonomy_term_delete($term->tid);
}

Veuillez noter que le code ci-dessus est un exemple de code pur, écrit par cœur. Peut avoir une erreur de syntaxe ou d'autres erreurs et fait beaucoup d'hypothèses. Il s'agit simplement d'illustrer une idée et de démontrer qu'une migration pourrait ne pas être un gros problème.

googletorp
la source
4

Il n'est pas conseillé de faire des changements directs de base de données lorsque vous travaillez avec Drupal. Mais oui, si nous savons où tout cela peut avoir un impact et effectuons les changements nécessaires en conséquence, il est OK de faire des changements directs dans la base de données. Parce que dans ce cas, cela n'est pas possible via l'interface utilisateur. REMARQUE: Si vous avez des nœuds associés à Term, vous devrez également gérer manuellement cela.

Consultez ce lien qui explique comment nous pouvons changer le vocabulaire du terme dans Drupal 7: Changer le vocabulaire d'un terme de taxonomie dans Drupal 7 en utilisant la base de données .

Yogesh
la source
Un seul problème que je vois dans ce cas est - si dans le cas, il y a des champs attachés à un terme avec certaines valeurs et que vous changez sa vidéo, alors les données stockées dans le champ seront perdues.
Ashish Deynap
Oui, c'est pourquoi j'ai également mentionné que, s'il y a des nœuds connectés, ils doivent également être traités .
Yogesh
Mais est-ce que des données sont également attachées au terme par vidéo? non seulement par clé tid?
Molfar
Non, toutes les données attachées au terme sont liées à tid. vid est utilisé pour référencer uniquement l'identifiant de vocabulaire, rien d'autre.
Yogesh
4

Je ne recommanderais pas de changer ce terme comme vous l'avez décrit dans votre question. Au lieu de cela, j'utiliserais une approche alternative pour obtenir un résultat similaire (dans l'ordre spécifié), qui est détaillé ci-dessous.

Étape 1 - Commencez à utiliser le nouveau terme dans les futures mises à jour des nœuds

Créez un nouveau champ de terme de taxonomie, de sorte que "désormais" toutes les futures mises à jour de nœuds (ou nouveaux nœuds en cours de création) utiliseront ce nouveau champ. Je suppose que ces termes sont utilisés pour les nœuds (si vous l'utilisez pour un autre type d'entité, comme les utilisateurs, etc.), la même approche peut également être utilisée pour ces entités.

Utilisez le module Règles pour créer une règle comme ceci:

  • Règles de l' événement: before saving content.
  • Conditions des règles:
    • entity has field, avec champ = l'ancien champ.
    • ET NON ( entity has field, avec champ = le nouveau champ).
  • Action des règles: set Drupal messagequi contient des instructions indiquant que l'ancien champ doit être supprimé et que le nouveau champ doit contenir la ou les valeurs appropriées.

Étape 2 - Utilisez des règles pour accélérer le processus

De toute évidence, l'approche de l'étape 1 prendra "un certain" temps si cela doit être fait manuellement, 1 nœud à la fois. Mais en utilisant Views (pour créer une liste de nœuds similaires à mettre à jour) et VBO (pour mettre à jour en masse ces listes), vous pourriez (devriez!) Accélérer un peu ce processus.

Surtout si vous souhaitez utiliser des règles pour créer une opération en bloc personnalisée pour une telle vue VBO, comme expliqué dans la réponse à " Comment utiliser des règles pour créer une opération en bloc personnalisée pour une vue VBO? ". Voici un prototype d'un composant de règles qui devrait aider à implémenter une telle opération en bloc personnalisée (au format d'exportation de règles):

{ "rules_replace_a_term_field_by_another_term_field" : {
    "LABEL" : "Replace a term field by another term field",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : { "node" : { "label" : "Node", "type" : "node" } },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_sample_tags" } },
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_demo_tags" } },
      { "data_is" : { "data" : [ "node:field-demo-tags" ], "value" : "1" } }
    ],
    "DO" : [
      { "data_set" : { "data" : [ "node:field-sample-tags" ], "value" : "31" } },
      { "drupal_message" : { "message" : "Term updated in node with id = [node:nid]" } }
    ]
  }
}

Quelques détails supplémentaires pour expliquer le prototype ci-dessus:

  • Il utilise un nœud comme paramètre.
  • Ce sont les conditions des règles:

    • vérifiez si l'entité (= nœud) a un champ field_sample_tags.
    • vérifiez si l'entité (= nœud) a un champ field_demo_tags.
    • vérifiez si la valeur du champ field_demo_tagscorrespond au terme que nous voulons remplacer (dans cet exemple, le terme a id = 1). Notez que si cette condition n'est pas remplie, aucune action de règles ne sera effectuée.
  • Ce sont les actions de règles:

    • Définissez la valeur du champ field_sample_tagségale au terme avec le terme id = 31(qui est le terme du vocabulaire nouvellement créé qui correspond au terme du vocabulaire à remplacer).
    • Afficher un message sur le site comme Term updated in node with id = 72, alors que 72c'est l'ID de nœud du nœud mis à jour.

Si vous le souhaitez, adaptez les noms de machine des noms de champ dans le prototype ci-dessus et les ID de terme utilisés. Ensuite, importez-le dans votre propre site (à l'aide de l'interface utilisateur des règles) et testez-le en utilisant le lien "exécuter" à droite du composant de règles importé (et entrez un identifiant de nœud pour le tester, après avoir basculé sur "entrée directe" mode "pour pouvoir spécifier un identifiant de nœud). Si pendant votre test, vous n'obtenez pas un tel Term updated in node ...message, cela doit être dû au fait que le nœud que vous avez sélectionné n'a pas utilisé la valeur de terme spécifiée dans vos règles Condition.

Étape 3 - Utilisez VBO comme touche finale

Une fois que vous avez terminé de tester le contrôle qualité de ce composant de règles à partir de l'étape 2, créez une vue VBO des nœuds à traiter, dans laquelle vous vous référez au prototype de règles ci-dessus (ou une variante de celui-ci pour répondre à vos besoins).

Bénéfice de cette approche

En utilisant cette approche, vous minimisez le risque d'introduire des incohérences de données (par rapport à la mise à jour directe de la base de données), sans aucun code personnalisé impliqué (vous n'utiliseriez que l'interface utilisateur des vues et l'interface utilisateur des règles).

Pierre.Vriens
la source
Vous supposez que les vues, le VBO et les règles sont déjà installés, sinon vous devez installer 3 modules pour cette solution. De plus, le "code" de configuration que vous devez implémenter n'est pas moins complexe que ce qu'il faudrait faire dans un hook de mise à jour. Mon point est que l'utilisation de règles et de vues n'est pas aussi simple que vous le faites entendre. Il convient également de se rappeler que, même si vous pouvez créer presque n'importe quoi avec les vues et les règles, cela n'est pas toujours une bonne idée.
googletorp
1
Oui en effet: pour utiliser Views, Rules ou VBO, le module doit être installé (+ activé). Mais sur les 990K sites D7 environ, il y a environ 810K sites qui ont également des vues , soit plus de 80%. Et pour les sites qui n'ont aucune raison d'utiliser des règles ou VBO: ces modules ne sont nécessaires que pour effectuer une telle conversion (une fois terminé, ils peuvent être supprimés si vous le souhaitez). À propos de la simplicité: l'OMI est plutôt un problème d'expérience. L'avantage de cette approche est qu'elle ne nécessite que des compétences en création de sites (un développeur PHP expérimenté peut ne pas être disponible / abordable).
Pierre.Vriens
2

Je sais que vous dites par programmation mais si vous voulez utiliser un module, vous pouvez utiliser Taxonomy Manager

Ce module fournit une interface puissante pour gérer les taxonomies. Un vocabulaire s'affiche dans une arborescence dynamique, où les termes parents peuvent être développés pour répertorier leurs termes enfants imbriqués ou peuvent être réduits.

Le gestionnaire de taxonomie présente les opérations et les fonctionnalités clés suivantes:

  • arborescence dynamique
  • suppression en masse
  • ajout en masse de nouveaux termes
  • déplacement de termes dans des hiérarchies fusion de termes (en utilisant le module Term merge dans 7.x)
  • changement de poids rapide avec des flèches haut et bas (et économie AJAX)
  • Formulaire d'édition de termes propulsé par AJAX
  • interface de recherche simple
  • Exportation de termes CSV
  • Prise en charge i18n pour les vocabulaires multilingues (par termes de langue)
  • Interface Double Tree pour déplacer les termes dans les hiérarchies, ajouter de nouvelles traductions et changer de termes entre différents vocabulaires
Adrian Cid Almaguer
la source