Zmień format wejściowy dla ponad 3000 węzłów

18

Mam wiele węzłów, które wymagają zmiany formatu wejściowego - mógłbym to zrobić ręcznie, ale nie zrobię tego przed Bożym Narodzeniem 2014.

Gdzie Drupal przechowuje te informacje? Jak mogę zmienić format wejściowy w ułamku sekundy za pomocą zapytania SQL?

Mortendk
źródło

Odpowiedzi:

20

Przedmówię tę odpowiedź, mówiąc, że wykonanie tego w całości stanowi potencjalne zagrożenie dla bezpieczeństwa, szczególnie jeśli zmieniasz format na bardziej łagodny zestaw filtrów. Formaty tekstowe modyfikują dane wyjściowe pola podczas wyświetlania, a nie podczas zapisywania. Na przykład wszelkie wcześniejsze znaki ucieczki HTML lub PHP przesłane do pola natychmiast wyrenderują / uruchomią, jeśli przypadkowo lub umyślnie ustawisz filtr na pełny kod HTML lub PHP.

Z tego powodu Drupal nie aktualizuje automatycznie wszystkich istniejących węzłów po zmianie formatu tekstu. Zachowanie formatów tekstowych w podobnych scenariuszach jest nadal kwestią otwartą .

Więc znowu: uważaj, są smoki.

Mając to na uwadze, każde pole przechowuje tekst jako kolumnę o nazwie field_foo_format, gdzie field_foojest nazwa maszyny pola. Musisz zaktualizować tę kolumnę w tabelach field_revision_field_fooi field_data_field_foo.

Wartością kolumny jest nazwa komputera zdefiniowana jako kolumna formatw filter_formattabeli. Tak więc aktualizacja wszystkich pól byłaby kwestią zapytania:

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

dla każdego pola, które wymaga zmiany.

Tutaj możesz określić new_formatwartość: http://YOURSITE.com/admin/config/content/formats - skonfiguruj link - numer lub ciąg w adresie URL to twoja new_format.Wyczyść pamięć podręczną po aktualizacji.

Kari Kääriäinen
źródło
1
Dobra odpowiedź. Należy również zrobić field_cache_clear();po zmianach field_data_...i field_revision_...stołów
milkovsky
4

Spróbuj w ten sposób, tworząc pętlę dla wszystkich węzłów określonego typu:

$node = node_load(nid);
$node->body[$node->language][0]['format'] = 'full_html'; // plain_text
node_save($node);
Ek Kosmos
źródło
1

Właśnie wpadłem na tę samą sytuację, co Morten tutaj, z aktualizacją D6 => D7, która najwyraźniej nie zakończyła formatów wejściowych.

Wybrałem bardziej surowe podejście niż odpowiedzi już tutaj i napisałem moduł, który przebiegł przez schemat DB i zaktualizował wszystkie kolumny zawierające ciąg „format”, zastępując wartości formatu D6 (1, 2, 3) nazwami maszyn D7 ( filtered_html, full_html, plain_text).

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

Zakodowane na stałe w celu obsługi mapowania

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

Może także spróbować przepisać pola o nazwie „format” (np. „Format_daty”, ale jeśli masz format daty o wartości „2”, to jest twój problem).

Chris Burgess
źródło
1

Dla mnie działało:

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'

Oczywiście musisz zmienić new_body_forma i typ_węzła

Ámon Tamás
źródło
To działało jak urok, ale musiałem wyczyścić skrzynki, aby zobaczyć efekt. Dziękuję Ci.
shasi kanth
0

Możesz użyć następującego kodu, jeśli masz zainstalowany moduł entity.module.

// I'm using node_save($node); 
$wrapper = entity_metadata_wrapper('node', $node->nid); 
$wrapper->body->set(array('value' => body_text, 'format'=>'full_html'));
Lee Seung Youn Carrie
źródło
0

Prawdopodobnie będziesz chciał wiedzieć, które pola wymagają aktualizacji, być może w celu zalogowania lub sprawdzenia danych. Aby to zrobić, uzyskaj wszystkie nazwy tabel i kolumn zawierające _formatkolumnę:

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

Uzbrojeni w te dane możesz tworzyć oddzielne zapytania od tych wartości. Najpierw sprawdź dane wyjściowe; może być konieczne usunięcie niektórych wpisów, które nie dotyczą treści / poprawek. Polecam użycie edytora obsługującego wyrażenia regularne do budowania zapytań. Przekształciłem dane w dużą select [...] unioninstrukcję, a następnie uruchomiłem przeciwko niej zapytania o aktualizację.

Takie podejście pozwoliło mi zaoszczędzić sporo czasu, gdy potrzebowałem zaktualizować tysiące węzłów / wersji. Pamiętaj, aby wyczyścić pamięć podręczną pola (NIE jest objęta drush cc all!):

field_cache_clear();

Lub z drush:

drush sqlq "truncate table cache_field;"

Usuwa także filtr tekstowy

Jeśli wycofujesz również filtr tekstowy, musisz zmienić domyślny format tekstu dla przekładników, które miały pola, które go używały. Jeśli tego nie zrobisz, użytkownicy otrzymają wiadomości o odmowie dostępu w polach, w których użyto old_format. Zrobiłem to zapytanie, aby znaleźć sprawców:

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

Aby wprowadzić zmiany, łatwiej mi było skorzystać z interfejsu, aby odwiedzić każdą stronę ustawień pola i nacisnąć Zapisz (dane są przechowywane jako longblob i nie można było wyszukiwać i zamieniać z powodu zastrzyków danych w lepszych formatach). Nawet pola z ustawionym przetwarzaniem tekstu Plain textzawierały stary_format! W przypadku pól, dla których ustawiono Przetwarzanie tekstu Filtered text (user selects text format), musisz dodatkowo wybrać nową wartość domyślną i nacisnąć Zapisz.

Powinieneś wyczyścić pamięć podręczną filtra po usunięciu filtra (ponownie, nie objęty drush cc all!):

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

Lub z drush:

drush sqlq "truncate table cache_filter;"
noobish
źródło
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');

zrobił dla mnie lewę. Nie zapomnij wyczyścić pamięci podręcznej

kaczka
źródło