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

18

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ù Drupal stocke-t-il ces informations? Comment puis-je changer le format d'entrée en une fraction de seconde, avec une requête SQL?

mortendk
la source

Réponses:

20

Je vais préfacer cette réponse en disant que faire cela en masse présente un risque potentiel pour la sécurité, 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 ou PHP précédemment échappé soumis à un champ sera rendu / exécuté directement si vous définissez accidentellement ou intentionnellement le filtre sur du code HTML ou PHP complet.

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

Encore une fois: méfiez-vous, il y a des dragons.

Cela dit, chaque champ stocke le texte dans une colonne nommée field_foo_format, où field_fooest le nom de l'ordinateur du champ. Vous devrez mettre à jour cette colonne sur les tables field_revision_field_fooet field_data_field_foo.

La valeur de la colonne est un nom d'ordinateur défini comme colonne formatde la filter_formattable. 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 new_formatvaleur 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.cache vide après la mise à jour.

Kari Kääriäinen
la source
1
Bonne réponse. Vous devriez également faire field_cache_clear();après les changements field_data_...et les field_revision_...tableaux
milkovsky
4

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);
Ek Kosmos
la source
1

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).

Chris Burgess
la source
1

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

Ámon Tamás
la source
Cela a fonctionné comme un charme, mais j'ai dû vider les caches pour voir l'effet. Je vous remercie.
shasi kanth
0

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'));
Lee SeungYoun Carrie
la source
0

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 _formatcolonne:

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 construire les requêtes. J'ai transformé les données en une grosse select [...] uniondéclaration, 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 obtiendront 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 pour Plain textcontenir l'ancien format! Pour les champs pour lesquels 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;"
noobish
la source
0
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

canard
la source