web-dev-qa-db-fra.com

Modifier le format d'entrée pour plus de 3000 nœuds

J'ai beaucoup de nœuds qui doivent changer leur format d'entrée - je pourrais le faire à la main, mais je n'aurai pas fini avant Noël 2014.

Où est Drupal stocker ces informations? Comment puis-je changer le format d'entrée en une fraction de seconde, avec une requête SQL?

17
mortendk

Je vais préfacer cette réponse en disant que faire cela en masse présente un risque de sécurité potentiel, surtout si vous changez le format pour un ensemble de filtres plus clément. Les formats de texte modifient la sortie du champ pendant l'affichage, pas pendant l'enregistrement. Ainsi, par exemple, tout code HTML précédemment échappé ou PHP soumis à un champ sera rendu/exécuté directement si vous définissez accidentellement ou intentionnellement le filtre sur Full HTML ou PHP.

C'est pour cette raison que Drupal ne met pas automatiquement à jour tous les nœuds existants lorsque vous modifiez un format de texte. Le comportement des formats de texte dans des scénarios similaires est toujours un problème ouvert .

Encore une fois: attention, il y a des dragons.

Cela dit, chaque champ stocke le texte sous la forme d'une colonne nommée field_foo_format, Où field_foo Est le nom de l'ordinateur du champ. Vous devrez mettre à jour cette colonne sur les tables field_revision_field_foo Et field_data_field_foo.

La valeur de la colonne est un nom d'ordinateur défini comme la colonne format dans la table filter_format. Ainsi, la mise à jour de tous les champs serait une question comme:

UPDATE field_revision_foo SET field_foo_format = 'new_format';
UPDATE field_data_foo SET field_foo_format = 'new_format';

pour chaque domaine qui doit être modifié.

Vous pouvez déterminer la valeur de new_format Ici: http://YOURSITE.com/admin/config/content/formats - configurer le lien - le numéro ou la chaîne dans l'URL est votre new_format. Vider le cache après la mise à jour.

20
user7

Essayez de cette façon, en faisant une boucle pour tous les nœuds d'un certain type:

$node = node_load(nid);
$node->body[$node->language][0]['format'] = 'full_html'; // plain_text
node_save($node);
4
Ek Kosmos

Pour moi, ce qui suit a fonctionné:

update `field_revision_body` set `body_format` = 'new_body_forma' WHERE `bundle` = 'node_type'
update `field_data_body` set `body_format` = 'new_body_forma' WHERE `bundle` = 'node_type'

Bien sûr, vous devez changer le new_body_forma et le node_type

1
Ámon Tamás

Je suis juste tombé dans la même situation que Morten ici, avec une mise à niveau D6 => D7 qui, apparemment, n'a pas terminé les formats d'entrée.

A pris une approche plus grossière que les réponses déjà ici, et a écrit un module qui a parcouru le schéma de base de données et mis à jour toutes les colonnes qui contiennent la chaîne `` format '', remplaçant les valeurs de format D6 (1, 2, 3) par des noms de machine D7 ( filtered_html, full_html, plain_text).

https://Gist.github.com/xurizaemon/9824872

Codé en dur pour prendre en charge la cartographie des

1 => filtered_html, 
2 => full_html,
3 => plain_text,

Peut également essayer de réécrire les champs qui sont nommés 'format' (par exemple "date_format", mais si vous avez un format de date avec la valeur '2', c'est votre problème).

1
Chris Burgess
update field_revision_body set body_format = 'full_html' WHERE bundle IN ('book','page');
update field_data_body set body_format = 'full_html' WHERE bundle IN ('book','page');

a fait l'affaire pour moi. N'oubliez pas de vider les caches

0
duck

Vraisemblablement, vous voudrez savoir quels champs doivent être mis à jour, éventuellement pour effectuer une journalisation ou des vérifications sur les données. Pour ce faire, obtenez tous les noms de table et de colonne qui contiennent une colonne _format:

select distinct TABLE_NAME, column_name
from information_schema.columns
where TABLE_SCHEMA = 'my_drupal_database_name' and column_name like '%_format';

Armé de ces données, vous pouvez créer des requêtes distinctes à partir de ces valeurs. Vérifiez d'abord la sortie; vous devrez peut-être supprimer certaines entrées qui ne concernent pas le contenu/les révisions. Je recommande d'utiliser un éditeur compatible regex pour créer les requêtes. J'ai transformé les données en une grosse instruction select [...] union, Puis j'ai exécuté des requêtes de mise à jour contre elles.

L'utilisation de cette approche m'a fait gagner du temps lorsque j'ai dû mettre à jour des milliers de nœuds/révisions. N'oubliez pas de vider le cache de champ (NON couvert par drush cc all!):

field_cache_clear();

Ou avec drush:

drush sqlq "truncate table cache_field;"

Suppression également du filtre de texte

Si vous supprimez également un filtre de texte, vous devrez ensuite modifier le format de texte par défaut pour les TC dont les champs l'ont utilisé. Si vous ne le faites pas, vos utilisateurs recevront des messages d'autorisation refusée dans les champs qui ont utilisé le old_format. J'ai fait cette requête pour trouver les coupables:

select * from field_config_instance where `data` LIKE '%old_format%';

Pour effectuer les modifications, j'ai trouvé plus facile d'utiliser l'interface pour visiter chaque page de paramètres de champ et appuyez sur Enregistrer (les données sont stockées sous forme de longblob et étaient difficiles à rechercher et à remplacer en raison des meilleurs injections de données du module de formats). Même les champs dont le traitement de texte était défini sur Plain text Contenaient l'ancien format! Pour les champs dont le traitement de texte est défini sur Filtered text (user selects text format), vous devrez en outre sélectionner une nouvelle valeur par défaut et appuyer sur Enregistrer.

Vous devez vider le cache du filtre après avoir supprimé un filtre (encore une fois, non couvert par drush cc all!):

cache_clear_all('*', 'cache_filter', TRUE);

Ou avec drush:

drush sqlq "truncate table cache_filter;"
0
noobish

Vous pouvez utiliser le code suivant, si le module entity.module est installé.

// I'm using node_save($node); 
$wrapper = entity_metadata_wrapper('node', $node->nid); 
$wrapper->body->set(array('value' => body_text, 'format'=>'full_html'));
0