Intereting Posts
Установить статус входа в систему? Миграция MultiSite на SSL: не обновляется медиабиблиотека У каждого слайда что-то не хватает в карусели Как сделать обновление постоянных ссылок из кода? При использовании javascript для динамического добавления текстового поля, как я могу отобразить его как редактор tinyMCE (в wordpress)? Подключиться к серверу с помощью SFTP вместо FTP / FTPS в WordPress Backup Каким типом являются шаблоны WP media-modal? Пользовательский список таксономии с детьми Как обновить выборочные параметры на странице настроек плагина Блокировка надписей навигации перед изменением заголовка? Вы очищаете свои самозанятые плагины при деактивации? Создание изображений из массива категорий Удаление размеров изображения из `the_content` Добавление пользовательских архивов типа записей в меню WordPress Позвольте пользователям загружать изображения (ы) в сообщение из внешнего интерфейса

Какова ваша наилучшая практика для выполнения одноразовых скриптов?

Проблема

Мы все были в подобной ситуации, и для многих вопросов на этом сайте нужно такое решение. Вы либо должны обновлять базу данных, автоматически вставлять много данных, конвертировать meta_keys или что-то подобное.

Конечно, в действующей системе, основанной на передовой практике, этого не должно произойти.

Но как бы то ни было, я хотел бы услышать ваше личное решение этой проблемы и почему вы выбрали свой.

Вопрос

Как реализовать одноразовые скрипты в вашей (запущенной) установке WordPress?

Проблема здесь в основном из-за следующих причин:

  • Сценарии, вставляющие данные, не должны запускаться более одного раза
  • Скрипты, требующие большого количества ресурсов, не должны запускаться в то время, когда их нельзя контролировать
  • Они не должны запускаться случайно

Причина, которую я задаю

У меня есть своя практика, я собираюсь опубликовать ее в ответах. Поскольку я не знаю, является ли это лучшим решением, я хотел бы узнать о вас. Кроме того, это вопрос, который задают много раз в контексте других вопросов, и было бы замечательно, если бы вы собрали идеи.

с нетерпением жду обучения от вас 🙂

Я для себя использую комбинацию:

  • один файл, посвященный одноразовому сценарию
  • используя переходный процесс, чтобы остановить скрипт от случайного запуска более одного раза
  • используя управление возможностями или пользовательский контроль, чтобы убедиться, что сценарий просто запущен мной.

Состав

Я использую файл ( onetime.php ) в моей включенной папке inc , которая включена в файл functions.php и удаляется оттуда после использования.

 include( 'inc/onetime.php' ); 

Файл для самого скрипта

В моей onetime.php моя функция f711_my_onetime_function() . Как может быть любая функция. Я предполагаю, что ваш скрипт проверен и работает правильно.

Чтобы добиться контроля над исполнением сценария, я использую оба

Контроль возможностей

Чтобы другие пользователи случайно не выполнили мой сценарий:

 if ( current_user_can( 'manage_options' ) ) // check for administrator rights 

или

 if ( get_current_user_id() == 711 ) // check if it is me - I prefer restricting the execution to me, not to all admins. 

переходный

чтобы не запускать сценарий несколько раз.

 $transient = 'f711_my_onetime_check'; if ( !get_transient( $transient ) ) // check if the function was not executed. 

Файл для выполнения скрипта в моей функции f711_my_onetime_function() будет выглядеть так:

 $transient = 'f711_my_onetime_check'; if ( get_current_user_id() == 711 && !get_transient( $transient ) ) { set_transient( $transient, 'locked', 600 ); // lock function for 10 Minutes add_action( 'wp_footer', 'f711_my_onetime_function' ); // execute my function on the desired hook. } function f711_my_onetime_function() { // all my glorious one-time-magic. } 

Причина, по которой я устанавливаю переходный процесс сразу после проверки, существует ли она, заключается в том, что я хочу, чтобы функция выполнялась после того, как скрипт был заблокирован от использования дважды.

Если мне нужен какой-либо вывод из моей функции, я либо распечатываю его как комментарий в нижнем колонтитуле, либо иногда даже фильтрую содержимое.

Время блокировки устанавливается в 10 минут, но может быть скорректировано с учетом ваших потребностей.

уборка

После успешного выполнения моего скрипта я удаляю include из functions.php и onetime.php с сервера. Поскольку я использовал тайм-аут для переходного процесса, мне не нужно очищать базу данных, но, конечно, вы также можете удалить переходный процесс после удаления файла.

Вы также можете сделать это:

запустите onetime.php и переименуйте его после выполнения.

 if ( current_user_can( 'manage_options' ) ) { if( ! file_exists( '/path/to/onetime.php' ) ) return; add_action( 'wp_footer', 'ravs_my_onetime_function' ); // execute my function on the desired hook. } function ravs_my_onetime_function() { // all my glorious one-time-magic. include( '/path/to/onetime.php' ); // after all execution rename your file; rename( '/path/to/onetime.php', '/path/to/onetime-backup.php'); } 

Я создал для него скрипт Phing для командной строки, ничего особенного, кроме загрузки внешнего скрипта для запуска. Причина, по которой я использовал его через CLI, заключается в следующем:

  • Я не хочу, чтобы он загружался по ошибке (нужно набрать команду)
  • Это безопасно, так как оно может быть запущено за пределами веб-корня, другими словами, это может повлиять на WP, но WP не может каким-либо образом достичь сценария.
  • Он не добавляет никакого кода в WP или сам БД.

 require('..path to ../wp-blog-header.php'); //bunch of WP globals define('WP_USE_THEMES', false); //custom code 

Таким образом, вы можете использовать Phing или PHP CLI и спать по ночам. WP-CLI также является хорошей альтернативой, хотя я забываю, если вы можете использовать его за пределами веб-корня.

Так как это популярный пост, вот пример скрипта: https://github.com/wycks/WordPhing (run.php)

Еще один довольно простой способ запуска одноразового скрипта – сделать это с помощью MU-плагина.

Поместите код в некоторый PHP-файл (например, one-time.php ), который вы загружаете в папку плагинов MU (по умолчанию /wp-content/mu-plugins ), настраиваете права доступа к файлам, запускаете плагин (то есть, согласно к выбранному вами крюку, вам в основном просто нужно посетить интерфейс / бэкэнд), и все готово.

Вот шаблон:

 /** * Main (and only) class. */ class OneTimeScript { /** * Plugin function hook. * * @type string */ public static $hook = 'init'; /** * Plugin function priority. * * @type int */ public static $priority = 0; /** * Run the one-time script. * * @hook self::$hook * @return void */ public static function run() { // one-time action goes here... // clean up add_action('shutdown', array(__CLASS__, 'unlink'), PHP_INT_MAX); } // function run /** * Remove the file. * * @hook shutdown * @return void */ public static function unlink() { unlink(__FILE__); } // function unlink } // class OneTimeScript add_action(OneTimeScript::$hook, array('OneTimeScript', 'run'), OneTimeScript::$priority); 

Без комментариев и всего, он выглядит примерно так:

 class OneTimeScript { public static $hook = 'init'; public static $priority = 0; public static function run() { // one-time action goes here... add_action('shutdown', array(__CLASS__, 'unlink'), PHP_INT_MAX); } // function run public static function unlink() { unlink(__FILE__); } // function unlink } // class OneTimeScript add_action(OneTimeScript::$hook, array('OneTimeScript', 'run'), OneTimeScript::$priority); 

Иногда я использовал функцию, подключенную к отключению плагина.

См. Здесь Обновить старые ссылки Довольно перманентные Пользовательский тип сообщения

Когда только админы могут активировать плагины, есть возможность проверки в качестве побочного эффекта.

Нет необходимости удалять файл после деактивации, он не будет включен в wordress. В зависимости от того, хотите ли вы снова запустить его, вы можете. Активизация и деактивация снова.

И иногда я использовал переходный процесс, как в ответ @fischi. Например, здесь запрос для создания продуктов woocommerce из изображений или здесь. Удалить / заменить теги img в опубликованном сообщении для автоматически опубликованных сообщений.

Комбинация обоих может быть альтернативой.

В идеальных условиях я бы сделал ssh на сервере и сам выполнил функцию, используя wp-cli.

Однако это часто невозможно, поэтому я стараюсь установить переменную $ _GET и привязать ее к «init», например:

 add_action( 'init', function() { if( isset( $_GET['one_time'] ) && $_GET['one_time'] == 'an_unlikely_string' ) { do_the_one_time_thing(); } }); 

затем нажмите

 http://my_blog.com/?one_time=an_unlikely_string 

и отключите крючок, когда это будет сделано.

Определенно вы можете, Просто создайте свой один временной код в качестве плагина.

 add_action('admin_init', 'one_time_call'); function one_time_call() { /* YOUR SCRIPTS */ deactivate_plugins('onetime/index.php'); //deactivate current plugin } 

Проблема в том, как активировать этот плагин без нажатия ссылки «Активировать»?

просто добавьте activate_plugins('onetime/index.php'); в functions.php

или Использование должно использовать плагины, http://codex.wordpress.org/Must_Use_Plugins

Попробуйте с различными действиями, например, когда вы хотите выполнить onetime-плагин,

  1. admin_init – после запуска admin

  2. init – wordpress init

  3. wp – при загрузке wordpress

Другой способ – установить глобальное wp_option, когда работа будет выполнена, и проверить эту опцию каждый раз, когда выполняется инициализационный крючок.

 function my_one_time_function() { // Exit if the work has already been done. if ( get_option( 'my_one_time_function', '0' ) == '1' ) { return; } /***** DO YOUR ONE TIME WORK *****/ // Add or update the wp_option update_option( 'my_one_time_function', '1' ); } add_action( 'init', 'my_one_time_function' ); 

Естественно, вам не нужно иметь этот код навсегда (даже если это простое чтение из базы данных), поэтому вы можете, возможно, удалить код, когда работа будет выполнена. Также вы можете вручную изменить это значение параметра на 0, если вам нужно повторно выполнить код.

Мой подход немного отличается от этого. Мне нравится добавлять мой одноразовый скрипт в качестве функции в function.php моей темы и запускать его по определенному запросу GET.

 if ( isset($_GET['linkupdate']) ) { add_action('init', 'link_update', 10); } function link_update() { // One Time Script die; } 

Чтобы запустить это, просто посетите URL-адрес «www.sitename.com/?linkupdate»,

Это прекрасно работает для меня до сих пор …

Имеет ли этот метод какие-либо недостатки? Просто интересуюсь…

Я просто использую одну настраиваемую страницу шаблона продукта, которую я не использую, и не связан ни с чем на общедоступном сервере.

Например, если у меня есть страница с отзывами, которая не является живой (в режиме черновика или что-то еще), но связана с одним шаблоном страницы, например single-testimonial.php – я могу размещать там функции, загружать страницу через preview и функция или что-то еще запускается один раз. Также очень легко внести изменения в функцию в случае отладки.

Это очень просто, и я предпочитаю его использовать init потому что у меня больше контроля над тем, когда и как его запускают. Просто мои предпочтения.