Intereting Posts
Получить регистрацию параметров wp_customize в интерфейсе Альтернативное изображение заголовка Задайте 3 строки в строке Пользовательские канонические URL-адреса Отсортировать все сообщения по названию категории в панели администратора? Найти и заменить доменное имя на лету? Страница результатов поиска – отображение пользовательских мета-полей Крючки для автоматической установки видимости продуктов, относящихся к определенной категории, только для каталогов Установка WordPress в корневой каталог с существующим статическим сайтом. Опасения? Исключить всюду, кроме области администратора? Вставить тег тега функции insde Меню удаляет все элементы и положение – ошибка в WordPress? Фиксированные значения для одинаковых почтовых переводов Wp Remote получить с ручной перенаправлением Как отобразить все изображения «Загружено» автором

Импорт XML-файла WordPress изнутри Functions.php

Я разрабатываю тему, которая имеет другой способ добавления содержимого, и поэтому установка WordPress по умолчанию не будет отображать контент из-за этого. Мне было интересно, можно ли автоматически импортировать XML-файл с помощью внутренней функции и или перехватчиков после активации темы?

Пользователь устанавливает тему > Пользователь активирует тему > Код за кулисами загружает XML-файл и выполняет бесшумный импорт его содержимого

В настоящее время для импорта XML-файла вам необходимо установить плагин импортера WordPress для WordPress, а затем вручную импортировать файл, выбрать пользователя для связывания импортированного контента и решить, хотите ли вы импортировать вложения мультимедиа. Я нахожу этот шаг для типов клиентов, на которых я настроен слишком запутанно, и хотел бы эффективно устранить необходимость этого шага.

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

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

Заранее спасибо.

Редактировать / Разъяснение

Здесь, похоже, много путаницы. Я не спрашиваю, как проверить, активирована ли тема, у меня эта часть отсортирована. Я спрашиваю, как я буду разбирать файл импорта XML и автоматически импортировать его без усилий пользователя. Я по сути хочу автоматизировать плагин импорта WordPress, который вы уже можете использовать, чтобы вручную импортировать XML-файл, выбрать автора, выбрать загрузку и импорт вложений в моих functions.php.

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

Solutions Collecting From Web of "Импорт XML-файла WordPress изнутри Functions.php"

Ваш вопрос немного специфичен, если вы «только» хотите автоматически импортировать некоторые сообщения / страницы. Существуют и другие способы сделать это, используя файл экспорта XML.

Если у вас есть только текстовые сообщения, вы должны использовать LOAD DATA INFILE . Сначала вы должны экспортировать свои сообщения.

global $wpdb, $wp_filesystem; $tables = array( 'posts' => array( 'posts', 'postmeta' ), 'comments' => array( 'comments', 'commentmeta' ), 'terms' => array( 'terms', 'term_taxonomy', 'term_relationships' ), 'users' => array( 'user', 'usermeta' ), 'links' => array( 'links' ), 'options' => array( 'options' ), 'other' => array(), // for multiside 'multiside' => array( 'blogs', 'signups', 'site', 'sitemeta', 'sitecategories', 'registration_log', 'blog_versions' ) ); $exports = array( 'posts', 'comments', 'users' ); $exportdir = TEMPLATEPATH . '/export'; if ( ! is_dir( $exportdir ) ) { $mkdir = wp_mkdir_p( $exportdir ); if ( false == $mkdir || ! is_dir( $exportdir ) ) throw new Exception( 'Cannot create export directory. Aborting.' ); } // empty the export dir else MySQL throws errors $files = glob( $exportdir . '/*' ); if ( ! empty( $files ) ) { foreach( $files as $file ) unlink( $file ); } foreach ( $exports as $export ) { if ( ! isset( $tables[$export] ) ) continue; if ( ! empty( $tables[$export] ) ) { foreach ( $tables[$export] as $table ) { $outfile = sprintf( '%s/%s_dump.sql', $exportdir, $table ); $sql = "SELECT * FROM {$wpdb->$table} INTO OUTFILE '%s'"; $res = $wpdb->query( $wpdb->prepare( $sql, $outfile ) ); if ( is_wp_error( $res ) ) echo "<p>Cannot export {$table} into {$outfile}</p>"; } } } 

Это создаст каталог в вашей папке темы (убедитесь, что он доступен для записи!) И экспортирует сообщения и комментарии (с его мета) в файлы дампа. Используйте export массива, чтобы определить, что вы хотите экспортировать. Я сгруппировал большинство вещей более или менее логично (если вы хотите экспортировать сообщения, чем вы также должны экспортировать postmeta и т. Д.).

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

Теперь вы хотите импортировать этот материал в новый блог

 global $wpdb; $exportdir = TEMPLATEPATH . '/export'; $files = glob( $exportdir . '/*_dump.sql' ); foreach ( $files as $file ) { preg_match( '#/([^/]+)_dump.sql$#is', $file, $match ); if ( ! isset( $match[1] ) ) continue; $sql = "LOAD DATA LOCAL INFILE '%s' INTO TABLE {$wpdb->$match[1]};"; $res = $wpdb->query( $wpdb->prepare( $sql, $file ) ); if ( is_wp_error( $res ) ) echo "<p>Cannot import data from file {$file} into table {$wpdb->$match[1]}</p>"; } 

Это решение хорошо, если сообщения не содержат вложений, таких как изображения. Другая проблема заключается в том, что ни один пользователь и никакие категории не будут импортированы. Убедитесь, что оба они созданы до начала импорта (или включают пользователей и категории в ваш экспорт). Это очень грубый метод для импорта вещей, он переопределит существующие вещи!

Если вы также хотите экспортировать вложения, вам нужно немного поработать.

(Sidenote: Пожалуйста, прочитайте полный ответ и самые последние слова в конце! Эта тема не для новичков, и я не пишу предупреждение на каждую рискованную строку кода)

WordPress Importer Plugin, кажется, хороший способ импортировать весь материал и автоматически импортировать / загружать вложения. Итак, давайте посмотрим, что сделает этот плагин.

Сначала плагин просит загрузить файл XML. Затем он анализирует XML-файл и запрашивает сопоставление автора, и если вложения должны быть загружены или нет.

Для автоматического запуска плагина нам нужно изменить некоторые вещи. Сначала нам нужно пропустить процесс загрузки. Это довольно просто, потому что вы можете связать XML-файл с темой, и вы знаете, где находится файл XML. Затем мы должны пропустить вопросы, которые появляются после загрузки XML-файла. Мы можем предопределить наши собственные значения и передать их процессу импорта.

Начните с копии плагина. Создайте каталог в своей теме, например autoimport и скопируйте файлы wordpress-importer.php и parsers.php . Это хорошая идея переименовать файл wordpress-importer.php в нечто вроде autoimporter.php . В вашей функции темы добавьте вызов функции для запуска автоматизированного impoprt

 /** * Auto import a XML file */ add_action( 'after_setup_theme', 'autoimport' ); function autoimport() { // get the file require_once TEMPLATEPATH . '/autoimport/autoimporter.php'; if ( ! class_exists( 'Auto_Importer' ) ) die( 'Auto_Importer not found' ); // call the function $args = array( 'file' => TEMPLATEPATH . '/autoimport/import.xml', 'map_user_id' => 1 ); auto_import( $args ); } 

Сначала мы устанавливаем некоторые аргументы. Прежде всего, это полный путь к XML-файлу. Второй – это идентификатор существующего пользователя. Нам нужен этот пользователь для сопоставления авторов, это тот пользователь, где будут отображаться все сообщения, если не будут созданы новые авторы.

Теперь мы должны понять, как работает плагин. Откройте переименованный файл плагина и прокрутите вниз до конца. Существует функция wordpress_importer_init() и вызов действия. Удалите оба, это больше не нужно. Теперь перейдите в верхнюю часть файла и удалите заголовок плагина (комментарий в начале файла). После этого переименуйте класс WP_Importer в нечто вроде Auto_Importer , не забудьте настроить оператор function_exists и первый метод WP_Importer (это конструктор в стиле PHP4).

Позже мы передадим XML-файл непосредственно конструктору класса, изменим первый метод на этот

 var $xmlfile = ''; var $map_user_id = 0; function Auto_Importer( $args ) { if ( file_exists( $args['file'] ) ) { // for windows systems $file = str_replace( '\\', '/', $args['file'] ); $this->xmlfile = $file; } if ( isset( $args['map_user_id'] ) ) $this->map_user_id = $args['map_user_id']; } 

Теперь у нас есть, чтобы удалить и изменить некоторые методы внутри класса. Первый метод – метод dispatch() . Этот метод говорит вам, как работает класс. Он выполняет три шага. Сначала загрузите XML-файл, затем обработайте его и, наконец, импортируйте данные.

Нулевой случай – это первый шаг, это приветствие. Это та часть, которую вы видите, если вы впервые вызываете импорт. Он попросит загрузить файл. Второй случай обрабатывает загрузку и отображает форму для параметров импорта. Дело три, наконец, импорт. Другими словами: первые два шага требуют только данных, которые мы можем предоставить сами. Нам нужен только шаг 3 (случай 2) и должен предоставить данные, заданные на шагах 1 и 2.

На wp_import_handle_upload() шаге вы видите вызов функции wp_import_handle_upload() . Эта функция устанавливает некоторые сведения о файле xml. Мы больше не можем использовать эту функцию, потому что мы не загрузили файл. Поэтому мы должны скопировать и изменить функцию. Создайте новый метод внутри класса

 function import_handle_upload() { $url = get_template_directory_uri() . str_replace( TEMPLATEPATH, '', $this->xmlfile ); $type = 'application/xml'; // we know the mime type of our file $file = $this->xmlfile; $filename = basename( $this->xmlfile ); // Construct the object array $object = array( 'post_title' => $filename, 'post_content' => $url, 'post_mime_type' => $type, 'guid' => $url, 'context' => 'import', 'post_status' => 'private' ); // Save the data $id = wp_insert_attachment( $object, $file ); // schedule a cleanup for one day from now in case of failed import or missing wp_import_cleanup() call wp_schedule_single_event( time() + DAY_IN_SECONDS, 'importer_scheduled_cleanup', array( $id ) ); return array( 'file' => $file, 'id' => $id ); } 

И замените вызов функции $file = wp_import_handle_upload(); в методе handle_upload() с нашим новым методом $file = $this->import_handle_upload();

Теперь мы заменили процесс загрузки собственным файлом (который уже должен существовать). Продолжайте и удалите ненужные методы. Методы gereet() , header() и footer() больше не нужны (верхний и нижний колонтитулы только печатают некоторый текст) и могут быть удалены из класса. В методе dispatch() удалите вызовы этих методов ( $this->header() и $this->footer() ).

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

Первая часть проста. Установите значение true, если вложения должны быть загружены или false, если нет. Сопоставление автора немного сложнее. Если разрешено создавать новых пользователей (авторов из файла импорта), создайте их. Если нет, назначьте сообщения существующим пользователям. Это было сделано в методе get_author_mapping() . Мы должны заменить данные $_POST существующими данными. Здесь нам нужно простое решение, поэтому мы просто сопоставляем всех новых авторов с существующим, если не разрешено создавать новых пользователей. Или просто создайте всех новых пользователей. Во втором случае убедитесь, что все новые пользователи являются фиктивными пользователями. Если нет, каждый раз, когда вы их импортируете, они получают электронное письмо с логином и паролем в новый блог! Я не объясняю каждую строку кода, вот полный переписанный метод

 function get_author_mapping( $map_users_id ) { if ( empty( $this->authors ) ) return; $create_users = $this->allow_create_users(); foreach ( (array) $this->authors as $i => $data ) { $old_login = $data['author_login']; // Multisite adds strtolower to sanitize_user. Need to sanitize here to stop breakage in process_posts. $santized_old_login = sanitize_user( $old_login, true ); $old_id = isset( $this->authors[$old_login]['author_id'] ) ? intval($this->authors[$old_login]['author_id']) : false; if ( ! $create_users ) { $user = get_userdata( intval($map_users_id) ); if ( isset( $user->ID ) ) { if ( $old_id ) $this->processed_authors[$old_id] = $user->ID; $this->author_mapping[$santized_old_login] = $user->ID; } } else if ( $create_users ) { if ( ! empty($this->authors[$i]) ) { $user_id = wp_create_user( $this->authors[$i]['author_login'], wp_generate_password() ); } else if ( $this->version != '1.0' ) { $user_data = array( 'user_login' => $old_login, 'user_pass' => wp_generate_password(), 'user_email' => isset( $this->authors[$old_login]['author_email'] ) ? $this->authors[$old_login]['author_email'] : '', 'display_name' => $this->authors[$old_login]['author_display_name'], 'first_name' => isset( $this->authors[$old_login]['author_first_name'] ) ? $this->authors[$old_login]['author_first_name'] : '', 'last_name' => isset( $this->authors[$old_login]['author_last_name'] ) ? $this->authors[$old_login]['author_last_name'] : '', ); $user_id = wp_insert_user( $user_data ); } if ( ! is_wp_error( $user_id ) ) { if ( $old_id ) $this->processed_authors[$old_id] = $user_id; $this->author_mapping[$santized_old_login] = $user_id; } else { printf( __( 'Failed to create new user for %s. Their posts will be attributed to the current user.', 'wordpress-importer' ), esc_html($this->authors[$old_login]['author_display_name']) ); if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG ) echo ' ' . $user_id->get_error_message(); echo '<br />'; } } // failsafe: if the user_id was invalid, default to the current user if ( ! isset( $this->author_mapping[$santized_old_login] ) ) { if ( $old_id ) $this->processed_authors[$old_id] = (int) get_current_user_id(); $this->author_mapping[$santized_old_login] = (int) get_current_user_id(); } } } 

Остается некоторая работа. Добавление функции auto_import() сначала

 function auto_import( $args ) { $defaults = array( 'file' => '', 'map_user_id' => 0); $args = wp_parse_args( $args, $defaults ); $autoimport = new Auto_Importer( $args ); $autoimport->do_import(); } 

Поместите эту функцию после класса. Эта функция пропускает некоторые ошибки обработки и проверки (например, для пустого аргумента файла).

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

 if ( ! defined( 'WP_LOAD_IMPORTERS' ) ) return; 

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

 $required = array( 'post_exists' => ABSPATH . 'wp-admin/includes/post.php', 'wp_generate_attachment_metadata' => ABSPATH . 'wp-admin/includes/image.php', 'comment_exists' => ABSPATH . 'wp-admin/includes/comment.php' ); foreach ( $required as $func => $req_file ) { if ( ! function_exists( $func ) ) require_once $req_file; } 

В основном все. Я тестирую это на локальной установке с тестовыми данными XML из WordPress. Он работает для меня, но это не идеальное решение для производства!

И некоторые последние слова о настройке некоторых параметров. Существует два варианта, которые могут быть изменены фильтром:

 add_filter( 'import_allow_create_users', function() { return false; } ); add_filter( 'import_allow_fetch_attachments', '__return_false' ); 

Думаю, мне не нужно это объяснять. Поместите эти фильтры в свои functions.php и настройте true или false (первый – стиль PHP5.3, второй – стиль WP).

Очень последние слова

Я вложил все это в суть . Используйте его на свой страх и риск! Я ничего не несу! , Пожалуйста, взгляните на файлы в сущности, я не объяснял каждый маленький шаг здесь.

Думает, что я еще не сделал: задайте значение, например, в параметрах (темы) после импорта. Кроме того, импорт начинается каждый раз, когда тема будет активирована.

Возможно, я буду работать над этим в будущем, очистить некоторые вещи и провести на нем больше тестов.

Позвольте мне повторить 2 вещи здесь:

(а) «Я не спрашиваю, как … У меня эта часть отсортирована …»

»» Я со временем научился быть в порядке с тем, что подход к проблемам / исправлениям не обязательно требует некоторой «видимой ассоциации» с проблемой.

(б) «… я должен был бы сделать, чтобы вырезать части …» «… клиенты торговцы, так что даже что-то простое …»

»» Почему проще для клиента за счет затруднения для себя? Я мог бы предложить «услуги» после результатов и установить удаленное соединение, чтобы сделать это для них [платный], вместо «… взломать плагин импорта …». Я имею в виду, спросите себя, действительно ли это стоит в вашей нынешней схеме вещей. Однако, если вы готовы приложить усилия, попробуйте сделать снимок кода ниже. Если вы можете, то:

  • сначала возьмите основы и лучше понимайте БД
  • иметь удобную ссылку для всех функций – старый – это золото
  • иметь удобную ссылку для всех крючков – упростить упростить

Я согласен с обоими chrisguitarguy и amolv выше.

Как сказал Крис, количество способов достижения результата – это много. Это всего лишь одно. Хотя у этого есть потенциал, чтобы стать трудоемким, действительно обращайтесь к последним парам строк перед чем-либо еще.

 <?php /* I usually dump ONE line in functions.php */ require_once (TEMPLATEPATH . '/includes/whatever.php'); /* and then in that loc CHECK FIRST*/ if ((is_admin() && isset($_GET['activated']) && $pagenow == 'themes.php')||(is_admin() && isset($_GET['upgrade']) && $pagenow == 'admin.php' && $_GET['page'] == 'admin-options.php')) { global $wpdb, $wp_rewrite, $hey; // create tables your_tables(); // insert value defaults your_values(); // insert link defaults your_links(); // pages and tpl your_pages(); // create category or categories // wp_create_categories $categories, $post_id = '' // wp_create_category $cat_name, $parent //flush rewrite $wp_rewrite->flush_rules(); } // create them db tables function your_tables() { global $wpdb, $hey; $collate = ''; if($wpdb->supports_collation()) { if(!empty($wpdb->charset)) $collate = "DEFAULT CHARACTER SET $wpdb->charset"; if(!empty($wpdb->collate)) $collate .= " COLLATE $wpdb->collate"; } $sql = "CREATE TABLE IF NOT EXISTS ". $wpdb->prefix . "table1_name" ." ( `id` INT(10) NOT NULL auto_increment, `some_name1` VARCHAR(255) NOT NULL, `some_name2` VARCHAR(255) NOT NULL, `some_name3` LONGTEXT, `some_name4` LONGTEXT NOT NULL, `some_name5` VARCHAR(255) DEFAULT NULL, `some_name6` VARCHAR(255) DEFAULT NULL, `some_name7` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', `some_name8` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY id (`id`)) $collate;"; $wpdb->query($sql); $sql = "CREATE TABLE IF NOT EXISTS ". $wpdb->prefix . "table2_name" ." ( `meta_id` INT(10) NOT NULL AUTO_INCREMENT, `some_name1` INT(10) NOT NULL, `some_name2` INT(10) NOT NULL, `some_name3` VARCHAR(255) NOT NULL, `some_name4` INT(10) NOT NULL, PRIMARY KEY id (`meta_id`)) $collate;"; $wpdb->query($sql); // and so on and so forth /* Insert default/ALL data into tables */ // BUT CHECK FIRST IF DATA EXISTS. IF = YES DONT PUSH IN ANYTHING $sql = "SELECT field_id " . "FROM " . $wpdb->prefix . "table1_name LIMIT 1"; $wpdb->get_results($sql); if($wpdb->num_rows == 0) { // more code will follow // i have to get going now } ?> 

ЗАМЕТКА

  • Если вы были с WP на какое-то время, то не стоит упоминать BACK UP YOUR DB FIRST .

  • phpMyAdmin имеет сырую мощность и делает его довольно простым, чтобы тщательно вкрутить все.

  • Хотя требуемое усилие может показаться сложным изначально, если все сделано правильно, вы можете заставить его функционировать, как часы …

в заключение

Как нажимать 2000 строк данных за 20 секунд на эти последние 2 строки в пределах этих двух брекетов?

phpMyAdmin »Выбрать БД слева» »Выбрать все ТАБЛИЦЫ справа» »Экспорт ▼

 ➝ Custom: display all options ➝ View output as text = ON ➝ Save output to a file = OFF ➝ Compression = NONE ➝ Format = SQL ➝ Dump Table = STRUCTURE & DATA ➝ Add DROP TABLE... = OFF (Important!) ➝ Syntax to use = "both of the above" »» GO! 
  • На следующем экране я мог бы скопировать часть «СТРУКТУРА» в $ sql = "…." для your_tables() и части DATA в $sql для your_data()

  • Для остальных WP по умолчанию я использую update_option(...) и update_post_meta(...)

Нет никакого эквивалента темы register_activation_hook для плагинов – есть несколько хаков . Зачем? Потому что тема – это кожа. Только функциональность, специально связанная с отображением контента, должна идти по теме, а не по содержанию.

Насколько это возможно: используйте приведенный выше пример для запуска функции обратного вызова один раз. Импортер WordPress работает с XML-файлами, существует множество различных способов анализа XML в PHP. Возьмите свой выбор, проанализируйте файл, сделайте то, что вы хотите с ним.

в функции functions.php можно проверить

 if( isset($_GET['activated']) && 'themes.php' == $GLOBALS['pagenow']) ) { // check duplicates // call import class //xml import code // do whatever you want to } 

Как только ваша тема активируется, вы автоматически импортируете данные.