mirror of
https://git.sindominio.net/estibadores/wordpress.git
synced 2024-11-14 23:21:07 +01:00
3318 lines
102 KiB
PHP
3318 lines
102 KiB
PHP
<?php
|
||
|
||
/**
|
||
* The admin-specific functionality of the plugin.
|
||
*
|
||
* @link https://wordpress.org/plugins/fg-spip-to-wp/
|
||
* @since 1.0.0
|
||
*
|
||
* @package FG_Spip_to_WordPress
|
||
* @subpackage FG_Spip_to_WordPress/admin
|
||
*/
|
||
|
||
if ( !class_exists('FG_Spip_to_WordPress_Admin', false) ) {
|
||
|
||
define('_RACCOURCI_TH_SPAN', '\s*(:?{{[^{}]+}}\s*)?|<'); // Pattern for table shortcodes replacement
|
||
|
||
/**
|
||
* The admin-specific functionality of the plugin.
|
||
*
|
||
* @package FG_Spip_to_WordPress
|
||
* @subpackage FG_Spip_to_WordPress/admin
|
||
* @author Frédéric GILLES
|
||
*/
|
||
class FG_Spip_to_WordPress_Admin extends WP_Importer {
|
||
|
||
const IMPORT_TIMEOUT = 7200; // Timeout = 2 hours
|
||
|
||
/**
|
||
* The ID of this plugin.
|
||
*
|
||
* @since 1.0.0
|
||
* @access private
|
||
* @var string $plugin_name The ID of this plugin.
|
||
*/
|
||
private $plugin_name;
|
||
|
||
/**
|
||
* The version of this plugin.
|
||
*
|
||
* @since 1.0.0
|
||
* @access private
|
||
* @var string $version The current version of this plugin.
|
||
*/
|
||
private $version;
|
||
|
||
public $spip_version; // SPIP version
|
||
public $spip_charset; // SPIP characters set
|
||
public $plugin_options; // Plug-in options
|
||
public $progressbar;
|
||
public $imported_categories = array();
|
||
public $chunks_size = 10;
|
||
public $posts_count = 0; // Number of imported posts
|
||
public $pages_count = 0; // Number of imported pages
|
||
public $media_count = 0; // Number of imported medias
|
||
public $media_path;
|
||
public $post_type = 'post'; // post or page
|
||
|
||
protected $faq_url; // URL of the FAQ page
|
||
protected $notices = array(); // Error or success messages
|
||
protected $cat_prefix = 'spip_cat_';
|
||
|
||
private $log_file;
|
||
private $log_file_url;
|
||
private $test_antiduplicate = false;
|
||
|
||
/**
|
||
* Initialize the class and set its properties.
|
||
*
|
||
* @since 1.0.0
|
||
* @param string $plugin_name The name of this plugin.
|
||
* @param string $version The version of this plugin.
|
||
*/
|
||
public function __construct( $plugin_name, $version ) {
|
||
|
||
$this->plugin_name = $plugin_name;
|
||
$this->version = $version;
|
||
$this->faq_url = 'https://wordpress.org/plugins/fg-spip-to-wp/faq/';
|
||
|
||
$upload_dir = wp_upload_dir();
|
||
$this->log_file = $upload_dir['basedir'] . '/' . $this->plugin_name . '.logs';
|
||
$this->log_file_url = $upload_dir['baseurl'] . '/' . $this->plugin_name . '.logs';
|
||
// Replace the protocol if the WordPress address is wrong in the WordPress General settings
|
||
if ( is_ssl() ) {
|
||
$this->log_file_url = preg_replace('/^https?/', 'https', $this->log_file_url);
|
||
}
|
||
|
||
// Progress bar
|
||
$this->progressbar = new FG_Spip_to_WordPress_ProgressBar($this);
|
||
}
|
||
|
||
/**
|
||
* The name of the plugin used to uniquely identify it within the context of
|
||
* WordPress and to define internationalization functionality.
|
||
*
|
||
* @since 1.0.0
|
||
* @return string The name of the plugin.
|
||
*/
|
||
public function get_plugin_name() {
|
||
return $this->plugin_name;
|
||
}
|
||
|
||
/**
|
||
* Register the stylesheets for the admin area.
|
||
*
|
||
* @since 1.0.0
|
||
*/
|
||
public function enqueue_styles() {
|
||
|
||
wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/fg-spip-to-wp-admin.css', array(), $this->version, 'all' );
|
||
|
||
}
|
||
|
||
/**
|
||
* Register the JavaScript for the admin area.
|
||
*
|
||
* @since 1.0.0
|
||
*/
|
||
public function enqueue_scripts() {
|
||
|
||
wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/fg-spip-to-wp-admin.js', array( 'jquery', 'jquery-ui-progressbar' ), $this->version, false );
|
||
wp_localize_script( $this->plugin_name, 'objectL10n', array(
|
||
'delete_imported_data_confirmation_message' => __( 'All previously imported data will be deleted from WordPress.', 'fg-spip-to-wp' ),
|
||
'delete_all_confirmation_message' => __( 'All content will be deleted from WordPress.', 'fg-spip-to-wp' ),
|
||
'delete_no_answer_message' => __( 'Please select a remove option.', 'fg-spip-to-wp' ),
|
||
'import_completed' => __( 'IMPORT COMPLETED', 'fg-spip-to-wp' ),
|
||
'content_removed_from_wordpress' => __( 'Content removed from WordPress', 'fg-spip-to-wp' ),
|
||
'settings_saved' => __( 'Settings saved', 'fg-spip-to-wp' ),
|
||
'importing' => __( 'Importing…', 'fg-spip-to-wp' ),
|
||
'import_stopped_by_user' => __( 'IMPORT STOPPED BY USER', 'fg-spip-to-wp' ),
|
||
'internal_links_modified' => __( 'Internal links modified', 'fg-spip-to-wp' ),
|
||
) );
|
||
wp_localize_script( $this->plugin_name, 'objectPlugin', array(
|
||
'log_file_url' => $this->log_file_url,
|
||
'progress_url' => $this->progressbar->get_url(),
|
||
));
|
||
|
||
}
|
||
|
||
/**
|
||
* Initialize the plugin
|
||
*/
|
||
public function init() {
|
||
register_importer('fg-spip-to-wp', __('SPIP', 'fg-spip-to-wp'), __('Import categories, articles, news and images from a SPIP database into WordPress', 'fg-spip-to-wp'), array($this, 'importer'));
|
||
}
|
||
|
||
/**
|
||
* Display the stored notices
|
||
*
|
||
* @since 2.0.0
|
||
*/
|
||
public function display_notices() {
|
||
foreach ( $this->notices as $notice ) {
|
||
echo '<div class="' . $notice['level'] . '"><p>[' . $this->plugin_name . '] ' . $notice['message'] . "</p></div>\n";
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Write a message in the log file
|
||
*
|
||
* @since 2.0.0
|
||
*
|
||
* @param string $message
|
||
*/
|
||
public function log($message) {
|
||
file_put_contents($this->log_file, "$message\n", FILE_APPEND);
|
||
}
|
||
|
||
/**
|
||
* Store an admin notice
|
||
*/
|
||
public function display_admin_notice( $message ) {
|
||
$this->notices[] = array('level' => 'updated', 'message' => $message);
|
||
error_log('[INFO] [' . $this->plugin_name . '] ' . $message);
|
||
$this->log($message);
|
||
}
|
||
|
||
/**
|
||
* Store an admin error
|
||
*/
|
||
public function display_admin_error( $message ) {
|
||
$this->notices[] = array('level' => 'error', 'message' => $message);
|
||
error_log('[ERROR] [' . $this->plugin_name . '] ' . $message);
|
||
$this->log('[ERROR] ' . $message);
|
||
}
|
||
|
||
/**
|
||
* Store an admin warning
|
||
*/
|
||
public function display_admin_warning( $message ) {
|
||
$this->notices[] = array('level' => 'error', 'message' => $message);
|
||
error_log('[WARNING] [' . $this->plugin_name . '] ' . $message);
|
||
$this->log('[WARNING] ' . $message);
|
||
}
|
||
|
||
/**
|
||
* Run the importer
|
||
*
|
||
* @since 2.0.0
|
||
*/
|
||
public function importer() {
|
||
$feasible_actions = array(
|
||
'empty',
|
||
'save',
|
||
'test_database',
|
||
'import',
|
||
'modify_links',
|
||
);
|
||
$action = '';
|
||
foreach ( $feasible_actions as $potential_action ) {
|
||
if ( isset($_POST[$potential_action]) ) {
|
||
$action = $potential_action;
|
||
break;
|
||
}
|
||
}
|
||
$this->dispatch($action);
|
||
$this->display_admin_page(); // Display the admin page
|
||
}
|
||
|
||
/**
|
||
* Import triggered by AJAX
|
||
*
|
||
* @since 2.0.0
|
||
*/
|
||
public function ajax_importer() {
|
||
$current_user = wp_get_current_user();
|
||
if ( !empty($current_user) && $current_user->has_cap('import') ) {
|
||
$action = filter_input(INPUT_POST, 'plugin_action', FILTER_SANITIZE_STRING);
|
||
|
||
if ( $action == 'update_wordpress_info') {
|
||
// Update the WordPress database info
|
||
echo $this->get_database_info();
|
||
|
||
} else {
|
||
ini_set('display_errors', true); // Display the errors that may happen (ex: Allowed memory size exhausted)
|
||
|
||
// Empty the log file if we empty the WordPress content
|
||
if ( ($action == 'empty') || (($action == 'import') && filter_input(INPUT_POST, 'automatic_empty', FILTER_VALIDATE_BOOLEAN)) ) {
|
||
file_put_contents($this->log_file, '');
|
||
}
|
||
|
||
$time_start = date('Y-m-d H:i:s');
|
||
$this->display_admin_notice("=== START $action $time_start ===");
|
||
$result = $this->dispatch($action);
|
||
if ( !empty($result) ) {
|
||
echo json_encode($result); // Send the result to the AJAX caller
|
||
}
|
||
$time_end = date('Y-m-d H:i:s');
|
||
$this->display_admin_notice("=== END $action $time_end ===\n");
|
||
}
|
||
}
|
||
wp_die();
|
||
}
|
||
|
||
/**
|
||
* Dispatch the actions
|
||
*
|
||
* @param string $action Action
|
||
* @return object Result to return to the caller
|
||
*/
|
||
public function dispatch($action) {
|
||
set_time_limit(self::IMPORT_TIMEOUT);
|
||
|
||
// Set the time zone
|
||
$timezone = get_option('timezone_string');
|
||
if ( !empty($timezone) ) {
|
||
date_default_timezone_set($timezone);
|
||
}
|
||
|
||
// Suspend the cache during the migration to avoid exhausted memory problem
|
||
wp_suspend_cache_addition(true);
|
||
wp_suspend_cache_invalidation(true);
|
||
|
||
// Default values
|
||
$this->plugin_options = array(
|
||
'automatic_empty' => 0,
|
||
'driver' => 'mysql',
|
||
'hostname' => 'localhost',
|
||
'port' => 3306,
|
||
'database' => null,
|
||
'username' => 'root',
|
||
'password' => '',
|
||
'sqlite_file' => '',
|
||
'prefix' => 'spip_',
|
||
'introtext' => 'in_content',
|
||
'archived_posts' => 'not_imported',
|
||
'skip_media' => 0,
|
||
'media_import_method' => 'http',
|
||
'url' => null,
|
||
'root_directory' => null,
|
||
'logo' => 'as_featured',
|
||
'import_external' => 0,
|
||
'import_duplicates' => 0,
|
||
'force_media_import' => 0,
|
||
'import_as_pages' => 0,
|
||
'timeout' => 5,
|
||
'logger_autorefresh' => 1,
|
||
);
|
||
$options = get_option('fgs2wp_options');
|
||
if ( is_array($options) ) {
|
||
$this->plugin_options = array_merge($this->plugin_options, $options);
|
||
}
|
||
|
||
// Check if the upload directory is writable
|
||
$upload_dir = wp_upload_dir();
|
||
if ( !is_writable($upload_dir['basedir']) ) {
|
||
$this->display_admin_error(__('The wp-content directory must be writable.', 'fg-spip-to-wp'));
|
||
}
|
||
|
||
// Requires at least WordPress 4.4
|
||
if ( version_compare(get_bloginfo('version'), '4.4', '<') ) {
|
||
$this->display_admin_error(sprintf(__('WordPress 4.4+ is required. Please <a href="%s">update WordPress</a>.', 'fg-spip-to-wp'), admin_url('update-core.php')));
|
||
}
|
||
|
||
elseif ( !empty($action) ) {
|
||
switch($action) {
|
||
|
||
// Delete content
|
||
case 'empty':
|
||
if ( check_admin_referer( 'empty', 'fgs2wp_nonce' ) ) { // Security check
|
||
if ($this->empty_database($_POST['empty_action'])) { // Empty WP database
|
||
$this->display_admin_notice(__('WordPress content removed', 'fg-spip-to-wp'));
|
||
} else {
|
||
$this->display_admin_error(__('Couldn\'t remove content', 'fg-spip-to-wp'));
|
||
}
|
||
wp_cache_flush();
|
||
}
|
||
break;
|
||
|
||
// Save database options
|
||
case 'save':
|
||
if ( check_admin_referer( 'parameters_form', 'fgs2wp_nonce' ) ) { // Security check
|
||
$this->save_plugin_options();
|
||
$this->display_admin_notice(__('Settings saved', 'fg-spip-to-wp'));
|
||
}
|
||
break;
|
||
|
||
// Test the database connection
|
||
case 'test_database':
|
||
if ( check_admin_referer( 'parameters_form', 'fgs2wp_nonce' ) ) { // Security check
|
||
// Save database options
|
||
$this->save_plugin_options();
|
||
|
||
if ( $this->test_database_connection() ) {
|
||
return array('status' => 'OK', 'message' => __('Connection successful', 'fg-spip-to-wp'));
|
||
} else {
|
||
return array('status' => 'Error', 'message' => __('Connection failed', 'fg-spip-to-wp') . '<br />' . __('See the errors in the log below', 'fg-spip-to-wp'));
|
||
}
|
||
}
|
||
break;
|
||
|
||
// Run the import
|
||
case 'import':
|
||
if ( check_admin_referer( 'parameters_form', 'fgs2wp_nonce' ) ) { // Security check
|
||
// Save database options
|
||
$this->save_plugin_options();
|
||
|
||
if ( $this->test_database_connection() ) {
|
||
// Automatic empty
|
||
if ( $this->plugin_options['automatic_empty'] ) {
|
||
if ($this->empty_database('all')) {
|
||
$this->display_admin_notice(__('WordPress content removed', 'fg-spip-to-wp'));
|
||
} else {
|
||
$this->display_admin_error(__('Couldn\'t remove content', 'fg-spip-to-wp'));
|
||
}
|
||
wp_cache_flush();
|
||
}
|
||
|
||
// Import content
|
||
$this->import();
|
||
}
|
||
}
|
||
break;
|
||
|
||
// Stop the import
|
||
case 'stop_import':
|
||
if ( check_admin_referer( 'parameters_form', 'fgs2wp_nonce' ) ) { // Security check
|
||
$this->stop_import();
|
||
}
|
||
break;
|
||
|
||
// Modify internal links
|
||
case 'modify_links':
|
||
if ( check_admin_referer( 'modify_links', 'fgs2wp_nonce' ) ) { // Security check
|
||
$result = $this->modify_links();
|
||
$this->display_admin_notice(sprintf(_n('%d internal link modified', '%d internal links modified', $result['links_count'], 'fg-spip-to-wp'), $result['links_count']));
|
||
}
|
||
break;
|
||
|
||
default:
|
||
// Do other actions
|
||
do_action('fgs2wp_dispatch', $action);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Display the admin page
|
||
*
|
||
*/
|
||
private function display_admin_page() {
|
||
$data = $this->plugin_options;
|
||
|
||
$data['title'] = __('Import SPIP', 'fg-spip-to-wp');
|
||
$data['description'] = __('This plugin will import categories, articles, news and images from a SPIP database into WordPress.<br />Compatible with SPIP from 1.8 to 3.2.', 'fg-spip-to-wp');
|
||
$data['description'] .= "<br />\n" . sprintf(__('For any issue, please read the <a href="%s" target="_blank">FAQ</a> first.', 'fg-spip-to-wp'), $this->faq_url);
|
||
$data['database_info'] = $this->get_database_info();
|
||
|
||
// Hook for modifying the admin page
|
||
$data = apply_filters('fgs2wp_pre_display_admin_page', $data);
|
||
|
||
// Load the CSS and Javascript
|
||
$this->enqueue_styles();
|
||
$this->enqueue_scripts();
|
||
|
||
include plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/admin-display.php';
|
||
|
||
// Hook for doing other actions after displaying the admin page
|
||
do_action('fgs2wp_post_display_admin_page');
|
||
|
||
}
|
||
|
||
/**
|
||
* Get the WordPress database info
|
||
*
|
||
* @return string Database info
|
||
*/
|
||
private function get_database_info() {
|
||
$posts_count = $this->count_posts('post');
|
||
$pages_count = $this->count_posts('page');
|
||
$media_count = $this->count_posts('attachment');
|
||
$cat_count = wp_count_terms('category', array('hide_empty' => 0));
|
||
|
||
$database_info =
|
||
sprintf(_n('%d category', '%d categories', $cat_count, 'fg-spip-to-wp'), $cat_count) . "<br />" .
|
||
sprintf(_n('%d post', '%d posts', $posts_count, 'fg-spip-to-wp'), $posts_count) . "<br />" .
|
||
sprintf(_n('%d page', '%d pages', $pages_count, 'fg-spip-to-wp'), $pages_count) . "<br />" .
|
||
sprintf(_n('%d media', '%d medias', $media_count, 'fg-spip-to-wp'), $media_count) . "<br />";
|
||
$database_info = apply_filters('fgs2wp_get_database_info', $database_info);
|
||
return $database_info;
|
||
}
|
||
|
||
/**
|
||
* Count the number of posts for a post type
|
||
* @param string $post_type
|
||
*/
|
||
public function count_posts($post_type) {
|
||
$count = 0;
|
||
$excluded_status = array('trash', 'auto-draft');
|
||
$tab_count = wp_count_posts($post_type);
|
||
foreach ( $tab_count as $key => $value ) {
|
||
if ( !in_array($key, $excluded_status) ) {
|
||
$count += $value;
|
||
}
|
||
}
|
||
return $count;
|
||
}
|
||
|
||
/**
|
||
* Add an help tab
|
||
*
|
||
*/
|
||
public function add_help_tab() {
|
||
$screen = get_current_screen();
|
||
$screen->add_help_tab(array(
|
||
'id' => 'fgs2wp_help_instructions',
|
||
'title' => __('Instructions', 'fg-spip-to-wp'),
|
||
'content' => '',
|
||
'callback' => array($this, 'help_instructions'),
|
||
));
|
||
$screen->add_help_tab(array(
|
||
'id' => 'fgs2wp_help_options',
|
||
'title' => __('Options', 'fg-spip-to-wp'),
|
||
'content' => '',
|
||
'callback' => array($this, 'help_options'),
|
||
));
|
||
$screen->set_help_sidebar('<a href="' . $this->faq_url . '" target="_blank">' . __('FAQ', 'fg-spip-to-wp') . '</a>');
|
||
}
|
||
|
||
/**
|
||
* Instructions help screen
|
||
*
|
||
* @return string Help content
|
||
*/
|
||
public function help_instructions() {
|
||
include plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/help-instructions.tpl.php';
|
||
}
|
||
|
||
/**
|
||
* Options help screen
|
||
*
|
||
* @return string Help content
|
||
*/
|
||
public function help_options() {
|
||
include plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/help-options.tpl.php';
|
||
}
|
||
|
||
/**
|
||
* Open the connection on Spip database
|
||
*
|
||
* return boolean Connection successful or not
|
||
*/
|
||
protected function spip_connect() {
|
||
global $spip_db;
|
||
|
||
if ( !class_exists('PDO') ) {
|
||
$this->display_admin_error(__('PDO is required. Please enable it.', 'fg-spip-to-wp'));
|
||
return false;
|
||
}
|
||
try {
|
||
switch ( $this->plugin_options['driver'] ) {
|
||
case 'mysql':
|
||
// MySQL
|
||
$spip_db = new PDO('mysql:host=' . $this->plugin_options['hostname'] . ';port=' . $this->plugin_options['port'] . ';dbname=' . $this->plugin_options['database'], $this->plugin_options['username'], $this->plugin_options['password'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
|
||
break;
|
||
|
||
case 'sqlite':
|
||
// SQLite
|
||
if ( !file_exists($this->plugin_options['sqlite_file']) ) {
|
||
$this->display_admin_error(__("Couldn't read the SPIP database SQLite file: ", 'fg-spip-to-wp') . $this->plugin_options['sqlite_file']);
|
||
return false;
|
||
}
|
||
$spip_db = new PDO('sqlite:' . $this->plugin_options['sqlite_file']);
|
||
break;
|
||
}
|
||
if ( defined('WP_DEBUG') && WP_DEBUG ) {
|
||
$spip_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Display SQL errors
|
||
}
|
||
} catch ( PDOException $e ) {
|
||
$this->display_admin_error(__('Couldn\'t connect to the SPIP database. Please check your parameters. And be sure the WordPress server can access the SPIP database.', 'fg-spip-to-wp') . "<br />\n" . $e->getMessage() . "<br />\n" . sprintf(__('Please read the <a href="%s" target="_blank">FAQ for the solution</a>.', 'fg-spip-to-wp'), $this->faq_url));
|
||
return false;
|
||
}
|
||
$this->spip_version = $this->get_spip_version();
|
||
$this->spip_charset = $this->get_spip_meta('charset');
|
||
$this->blob_encoding = $this->is_text_encoded_as_blob() ;
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Execute a SQL query on the Spip database
|
||
*
|
||
* @param string $sql SQL query
|
||
* @return array Query result
|
||
*/
|
||
public function spip_query($sql) {
|
||
global $spip_db;
|
||
$result = array();
|
||
|
||
try {
|
||
$query = $spip_db->query($sql, PDO::FETCH_ASSOC);
|
||
if ( is_object($query) ) {
|
||
foreach ( $query as $row ) {
|
||
$result[] = $row;
|
||
}
|
||
}
|
||
|
||
} catch ( PDOException $e ) {
|
||
$this->display_admin_error(__('Error:', 'fg-spip-to-wp') . $e->getMessage());
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Delete all posts, medias and categories from the database
|
||
*
|
||
* @param string $action imported = removes only new imported posts
|
||
* all = removes all
|
||
* @return boolean
|
||
*/
|
||
private function empty_database($action) {
|
||
global $wpdb;
|
||
$result = true;
|
||
|
||
$wpdb->show_errors();
|
||
|
||
// Hook for doing other actions before emptying the database
|
||
do_action('fgs2wp_pre_empty_database', $action);
|
||
|
||
$sql_queries = array();
|
||
|
||
if ( $action == 'all' ) {
|
||
// Remove all content
|
||
$sql_queries[] = "TRUNCATE $wpdb->commentmeta";
|
||
$sql_queries[] = "TRUNCATE $wpdb->comments";
|
||
$sql_queries[] = "TRUNCATE $wpdb->term_relationships";
|
||
$sql_queries[] = "TRUNCATE $wpdb->termmeta";
|
||
$sql_queries[] = "TRUNCATE $wpdb->postmeta";
|
||
$sql_queries[] = "TRUNCATE $wpdb->posts";
|
||
$sql_queries[] = <<<SQL
|
||
-- Delete Terms
|
||
DELETE FROM $wpdb->terms
|
||
WHERE term_id > 1 -- non-classe
|
||
SQL;
|
||
$sql_queries[] = <<<SQL
|
||
-- Delete Terms taxonomies
|
||
DELETE FROM $wpdb->term_taxonomy
|
||
WHERE term_id > 1 -- non-classe
|
||
SQL;
|
||
$sql_queries[] = "ALTER TABLE $wpdb->terms AUTO_INCREMENT = 2";
|
||
$sql_queries[] = "ALTER TABLE $wpdb->term_taxonomy AUTO_INCREMENT = 2";
|
||
|
||
} else {
|
||
|
||
// (Re)create a temporary table with the IDs to delete
|
||
$sql_queries[] = <<<SQL
|
||
DROP TEMPORARY TABLE IF EXISTS {$wpdb->prefix}fg_data_to_delete;
|
||
SQL;
|
||
|
||
$sql_queries[] = <<<SQL
|
||
CREATE TEMPORARY TABLE IF NOT EXISTS {$wpdb->prefix}fg_data_to_delete (
|
||
`id` bigint(20) unsigned NOT NULL,
|
||
PRIMARY KEY (`id`)
|
||
) DEFAULT CHARSET=utf8;
|
||
SQL;
|
||
|
||
// Insert the imported posts IDs in the temporary table
|
||
$sql_queries[] = <<<SQL
|
||
INSERT IGNORE INTO {$wpdb->prefix}fg_data_to_delete (`id`)
|
||
SELECT post_id FROM $wpdb->postmeta
|
||
WHERE meta_key LIKE '_fgs2wp_%'
|
||
SQL;
|
||
|
||
// Delete the imported posts and related data
|
||
|
||
$sql_queries[] = <<<SQL
|
||
-- Delete Comments and Comment metas
|
||
DELETE c, cm
|
||
FROM $wpdb->comments c
|
||
LEFT JOIN $wpdb->commentmeta cm ON cm.comment_id = c.comment_ID
|
||
INNER JOIN {$wpdb->prefix}fg_data_to_delete del
|
||
WHERE c.comment_post_ID = del.id;
|
||
SQL;
|
||
|
||
$sql_queries[] = <<<SQL
|
||
-- Delete Term relashionships
|
||
DELETE tr
|
||
FROM $wpdb->term_relationships tr
|
||
INNER JOIN {$wpdb->prefix}fg_data_to_delete del
|
||
WHERE tr.object_id = del.id;
|
||
SQL;
|
||
|
||
$sql_queries[] = <<<SQL
|
||
-- Delete Posts Children and Post metas
|
||
DELETE p, pm
|
||
FROM $wpdb->posts p
|
||
LEFT JOIN $wpdb->postmeta pm ON pm.post_id = p.ID
|
||
INNER JOIN {$wpdb->prefix}fg_data_to_delete del
|
||
WHERE p.post_parent = del.id
|
||
AND p.post_type != 'attachment'; -- Don't remove the old medias attached to posts
|
||
SQL;
|
||
|
||
$sql_queries[] = <<<SQL
|
||
-- Delete Posts and Post metas
|
||
DELETE p, pm
|
||
FROM $wpdb->posts p
|
||
LEFT JOIN $wpdb->postmeta pm ON pm.post_id = p.ID
|
||
INNER JOIN {$wpdb->prefix}fg_data_to_delete del
|
||
WHERE p.ID = del.id;
|
||
SQL;
|
||
|
||
// Truncate the temporary table
|
||
$sql_queries[] = <<<SQL
|
||
TRUNCATE {$wpdb->prefix}fg_data_to_delete;
|
||
SQL;
|
||
|
||
// Insert the imported terms IDs in the temporary table
|
||
$sql_queries[] = <<<SQL
|
||
INSERT IGNORE INTO {$wpdb->prefix}fg_data_to_delete (`id`)
|
||
SELECT term_id FROM $wpdb->termmeta
|
||
WHERE meta_key LIKE '_fgs2wp_%'
|
||
SQL;
|
||
|
||
// Delete the imported terms and related data
|
||
|
||
$sql_queries[] = <<<SQL
|
||
-- Delete Terms, Term taxonomies and Term metas
|
||
DELETE t, tt, tm
|
||
FROM $wpdb->terms t
|
||
LEFT JOIN $wpdb->term_taxonomy tt ON tt.term_id = t.term_id
|
||
LEFT JOIN $wpdb->termmeta tm ON tm.term_id = t.term_id
|
||
INNER JOIN {$wpdb->prefix}fg_data_to_delete del
|
||
WHERE t.term_id = del.id;
|
||
SQL;
|
||
|
||
// Truncate the temporary table
|
||
$sql_queries[] = <<<SQL
|
||
TRUNCATE {$wpdb->prefix}fg_data_to_delete;
|
||
SQL;
|
||
|
||
// Insert the imported comments IDs in the temporary table
|
||
$sql_queries[] = <<<SQL
|
||
INSERT IGNORE INTO {$wpdb->prefix}fg_data_to_delete (`id`)
|
||
SELECT comment_id FROM $wpdb->commentmeta
|
||
WHERE meta_key LIKE '_fgs2wp_%'
|
||
SQL;
|
||
|
||
// Delete the imported comments and related data
|
||
$sql_queries[] = <<<SQL
|
||
-- Delete Comments and Comment metas
|
||
DELETE c, cm
|
||
FROM $wpdb->comments c
|
||
LEFT JOIN $wpdb->commentmeta cm ON cm.comment_id = c.comment_ID
|
||
INNER JOIN {$wpdb->prefix}fg_data_to_delete del
|
||
WHERE c.comment_ID = del.id;
|
||
SQL;
|
||
|
||
}
|
||
|
||
// Execute SQL queries
|
||
if ( count($sql_queries) > 0 ) {
|
||
foreach ( $sql_queries as $sql ) {
|
||
$result &= $wpdb->query($sql);
|
||
}
|
||
}
|
||
|
||
// Hook for doing other actions after emptying the database
|
||
do_action('fgs2wp_post_empty_database', $action);
|
||
|
||
// Drop the temporary table
|
||
$wpdb->query("DROP TEMPORARY TABLE IF EXISTS {$wpdb->prefix}fg_data_to_delete;");
|
||
|
||
// Reset the SPIP import counters
|
||
update_option('fgs2wp_last_spip_article_id', 0);
|
||
update_option('fgs2wp_last_spip_news_id', 0);
|
||
update_option('fgs2wp_last_category_id', 0);
|
||
|
||
// Re-count categories and tags items
|
||
$this->terms_count();
|
||
|
||
// Update cache
|
||
$this->clean_cache();
|
||
delete_transient('wc_count_comments');
|
||
|
||
$this->optimize_database();
|
||
|
||
$this->progressbar->set_total_count(0);
|
||
|
||
$wpdb->hide_errors();
|
||
return ($result !== false);
|
||
}
|
||
|
||
/**
|
||
* Optimize the database
|
||
*
|
||
*/
|
||
protected function optimize_database() {
|
||
global $wpdb;
|
||
|
||
$sql = <<<SQL
|
||
OPTIMIZE TABLE
|
||
`$wpdb->commentmeta` ,
|
||
`$wpdb->comments` ,
|
||
`$wpdb->options` ,
|
||
`$wpdb->postmeta` ,
|
||
`$wpdb->posts` ,
|
||
`$wpdb->terms` ,
|
||
`$wpdb->term_relationships` ,
|
||
`$wpdb->term_taxonomy`,
|
||
`$wpdb->termmeta`
|
||
SQL;
|
||
$wpdb->query($sql);
|
||
}
|
||
|
||
/**
|
||
* Test the database connection
|
||
*
|
||
* @return boolean
|
||
*/
|
||
function test_database_connection() {
|
||
global $spip_db;
|
||
|
||
if ( $this->spip_connect() ) {
|
||
// Test that the "articles" table exists
|
||
if ( $this->table_exists('articles') ) {
|
||
$this->display_admin_notice(__('Connected with success to the SPIP database', 'fg-spip-to-wp'));
|
||
|
||
do_action('fgs2wp_post_test_database_connection');
|
||
return true;
|
||
|
||
} else {
|
||
$this->display_admin_error(__('Couldn\'t connect to the SPIP database. Please check your parameters. And be sure the WordPress server can access the SPIP database.', 'fg-spip-to-wp') . "<br />\n");
|
||
}
|
||
}
|
||
$spip_db = null;
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Get some Spip information
|
||
*
|
||
*/
|
||
public function get_spip_info() {
|
||
$message = __('Spip data found:', 'fg-spip-to-wp') . "\n";
|
||
|
||
// Categories
|
||
$cat_count = $this->get_categories_count();
|
||
$message .= sprintf(_n('%d section', '%d sections', $cat_count, 'fg-spip-to-wp'), $cat_count) . "\n";
|
||
|
||
// Articles
|
||
$articles_count = $this->get_articles_count();
|
||
$message .= sprintf(_n('%d article', '%d articles', $articles_count, 'fg-spip-to-wp'), $articles_count) . "\n";
|
||
|
||
// News
|
||
$news_count = $this->get_news_count();
|
||
$message .= sprintf(_n('%d news', '%d news', $news_count, 'fg-spip-to-wp'), $news_count) . "\n";
|
||
|
||
$message = apply_filters('fgs2wp_pre_display_spip_info', $message);
|
||
|
||
$this->display_admin_notice($message);
|
||
}
|
||
|
||
/**
|
||
* Get the number of Spip categories
|
||
*
|
||
* @return int Number of categories
|
||
*/
|
||
private function get_categories_count() {
|
||
$prefix = $this->plugin_options['prefix'];
|
||
$sql = "
|
||
SELECT COUNT(*) AS nb
|
||
FROM ${prefix}rubriques r
|
||
";
|
||
$result = $this->spip_query($sql);
|
||
$cat_count = isset($result[0]['nb'])? $result[0]['nb'] : 0;
|
||
return $cat_count;
|
||
}
|
||
|
||
/**
|
||
* Get the number of Spip articles
|
||
*
|
||
* @return int Number of articles
|
||
*/
|
||
private function get_articles_count() {
|
||
$prefix = $this->plugin_options['prefix'];
|
||
$sql = "
|
||
SELECT COUNT(*) AS nb
|
||
FROM ${prefix}articles a
|
||
WHERE a.statut IN ('publie', 'prepa', 'prop')
|
||
";
|
||
$result = $this->spip_query($sql);
|
||
$articles_count = isset($result[0]['nb'])? $result[0]['nb'] : 0;
|
||
return $articles_count;
|
||
}
|
||
|
||
/**
|
||
* Get the number of Spip news
|
||
*
|
||
* @return int Number of news
|
||
*/
|
||
private function get_news_count() {
|
||
$prefix = $this->plugin_options['prefix'];
|
||
$sql = "
|
||
SELECT COUNT(*) AS nb
|
||
FROM ${prefix}breves b
|
||
WHERE b.statut IN ('publie', 'prepa', 'prop')
|
||
";
|
||
$result = $this->spip_query($sql);
|
||
$news_count = isset($result[0]['nb'])? $result[0]['nb'] : 0;
|
||
return $news_count;
|
||
}
|
||
|
||
/**
|
||
* Save the plugin options
|
||
*
|
||
*/
|
||
private function save_plugin_options() {
|
||
$this->plugin_options = array_merge($this->plugin_options, $this->validate_form_info());
|
||
update_option('fgs2wp_options', $this->plugin_options);
|
||
|
||
// Hook for doing other actions after saving the options
|
||
do_action('fgs2wp_post_save_plugin_options');
|
||
}
|
||
|
||
/**
|
||
* Validate POST info
|
||
*
|
||
* @return array Form parameters
|
||
*/
|
||
private function validate_form_info() {
|
||
// Add http:// before the URL if it is missing
|
||
$url = esc_url(filter_input(INPUT_POST, 'url', FILTER_SANITIZE_URL));
|
||
if ( !empty($url) && (preg_match('#^https?://#', $url) == 0) ) {
|
||
$url = 'http://' . $url;
|
||
}
|
||
return array(
|
||
'automatic_empty' => filter_input(INPUT_POST, 'automatic_empty', FILTER_VALIDATE_BOOLEAN),
|
||
'driver' => filter_input(INPUT_POST, 'driver', FILTER_SANITIZE_STRING),
|
||
'hostname' => filter_input(INPUT_POST, 'hostname', FILTER_SANITIZE_STRING),
|
||
'port' => filter_input(INPUT_POST, 'port', FILTER_SANITIZE_NUMBER_INT),
|
||
'database' => filter_input(INPUT_POST, 'database', FILTER_SANITIZE_STRING),
|
||
'username' => filter_input(INPUT_POST, 'username'),
|
||
'password' => filter_input(INPUT_POST, 'password'),
|
||
'sqlite_file' => filter_input(INPUT_POST, 'sqlite_file', FILTER_SANITIZE_STRING),
|
||
'prefix' => filter_input(INPUT_POST, 'prefix', FILTER_SANITIZE_STRING),
|
||
'introtext' => filter_input(INPUT_POST, 'introtext', FILTER_SANITIZE_STRING),
|
||
'archived_posts' => filter_input(INPUT_POST, 'archived_posts', FILTER_SANITIZE_STRING),
|
||
'skip_media' => filter_input(INPUT_POST, 'skip_media', FILTER_VALIDATE_BOOLEAN),
|
||
'media_import_method' => filter_input(INPUT_POST, 'media_import_method', FILTER_SANITIZE_STRING),
|
||
'url' => $url,
|
||
'root_directory' => filter_input(INPUT_POST, 'root_directory', FILTER_SANITIZE_STRING),
|
||
'logo' => filter_input(INPUT_POST, 'logo', FILTER_SANITIZE_STRING),
|
||
'import_external' => filter_input(INPUT_POST, 'import_external', FILTER_VALIDATE_BOOLEAN),
|
||
'import_duplicates' => filter_input(INPUT_POST, 'import_duplicates', FILTER_VALIDATE_BOOLEAN),
|
||
'force_media_import' => filter_input(INPUT_POST, 'force_media_import', FILTER_VALIDATE_BOOLEAN),
|
||
'import_as_pages' => filter_input(INPUT_POST, 'import_as_pages', FILTER_VALIDATE_BOOLEAN),
|
||
'timeout' => filter_input(INPUT_POST, 'timeout', FILTER_SANITIZE_NUMBER_INT),
|
||
'logger_autorefresh' => filter_input(INPUT_POST, 'logger_autorefresh', FILTER_VALIDATE_BOOLEAN),
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Import
|
||
*
|
||
*/
|
||
private function import() {
|
||
if ( $this->spip_connect() ) {
|
||
|
||
$time_start = microtime(true);
|
||
|
||
define('WP_IMPORTING', true);
|
||
update_option('fgs2wp_stop_import', false, false); // Reset the stop import action
|
||
|
||
// To solve the issue of links containing ":" in multisite mode
|
||
kses_remove_filters();
|
||
|
||
// Check prerequesites before the import
|
||
$do_import = apply_filters('fgs2wp_pre_import_check', true);
|
||
if ( !$do_import) {
|
||
return;
|
||
}
|
||
|
||
$total_elements_count = $this->get_total_elements_count();
|
||
$this->progressbar->set_total_count($total_elements_count);
|
||
|
||
$this->post_type = ($this->plugin_options['import_as_pages'] == 1) ? 'page' : 'post';
|
||
$this->media_path = $this->get_image_path();
|
||
|
||
// Hook for doing other actions before the import
|
||
do_action('fgs2wp_pre_import');
|
||
|
||
// Categories
|
||
if ( !isset($this->premium_options['skip_categories']) || !$this->premium_options['skip_categories'] ) {
|
||
$cat_count = $this->import_categories();
|
||
$this->display_admin_notice(sprintf(_n('%d category imported', '%d categories imported', $cat_count, 'fg-spip-to-wp'), $cat_count));
|
||
}
|
||
|
||
// Set the list of previously imported categories
|
||
$this->imported_categories = $this->get_term_metas_by_metakey('_fgs2wp_old_category_id');
|
||
|
||
// Articles and medias
|
||
if ( !isset($this->premium_options['skip_articles']) || !$this->premium_options['skip_articles'] ) {
|
||
$this->import_articles();
|
||
}
|
||
|
||
// News
|
||
if ( !isset($this->premium_options['skip_news']) || !$this->premium_options['skip_news'] ) {
|
||
$this->import_news();
|
||
}
|
||
|
||
$this->display_admin_notice(sprintf(_n('%d post imported', '%d posts imported', $this->posts_count, 'fg-spip-to-wp'), $this->posts_count));
|
||
if ( $this->pages_count > 0 ) {
|
||
$this->display_admin_notice(sprintf(_n('%d page imported', '%d pages imported', $this->pages_count, 'fg-spip-to-wp'), $this->pages_count));
|
||
}
|
||
$this->display_admin_notice(sprintf(_n('%d media imported', '%d medias imported', $this->media_count, 'fg-spip-to-wp'), $this->media_count));
|
||
|
||
if ( !$this->import_stopped() ) {
|
||
// Hook for doing other actions after the import
|
||
do_action('fgs2wp_post_import');
|
||
}
|
||
|
||
// Hook for other notices
|
||
do_action('fgs2wp_import_notices');
|
||
|
||
// Debug info
|
||
if ( defined('WP_DEBUG') && WP_DEBUG ) {
|
||
$this->display_admin_notice(sprintf("Memory used: %s bytes<br />\n", number_format(memory_get_usage())));
|
||
$time_end = microtime(true);
|
||
$this->display_admin_notice(sprintf("Duration: %d sec<br />\n", $time_end - $time_start));
|
||
}
|
||
|
||
$this->display_admin_notice(__("Don't forget to modify internal links.", 'fg-spip-to-wp'));
|
||
$this->display_admin_notice("IMPORT COMPLETED");
|
||
|
||
wp_cache_flush();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Actions to do before the import
|
||
*
|
||
* @param bool $import_doable Can we start the import?
|
||
* @return bool Can we start the import?
|
||
*/
|
||
public function pre_import_check($import_doable) {
|
||
if ( $import_doable ) {
|
||
if ( !$this->plugin_options['skip_media'] ) {
|
||
if ( ($this->plugin_options['media_import_method'] == 'http') && empty($this->plugin_options['url']) ) {
|
||
$this->display_admin_error(__('The URL field is required to import the media.', 'fg-spip-to-wp'));
|
||
$import_doable = false;
|
||
} elseif ( ($this->plugin_options['media_import_method'] == 'local') && empty($this->plugin_options['root_directory']) ) {
|
||
$this->display_admin_error(__('The root directory field is required to import the media.', 'fg-spip-to-wp'));
|
||
$import_doable = false;
|
||
}
|
||
}
|
||
}
|
||
return $import_doable;
|
||
}
|
||
|
||
/**
|
||
* Get the number of elements to import
|
||
*
|
||
* @return int Number of elements to import
|
||
*/
|
||
private function get_total_elements_count() {
|
||
$count = 0;
|
||
|
||
// Categories
|
||
if ( !isset($this->premium_options['skip_categories']) || !$this->premium_options['skip_categories'] ) {
|
||
$count += $this->get_categories_count();
|
||
}
|
||
|
||
// Articles
|
||
if ( !isset($this->premium_options['skip_articles']) || !$this->premium_options['skip_articles'] ) {
|
||
$count += $this->get_articles_count();
|
||
}
|
||
|
||
// News
|
||
if ( !isset($this->premium_options['skip_news']) || !$this->premium_options['skip_news'] ) {
|
||
$count += $this->get_news_count();
|
||
}
|
||
|
||
$count = apply_filters('fgs2wp_get_total_elements_count', $count);
|
||
|
||
return $count;
|
||
}
|
||
|
||
/**
|
||
* Import categories
|
||
*
|
||
* @return int Number of categories imported
|
||
*/
|
||
private function import_categories() {
|
||
$imported_categories_count = 0;
|
||
$all_categories = array();
|
||
|
||
if ( $this->import_stopped() ) {
|
||
return 0;
|
||
}
|
||
|
||
$this->log(__('Importing categories...', 'fg-spip-to-wp'));
|
||
|
||
// Hook before importing the categories
|
||
do_action('fgs2wp_pre_import_categories');
|
||
|
||
do {
|
||
if ( $this->import_stopped() ) {
|
||
break;
|
||
}
|
||
$categories = $this->get_categories($this->chunks_size); // Get the Spip categories
|
||
$categories_count = count($categories);
|
||
|
||
if ( ($categories != null) && (count($categories) > 0) ) {
|
||
$all_categories = array_merge($all_categories, $categories);
|
||
// Insert the categories
|
||
$imported_categories_count += $this->insert_categories($categories);
|
||
}
|
||
} while ( ($categories != null) && ($categories_count > 0) );
|
||
|
||
$all_categories = apply_filters('fgs2wp_import_categories', $all_categories);
|
||
|
||
// Update the categories with their parent ids
|
||
// We need to do it in a second step because the children categories
|
||
// may have been imported before their parent
|
||
$this->update_parent_categories($all_categories);
|
||
|
||
if ( !$this->import_stopped() ) {
|
||
// Hook after importing all the categories
|
||
do_action('fgs2wp_post_import_categories', $all_categories);
|
||
}
|
||
|
||
return $imported_categories_count;
|
||
}
|
||
|
||
/**
|
||
* Insert a list of categories in the database
|
||
*
|
||
* @param array $categories List of categories
|
||
* @param string $taxonomy Taxonomy
|
||
* @param string $last_category_metakey Last category meta key
|
||
* @return int Number of inserted categories
|
||
*/
|
||
public function insert_categories($categories, $taxonomy='category', $last_category_metakey='fgs2wp_last_category_id') {
|
||
$cat_count = 0;
|
||
$processed_cat_count = count($categories);
|
||
$term_metakey = '_fgs2wp_old_category_id';
|
||
|
||
// Set the list of previously imported categories
|
||
$this->imported_categories = $this->get_term_metas_by_metakey($term_metakey);
|
||
|
||
$terms = array();
|
||
if ( $taxonomy == 'category') {
|
||
$terms[] = '1'; // unclassified category
|
||
}
|
||
|
||
foreach ( $categories as $category ) {
|
||
$category_id = $category['id_rubrique'];
|
||
|
||
$category['texte'] = $this->convert_spip1_longblob($category['texte']); // SPIP 1.x LONGBLOB
|
||
|
||
// Check if the category is already imported
|
||
if ( array_key_exists($category_id, $this->imported_categories) ) {
|
||
continue; // Do not import already imported category
|
||
}
|
||
|
||
// Store the last ID to resume the import where it left off
|
||
update_option($last_category_metakey, $category_id);
|
||
|
||
$parent_id = isset($this->imported_categories[$category['id_parent']])? $this->imported_categories[$category['id_parent']]: 0;
|
||
$new_cat_id = $this->insert_category($category, $term_metakey, $parent_id);
|
||
|
||
if ( is_wp_error($new_cat_id) ) {
|
||
continue;
|
||
}
|
||
$cat_count++;
|
||
$terms[] = $new_cat_id;
|
||
$this->imported_categories[$category_id] = $new_cat_id;
|
||
|
||
// Hook after importing the category
|
||
do_action('fgs2wp_post_import_category', $new_cat_id, $category);
|
||
}
|
||
|
||
$this->progressbar->increment_current_count($processed_cat_count);
|
||
|
||
// Update cache
|
||
if ( !empty($terms) ) {
|
||
wp_update_term_count_now($terms, $taxonomy);
|
||
$this->clean_cache($terms, $taxonomy);
|
||
}
|
||
|
||
return $cat_count;
|
||
}
|
||
|
||
/**
|
||
* Insert a category in the database
|
||
*
|
||
* @since 2.5.0
|
||
*
|
||
* @param array $category Category
|
||
* @param string $term_metakey Term meta_key
|
||
* @param int $parent_id Category parent ID
|
||
* @return int Category ID
|
||
*/
|
||
public function insert_category($category, $term_metakey, $parent_id=0) {
|
||
$category_id = $category['id_rubrique'];
|
||
$category['titre'] = $this->remove_id($category['titre']);
|
||
$category['titre'] = FG_Spip_to_WordPress_Tools::fix_encoding($category['titre']);
|
||
$category_slug = sanitize_title($category['titre']);
|
||
$category['texte'] = FG_Spip_to_WordPress_Tools::fix_encoding($category['texte']);
|
||
|
||
// Insert the category
|
||
$new_category = array(
|
||
'cat_name' => $category['titre'],
|
||
'category_description' => $this->spip_format($category['texte']),
|
||
'category_nicename' => $category_slug,
|
||
'category_parent' => $parent_id,
|
||
);
|
||
|
||
// Hook before inserting the category
|
||
$new_category = apply_filters('fgs2wp_pre_insert_category', $new_category, $category);
|
||
|
||
$new_cat_id = wp_insert_category($new_category, true);
|
||
|
||
if ( !is_wp_error($new_cat_id) ) {
|
||
// Store the Spip category ID
|
||
add_term_meta($new_cat_id, $term_metakey, $category_id, true);
|
||
|
||
// Hook after inserting the category
|
||
do_action('fgs2wp_post_insert_category', $new_cat_id, $category);
|
||
} else {
|
||
if ( isset($new_cat_id->error_data['term_exists']) ) {
|
||
// Store the Spip category ID
|
||
add_term_meta($new_cat_id->error_data['term_exists'], $term_metakey, $category_id, false);
|
||
}
|
||
}
|
||
return $new_cat_id;
|
||
}
|
||
|
||
/**
|
||
* Update the parent categories
|
||
*
|
||
* @param array $categories Categories
|
||
* @param string $taxonomy Taxonomy
|
||
*/
|
||
public function update_parent_categories($categories, $taxonomy='category') {
|
||
foreach ( $categories as $category ) {
|
||
// Parent category
|
||
if ( isset($this->imported_categories[$category['id_rubrique']]) && !empty($category['id_parent']) && isset($this->imported_categories[$category['id_parent']]) ) {
|
||
$cat_id = $this->imported_categories[$category['id_rubrique']];
|
||
$parent_cat_id = $this->imported_categories[$category['id_parent']];
|
||
wp_update_term($cat_id, $taxonomy, array('parent' => $parent_cat_id));
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Convert SPIP format to HTML
|
||
*
|
||
* @param string $text SPIP text
|
||
* @return string HTML text
|
||
*/
|
||
public function spip_format($text) {
|
||
$text = str_replace('{{{', '<h2>', $text);
|
||
$text = str_replace('}}}', '</h2>', $text);
|
||
$text = str_replace('{{', '<strong>', $text);
|
||
$text = str_replace('}}', '</strong>', $text);
|
||
$text = str_replace('{', '<em>', $text);
|
||
$text = str_replace('}', '</em>', $text);
|
||
$text = preg_replace('#\[\->(.+?)\]#', "<a href=\"$1\">$1</a>", $text); // hyperlink with no anchor text, eg: [->http://www.spip.net]
|
||
$text = preg_replace('#\[([^[]+?)\->(.+?)\]#', "<a href=\"$2\">$1</a>", $text); // hyperlink, eg: [SPIP->http://www.spip.net]
|
||
$text = preg_replace('#\[([^[]*?)<-\]#', "<a name=\"$1\"></a>", $text); // anchor, eg: [anchor<-]
|
||
|
||
// Quote
|
||
$text = preg_replace('#<quote>(.*)</quote>#', '<blockquote>$1</blockquote>', $text);
|
||
$text = preg_replace('#<quote\|title=(.*?)(\|.*)?>#', '<blockquote>$1</blockquote>', $text);
|
||
|
||
// Line feeds
|
||
$text = preg_replace(",\r\n?,S", "\n", $text);
|
||
$text = preg_replace(",<p[>[:space:]],iS", "\n\n\\0", $text);
|
||
$text = preg_replace(",</p[>[:space:]],iS", "\\0\n\n", $text);
|
||
|
||
// Tables
|
||
$text = preg_replace(",^\n?[|],S", "\n\n|", $text);
|
||
$text = preg_replace(",\n\n+[|],S", "\n\n\n\n|", $text);
|
||
$text = preg_replace(",[|](\n\n+|\n?$),S", "|\n\n\n\n", $text);
|
||
$regs = array();
|
||
if (preg_match_all(',[^|](\n[|].*[|]\n)[^|],UmsS', $text, $regs, PREG_SET_ORDER)) {
|
||
foreach ($regs as $t) {
|
||
$text = str_replace($t[1], $this->process_table_shortcodes($t[1]), $text);
|
||
}
|
||
}
|
||
|
||
// Ordered and unordered lists
|
||
if ( (strpos($text, "\n-*") !== false) || (strpos($text, "\n-#") !== false) ) {
|
||
$text = $this->process_lists_shortcodes($text);
|
||
}
|
||
|
||
// Row starts
|
||
$text = $this->process_row_starts($text);
|
||
|
||
return $text;
|
||
}
|
||
|
||
/**
|
||
* Convert the unordered and ordered lists SPIP shortcodes
|
||
*
|
||
* @param string $text Text
|
||
* @return string Text
|
||
*/
|
||
private function process_lists_shortcodes($text) {
|
||
$parags = preg_split(",\n[[:space:]]*\n,S", $text);
|
||
$text = '';
|
||
$regs = array();
|
||
$pile_li = array();
|
||
$pile_type = array();
|
||
|
||
foreach ( $parags as $para ) {
|
||
$niveau = 0;
|
||
$lignes = explode("\n-", "\n" . $para);
|
||
|
||
$type = '';
|
||
$first_item = true;
|
||
foreach ( $lignes as $item ) {
|
||
if ( $first_item ) {
|
||
$text .= $item;
|
||
$first_item = false;
|
||
continue;
|
||
}
|
||
if ( preg_match(",^([*]*|[#]*)([^*#].*)$,sS", $item, $regs) ) {
|
||
$profond = strlen($regs[1]);
|
||
|
||
if ( $profond > 0 ) {
|
||
$ajout='';
|
||
$nouv_type = (substr($item,0,1) == '*') ? 'ul' : 'ol';
|
||
$change_type = ($type AND ($type <> $nouv_type) AND ($profond == $niveau)) ? 1 : 0;
|
||
$type = $nouv_type;
|
||
|
||
while ( $niveau > $profond - $change_type ) {
|
||
$ajout .= $pile_li[$niveau];
|
||
$ajout .= $pile_type[$niveau];
|
||
if (!$change_type) {
|
||
unset ($pile_li[$niveau]);
|
||
}
|
||
$niveau --;
|
||
}
|
||
|
||
if ( $niveau == $profond && !$change_type ) {
|
||
$ajout .= $pile_li[$niveau];
|
||
}
|
||
|
||
while ( $niveau < $profond ) {
|
||
if ( $niveau == 0 ) {
|
||
$ajout .= "\n\n";
|
||
}
|
||
$niveau ++;
|
||
$ajout .= "<$type>";
|
||
$pile_type[$niveau] = "</$type>";
|
||
}
|
||
|
||
$ajout .= "<li>";
|
||
$pile_li[$profond] = "</li>";
|
||
}
|
||
else {
|
||
$ajout = "\n-";
|
||
}
|
||
$text .= $ajout . $regs[2];
|
||
}
|
||
}
|
||
|
||
$ajout = '';
|
||
while ( $niveau > 0 ) {
|
||
$ajout .= $pile_li[$niveau];
|
||
$ajout .= $pile_type[$niveau];
|
||
$niveau --;
|
||
}
|
||
$text .= $ajout;
|
||
$text .= "\n\n";
|
||
}
|
||
return substr($text, 0, -2);
|
||
}
|
||
|
||
/**
|
||
* Convert the SPIP table shorcodes to HTML
|
||
*
|
||
* @since 2.14.0
|
||
*
|
||
* @param string $text Text
|
||
* @return string Text
|
||
*/
|
||
private function process_table_shortcodes($text) {
|
||
$regs = array();
|
||
$thead = array();
|
||
$cols = array();
|
||
|
||
preg_match_all(',([|].*)[|]\n,UmsS', $text, $regs, PREG_PATTERN_ORDER);
|
||
$lignes = array();
|
||
$debut_table = $summary = '';
|
||
$l = 0;
|
||
$numeric = true;
|
||
|
||
$reg_line1 = ',^(\|(' . _RACCOURCI_TH_SPAN . '))+$,sS';
|
||
$reg_line_all = ',^' . _RACCOURCI_TH_SPAN . '$,sS';
|
||
foreach ($regs[1] as $ligne) {
|
||
$l++;
|
||
if ($l == 1) {
|
||
$cap = array();
|
||
if (preg_match(',^\|\|([^|]*)(\|(.*))?$,sS', rtrim($ligne,'|'), $cap)) {
|
||
$l = 0;
|
||
$caption = trim($cap[1]);
|
||
if ( !empty($caption) ) {
|
||
$debut_table .= "<caption>".$caption."</caption>\n";
|
||
}
|
||
$summary = isset($cap[3])? ' summary="'.esc_html(trim($cap[3])).'"' : '';
|
||
}
|
||
else if ( preg_match($reg_line1, $ligne, $thead) ) {
|
||
preg_match_all('/\|([^|]*)/S', $ligne, $cols);
|
||
$ligne = '';
|
||
$cols = $cols[1];
|
||
$colspan = 1;
|
||
for ( $c = count($cols)-1; $c >= 0; $c-- ) {
|
||
$attr = '';
|
||
if ( $cols[$c] == '<' ) {
|
||
$colspan++;
|
||
} else {
|
||
if ( $colspan > 1 ) {
|
||
$attr = " colspan='$colspan'";
|
||
$colspan = 1;
|
||
}
|
||
$ligne = "<th scope='col'$attr>$cols[$c]</th>$ligne";
|
||
}
|
||
}
|
||
|
||
$debut_table .= "<thead><tr class='row_first'>" . $ligne."</tr></thead>\n";
|
||
$l = 0;
|
||
}
|
||
}
|
||
|
||
if ($l) {
|
||
if ( strpos($ligne,"\n-*") !== false OR strpos($ligne,"\n-#") !== false ) {
|
||
$ligne = $this->process_lists_shortcodes($ligne);
|
||
}
|
||
|
||
$ligne = preg_replace("/\n{2,}/", "<br />\n", $ligne);
|
||
|
||
preg_match_all('/\|([^|]*)/S', $ligne, $cols);
|
||
$lignes[] = $cols[1];
|
||
}
|
||
}
|
||
|
||
$rowspans = $numeric = array();
|
||
$n = count($lignes[0]);
|
||
$k = count($lignes);
|
||
for ( $i = 0; $i < $n; $i++ ) {
|
||
$align = true;
|
||
for ( $j = 0; $j < $k; $j++ ) {
|
||
$rowspans[$j][$i] = 1;
|
||
}
|
||
for ( $j = 0; $j < $k; $j++ ) {
|
||
$cell = trim($lignes[$j][$i]);
|
||
if ( preg_match($reg_line_all, $cell) ) {
|
||
$r = array();
|
||
if ( !preg_match('/^\d+([.,]?)\d*$/', $cell, $r) ) {
|
||
$align = '';
|
||
break;
|
||
}
|
||
elseif ($r[1]) {
|
||
$align = $r[1];
|
||
}
|
||
}
|
||
}
|
||
$numeric[$i] = !$align ? '' :
|
||
(" style='text-align: " .
|
||
(/* $align !== true ?"\"$align\"" : */ 'right') .
|
||
"'");
|
||
}
|
||
|
||
$html = '';
|
||
|
||
for ( $l = count($lignes)-1; $l >= 0; $l-- ) {
|
||
$cols = $lignes[$l];
|
||
$colspan = 1;
|
||
$ligne = '';
|
||
|
||
for ( $c = count($cols)-1; $c >= 0; $c-- ) {
|
||
$attr = isset($numeric[$c])? $numeric[$c] : '';
|
||
$cell = trim($cols[$c]);
|
||
if ( $cell == '<' ) {
|
||
$colspan++;
|
||
|
||
} elseif( $cell == '^' ) {
|
||
$rowspans[$l-1][$c] += $rowspans[$l][$c];
|
||
|
||
} else {
|
||
if( $colspan>1 ) {
|
||
$attr .= " colspan='$colspan'";
|
||
$colspan = 1;
|
||
}
|
||
if ( isset($rowspans[$l][$c]) && ($x=$rowspans[$l][$c]) > 1 ) {
|
||
$attr .= " rowspan='$x'";
|
||
}
|
||
$ligne = "\n<td" . $attr . '>' . $cols[$c] . '</td>' . $ligne;
|
||
}
|
||
}
|
||
|
||
$class = $this->alternate($l+1, 'even', 'odd');
|
||
$html = "<tr class='row_$class'>$ligne</tr>\n$html";
|
||
}
|
||
return "\n\n<table" . $summary . ">\n"
|
||
. $debut_table
|
||
. "<tbody>\n"
|
||
. $html
|
||
. "</tbody>\n"
|
||
. "</table>\n\n";
|
||
}
|
||
|
||
/**
|
||
* Filter |alternate
|
||
*
|
||
* @param int $i Row number
|
||
* @return mixed
|
||
*/
|
||
private function alternate($i) {
|
||
$num = func_num_args();
|
||
$args = func_get_args();
|
||
|
||
if ( $num == 2 && is_array($args[1]) ) {
|
||
$args = $args[1];
|
||
array_unshift($args,'');
|
||
$num = count($args);
|
||
}
|
||
|
||
return $args[(intval($i)-1)%($num-1)+1];
|
||
}
|
||
|
||
/**
|
||
* Replace the starts of the rows
|
||
*
|
||
* @since 2.14.0
|
||
*
|
||
* @param string $text Text
|
||
* @return string Text
|
||
*/
|
||
private function process_row_starts($text) {
|
||
$text = preg_replace(
|
||
array(
|
||
"/\n(----+|____+)/S",
|
||
"/\n-- */S",
|
||
"/\n_ +/S"
|
||
),
|
||
array(
|
||
"\n\n<hr />\n\n",
|
||
"\n<br />— ",
|
||
"\n<br />"
|
||
),
|
||
$text
|
||
);
|
||
return $text;
|
||
}
|
||
|
||
/**
|
||
* Clean the cache
|
||
*
|
||
*/
|
||
public function clean_cache($terms = array()) {
|
||
delete_option("category_children");
|
||
clean_term_cache($terms, 'category');
|
||
}
|
||
|
||
/**
|
||
* Import articles
|
||
*
|
||
* @return bool Import successful or not
|
||
*/
|
||
private function import_articles() {
|
||
$this->log(__('Importing articles...', 'fg-spip-to-wp'));
|
||
|
||
// Anti-duplicate
|
||
$this->test_antiduplicate = false;
|
||
|
||
// Hook for doing other actions before the import
|
||
do_action('fgs2wp_pre_import_articles');
|
||
|
||
do {
|
||
if ( $this->import_stopped() ) {
|
||
break;
|
||
}
|
||
$posts = $this->get_articles($this->chunks_size); // Get the Spip articles
|
||
$posts_count = count($posts);
|
||
|
||
if ( is_array($posts) ) {
|
||
foreach ( $posts as $post ) {
|
||
$new_post_id = $this->import_article($post);
|
||
if ( $new_post_id === false ) {
|
||
return false;
|
||
}
|
||
// Hook for doing other actions after importing the post
|
||
do_action('fgs2wp_post_import_post', $new_post_id, $post, 'article');
|
||
}
|
||
}
|
||
$this->progressbar->increment_current_count($posts_count);
|
||
} while ( ($posts != null) && ($posts_count > 0) );
|
||
|
||
if ( !$this->import_stopped() ) {
|
||
// Hook for doing other actions after the import
|
||
do_action('fgs2wp_post_import_articles');
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Import an article
|
||
*
|
||
* @since 2.0.0
|
||
*
|
||
* @param array $post Post data
|
||
* @return int new post ID | false | WP_Error
|
||
*/
|
||
public function import_article($post) {
|
||
$object_type = 'article';
|
||
|
||
$post['titre'] = FG_Spip_to_WordPress_Tools::fix_encoding($post['titre']);
|
||
$post['texte'] = $this->convert_spip1_longblob($post['texte']); // SPIP 1.x LONGBLOB
|
||
$post['texte'] = FG_Spip_to_WordPress_Tools::fix_encoding($post['texte']);
|
||
$post['chapo'] = FG_Spip_to_WordPress_Tools::fix_encoding($post['chapo']);
|
||
|
||
// Anti-duplicate
|
||
if ( !$this->test_antiduplicate ) {
|
||
sleep(2);
|
||
$test_post_id = $this->get_wp_post_id_from_spip_article_id($post['id']);
|
||
if ( !empty($test_post_id) ) {
|
||
$this->display_admin_error(__('The import process is still running. Please wait before running it again.', 'fg-spip-to-wp'));
|
||
return false;
|
||
}
|
||
$this->test_antiduplicate = true;
|
||
}
|
||
|
||
$post['titre'] = $this->remove_id($post['titre']); // Remove the ID from the title
|
||
|
||
// Hook for modifying the Spip post before processing
|
||
$post = apply_filters('fgs2wp_pre_process_post', $post, $object_type);
|
||
|
||
// Date
|
||
$post_date = $this->sanitize_date($post['date']);
|
||
|
||
$content = $post['texte'];
|
||
$chapo = $post['chapo'];
|
||
|
||
// Medias
|
||
if ( !$this->plugin_options['skip_media'] ) {
|
||
// Featured image
|
||
$featured_image = $this->get_featured_image($post['id'], $object_type);
|
||
list($featured_image, $post) = apply_filters('fgs2wp_pre_import_media', array($featured_image, $post));
|
||
$img_featured_image = '';
|
||
if ( !empty($featured_image) ) {
|
||
$img_featured_image = '<img src="' . $featured_image . '" />';
|
||
}
|
||
|
||
// Replace documents shortcodes
|
||
$chapo = $this->replace_document_shortcodes($chapo);
|
||
$content = $this->replace_document_shortcodes($content);
|
||
|
||
// Import media
|
||
$result = $this->import_media_from_content($img_featured_image . $chapo . $content, $post_date);
|
||
$post_media = $result['media'];
|
||
$this->media_count += $result['media_count'];
|
||
|
||
// Add the logo into the content
|
||
if ( ($this->plugin_options['logo'] != 'as_featured') && !empty($img_featured_image) ) {
|
||
$content = '<p>' . $img_featured_image . '</p>' . $content;
|
||
}
|
||
} else {
|
||
// Skip media
|
||
$post_media = array();
|
||
}
|
||
|
||
// Category
|
||
$categories_ids = array();
|
||
$category_id = $post['id_rubrique'];
|
||
if ( array_key_exists($category_id, $this->imported_categories) ) {
|
||
$categories_ids[] = $this->imported_categories[$category_id];
|
||
}
|
||
if ( count($categories_ids) == 0 ) {
|
||
$categories_ids[] = 1; // default category
|
||
}
|
||
|
||
// Header
|
||
$excerpt = '';
|
||
if ( !empty($chapo) ) {
|
||
switch ( $this->plugin_options['introtext'] ) {
|
||
case 'in_excerpt':
|
||
$excerpt = $chapo;
|
||
break;
|
||
case 'in_content':
|
||
$content = '<p class="post_excerpt">' . $chapo . '</p>' . "\n<!--more-->\n" . $content;
|
||
break;
|
||
case 'in_excerpt_and_content':
|
||
$excerpt = $chapo;
|
||
$content = '<p class="post_excerpt">' . $chapo . '</p>' . $content;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Process content
|
||
$excerpt = $this->process_content($excerpt, $post_media);
|
||
$content = $this->process_content($content, $post_media);
|
||
|
||
// Insert the post
|
||
$new_post = array(
|
||
'post_category' => $categories_ids,
|
||
'post_content' => $content,
|
||
'post_date' => $post_date,
|
||
'post_excerpt' => $excerpt,
|
||
'post_status' => $this->get_status($post['statut']),
|
||
'post_title' => $post['titre'],
|
||
'post_name' => sanitize_title($post['titre']),
|
||
'post_type' => $this->post_type,
|
||
'comment_status' => ($post['accepter_forum'] == 'non')? 'closed' : 'open',
|
||
);
|
||
|
||
// Hook for modifying the WordPress post just before the insert
|
||
$new_post = apply_filters('fgs2wp_pre_insert_post', $new_post, $post, $object_type);
|
||
|
||
$new_post_id = wp_insert_post($new_post, true);
|
||
|
||
// Increment the Spip last imported article ID
|
||
update_option('fgs2wp_last_spip_article_id', $post['id']);
|
||
|
||
if ( is_wp_error($new_post_id) ) {
|
||
$this->display_admin_error(sprintf(__('Article #%d:', 'fg-spip-to-wp'), $post['id']) . ' ' . $new_post_id->get_error_message());
|
||
} else {
|
||
// Add links between the post and its medias
|
||
$this->add_post_media($new_post_id, $new_post, $post_media, $this->plugin_options['logo'] != 'in_content');
|
||
|
||
// Add the Spip ID as a post meta in order to modify links after
|
||
add_post_meta($new_post_id, '_fgs2wp_old_article_id', $post['id'], true);
|
||
|
||
if ( $this->post_type == 'page' ) {
|
||
$this->pages_count++;
|
||
} else {
|
||
$this->posts_count++;
|
||
}
|
||
|
||
// Hook for doing other actions after inserting the post
|
||
do_action('fgs2wp_post_insert_post', $new_post_id, $post, $object_type);
|
||
}
|
||
|
||
return $new_post_id;
|
||
}
|
||
|
||
/**
|
||
* Convert a SPIP 1.x LONGBLOB to TEXT with the UTF8 encoding
|
||
*
|
||
* @since 2.10.0
|
||
*
|
||
* @param string $text Text
|
||
* @return string Text
|
||
*/
|
||
public function convert_spip1_longblob($text) {
|
||
if ( $this->blob_encoding && ($this->spip_charset != 'utf-8') ) {
|
||
$text = utf8_encode($text);
|
||
}
|
||
return $text;
|
||
}
|
||
|
||
/**
|
||
* Import news
|
||
*
|
||
* @return bool Import successful or not
|
||
*/
|
||
private function import_news() {
|
||
$this->log(__('Importing news...', 'fg-spip-to-wp'));
|
||
|
||
// Anti-duplicate
|
||
$this->test_antiduplicate = false;
|
||
|
||
// Hook for doing other actions before the import
|
||
do_action('fgs2wp_pre_import_news');
|
||
|
||
do {
|
||
if ( $this->import_stopped() ) {
|
||
break;
|
||
}
|
||
$posts = $this->get_news($this->chunks_size); // Get the Spip news
|
||
$posts_count = count($posts);
|
||
|
||
if ( is_array($posts) ) {
|
||
foreach ( $posts as $post ) {
|
||
$new_post_id = $this->import_one_news($post);
|
||
if ( $new_post_id === false ) {
|
||
return false;
|
||
}
|
||
// Hook for doing other actions after importing the post
|
||
do_action('fgs2wp_post_import_post', $new_post_id, $post, 'breve');
|
||
}
|
||
}
|
||
$this->progressbar->increment_current_count($posts_count);
|
||
} while ( ($posts != null) && ($posts_count > 0) );
|
||
|
||
if ( !$this->import_stopped() ) {
|
||
// Hook for doing other actions after the import
|
||
do_action('fgs2wp_post_import_news');
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Import a news (breve)
|
||
*
|
||
* @since 2.0.0
|
||
*
|
||
* @param array $post Post data
|
||
* @return int new post ID | false | WP_Error
|
||
*/
|
||
public function import_one_news($post) {
|
||
$object_type = 'breve';
|
||
|
||
$post['titre'] = FG_Spip_to_WordPress_Tools::fix_encoding($post['titre']);
|
||
$post['texte'] = $this->convert_spip1_longblob($post['texte']); // SPIP 1.x LONGBLOB
|
||
$post['texte'] = FG_Spip_to_WordPress_Tools::fix_encoding($post['texte']);
|
||
|
||
// Anti-duplicate
|
||
if ( !$this->test_antiduplicate ) {
|
||
sleep(2);
|
||
$test_post_id = $this->get_wp_post_id_from_spip_news_id($post['id']);
|
||
if ( !empty($test_post_id) ) {
|
||
$this->display_admin_error(__('The import process is still running. Please wait before running it again.', 'fg-spip-to-wp'));
|
||
return false;
|
||
}
|
||
$this->test_antiduplicate = true;
|
||
}
|
||
|
||
// SPIP 2.0 fixes
|
||
if ( version_compare($this->spip_version, '3', '<') ) {
|
||
$post['titre'] = $this->remove_id($post['titre']); // Remove the ID from the title
|
||
}
|
||
|
||
// Hook for modifying the Spip post before processing
|
||
$post = apply_filters('fgs2wp_pre_process_post', $post, $object_type);
|
||
|
||
// Date
|
||
$post_date = $this->sanitize_date($post['date_heure']);
|
||
|
||
$content = $post['texte'];
|
||
|
||
// Medias
|
||
if ( !$this->plugin_options['skip_media'] ) {
|
||
// Featured image
|
||
$featured_image = $this->get_featured_image($post['id'], $object_type);
|
||
list($featured_image, $post) = apply_filters('fgs2wp_pre_import_media', array($featured_image, $post));
|
||
$img_featured_image = '';
|
||
if ( !empty($featured_image) ) {
|
||
$img_featured_image = '<img src="' . $featured_image . '" />';
|
||
}
|
||
|
||
// Replace documents shortcodes
|
||
$content = $this->replace_document_shortcodes($content);
|
||
|
||
// Import media
|
||
$result = $this->import_media_from_content($img_featured_image . $content, $post_date);
|
||
$post_media = $result['media'];
|
||
$this->media_count += $result['media_count'];
|
||
|
||
// Add the logo into the content
|
||
if ( ($this->plugin_options['logo'] != 'as_featured') ) {
|
||
$content = '<p>' . $img_featured_image . '</p>' . $content;
|
||
}
|
||
} else {
|
||
// Skip media
|
||
$post_media = array();
|
||
}
|
||
|
||
// Category
|
||
$categories_ids = $this->get_wp_category_ids($post['id_rubrique'], $this->imported_categories);
|
||
|
||
// Process content
|
||
$content = $this->process_content($content, $post_media);
|
||
|
||
// Insert the post
|
||
$new_post = array(
|
||
'post_category' => $categories_ids,
|
||
'post_content' => $content,
|
||
'post_excerpt' => '',
|
||
'post_date' => $post_date,
|
||
'post_status' => $this->get_status($post['statut']),
|
||
'post_title' => $post['titre'],
|
||
'post_name' => sanitize_title($post['titre']),
|
||
'post_type' => 'post',
|
||
);
|
||
|
||
// Hook for modifying the WordPress post just before the insert
|
||
$new_post = apply_filters('fgs2wp_pre_insert_post', $new_post, $post, $object_type);
|
||
|
||
$new_post_id = wp_insert_post($new_post, true);
|
||
|
||
// Increment the Spip last imported post ID
|
||
update_option('fgs2wp_last_spip_news_id', $post['id']);
|
||
|
||
if ( is_wp_error($new_post_id) ) {
|
||
$this->display_admin_error(sprintf(__('Article #%d:', 'fg-spip-to-wp'), $post['id']) . ' ' . $new_post_id->get_error_message());
|
||
} else {
|
||
// Add links between the post and its medias
|
||
$this->add_post_media($new_post_id, $new_post, $post_media, $this->plugin_options['logo'] != 'in_content');
|
||
|
||
// Add the Spip ID as a post meta in order to modify links after
|
||
add_post_meta($new_post_id, '_fgs2wp_old_news_id', $post['id'], true);
|
||
|
||
// Add the extra SPIP fields
|
||
if ( !empty($post['lien_titre']) ) {
|
||
add_post_meta($new_post_id, 'lien_titre', $post['lien_titre'], true);
|
||
}
|
||
if ( !empty($post['lien_url']) ) {
|
||
add_post_meta($new_post_id, 'lien_url', $post['lien_url'], true);
|
||
}
|
||
|
||
$this->posts_count++;
|
||
|
||
// Hook for doing other actions after inserting the post
|
||
do_action('fgs2wp_post_insert_post', $new_post_id, $post, $object_type);
|
||
}
|
||
|
||
return $new_post_id;
|
||
}
|
||
|
||
/**
|
||
* Get the WordPress status from the SPIP status
|
||
*
|
||
* @since 1.9.0
|
||
*
|
||
* @param string $spip_status SPIP status
|
||
* @return string WordPress status
|
||
*/
|
||
public function get_status($spip_status) {
|
||
switch ( $spip_status ) {
|
||
case 'publie': // published
|
||
$status = 'publish';
|
||
break;
|
||
case 'prop': // pending
|
||
$status = 'pending';
|
||
break;
|
||
default:
|
||
$status = 'draft';
|
||
}
|
||
return $status;
|
||
}
|
||
|
||
/**
|
||
* Remove the ID at the beginning of a string
|
||
*
|
||
* @param string $string String
|
||
* @return string String
|
||
*/
|
||
public function remove_id($string) {
|
||
$result = preg_replace('/^\d+\. /', '', $string);
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Replace the articles shortcodes (art, br) in the post content
|
||
*
|
||
* @since 2.30.0
|
||
*
|
||
* @param string $content Content
|
||
* @return string Content
|
||
*/
|
||
private function replace_articles_shortcodes($content) {
|
||
$matches = array();
|
||
// Replace the shortcodes like [anchor_text->art99] or [anchor_text->br99]
|
||
if ( preg_match_all('#\[(.*?)->(art|br)(\d+)\]#', $content, $matches, PREG_SET_ORDER) > 0 ) {
|
||
foreach ($matches as $match ) {
|
||
$anchor_text = $match[1];
|
||
$short_object_type = $match[2]; // art | br
|
||
$id = $match[3];
|
||
$object_type = ($short_object_type == 'br')? 'breve' : 'article';
|
||
if ( empty($anchor_text) ) {
|
||
$anchor_text = $this->get_article_or_news_title($id, $object_type);
|
||
}
|
||
$replacement = '<a href="' . $object_type . $id . '.html">' . $anchor_text . '</a>';
|
||
$content = preg_replace('#' . preg_quote($match[0]) . '#', $replacement, $content);
|
||
}
|
||
}
|
||
return $content;
|
||
}
|
||
|
||
/**
|
||
* Get the title of the article (or the news)
|
||
*
|
||
* @since 2.30.0
|
||
*
|
||
* @param int $id Object ID
|
||
* @param string $object_type Object type
|
||
* @return string Title
|
||
*/
|
||
private function get_article_or_news_title($id, $object_type) {
|
||
if ( $object_type == 'br' ) {
|
||
$title = $this->get_news_title($id);
|
||
} else {
|
||
$title = $this->get_article_title($id);
|
||
}
|
||
return $title;
|
||
}
|
||
|
||
/**
|
||
* Get a news title
|
||
*
|
||
* @since 2.30.0
|
||
*
|
||
* @param int $id News ID
|
||
* @return string Title
|
||
*/
|
||
private function get_news_title($id) {
|
||
$title = 'Breve ' . $id;
|
||
$prefix = $this->plugin_options['prefix'];
|
||
$sql = "
|
||
SELECT titre
|
||
FROM ${prefix}breves b
|
||
WHERE b.id_breve = '$id'
|
||
LIMIT 1
|
||
";
|
||
$result = $this->spip_query($sql);
|
||
if ( count($result) > 0 ) {
|
||
$title = $result[0]['titre'];
|
||
}
|
||
return $title;
|
||
}
|
||
|
||
/**
|
||
* Get an article title
|
||
*
|
||
* @since 2.30.0
|
||
*
|
||
* @param int $id Article ID
|
||
* @return string Title
|
||
*/
|
||
private function get_article_title($id) {
|
||
$title = 'Article ' . $id;
|
||
$prefix = $this->plugin_options['prefix'];
|
||
$sql = "
|
||
SELECT titre
|
||
FROM ${prefix}articles a
|
||
WHERE a.id_article = '$id'
|
||
LIMIT 1
|
||
";
|
||
$result = $this->spip_query($sql);
|
||
if ( count($result) > 0 ) {
|
||
$title = $result[0]['titre'];
|
||
}
|
||
return $title;
|
||
}
|
||
|
||
/**
|
||
* Replace the documents shortcodes (doc, img, emb, pdf) in the post content
|
||
* @param string $content Content
|
||
* @return string Content
|
||
*/
|
||
private function replace_document_shortcodes($content) {
|
||
$matches = array();
|
||
$matches_align = array();
|
||
// Import the medias that use the SPIP shortcodes <doc>, <img>, <emb> or <pdf>
|
||
if ( preg_match_all('#<(doc|img|emb|pdf)(\d+)(\|(.*?))?>#', $content, $matches, PREG_SET_ORDER) > 0 ) {
|
||
foreach ($matches as $match ) {
|
||
// $doc_embed_type = $match[1]; // doc | img | emb | pdf
|
||
$doc_id = $match[2];
|
||
$doc_align = isset($match[4])? $match[4]: '';
|
||
$document = $this->get_document($doc_id);
|
||
if ( !empty($document) ) {
|
||
$filename = $document['fichier'];
|
||
if ( !preg_match('/^http/', $document['fichier']) ) {
|
||
$filename = $this->media_path . $filename;
|
||
}
|
||
if ( preg_match('/^txt=(.*)/', $doc_align, $matches_align) ) {
|
||
$doc_title = $matches_align[1];
|
||
} elseif ( !empty($document['titre']) ) {
|
||
$doc_title = $document['titre'];
|
||
} else {
|
||
$doc_title = basename($document['fichier']);
|
||
}
|
||
$filetype = wp_check_filetype($filename);
|
||
|
||
// Description
|
||
$description = !empty($document['descriptif'])? ' data-description="' . $document['descriptif'] . '"' : '';
|
||
|
||
if ( preg_match('/image/', $filetype['type']) ) {
|
||
// Image
|
||
// Alignment
|
||
$alignment = '';
|
||
if ( !empty($doc_align) ) {
|
||
$alignment = ' align="' . $doc_align . '"';
|
||
}
|
||
if ( !empty($document['titre']) ) {
|
||
// With caption
|
||
$replacement = '<img src="' . $filename . '" alt="' . $doc_title . '" title="' . $document['titre'] . '" class="caption"' . $description . $alignment . ' />';
|
||
} else {
|
||
$replacement = '<img src="' . $filename . '" alt="' . $doc_title . '"' . $description . $alignment . ' />';
|
||
}
|
||
} elseif ( preg_match('#^https://www.youtube.com#', $filename) ) {
|
||
// Embed YouTube video
|
||
$replacement = '[embed]' . $filename . '[/embed]';
|
||
} else {
|
||
// Not an image
|
||
$replacement = '<a href="' . $filename . '"' . $description . '>' . $doc_title . '</a>';
|
||
}
|
||
$content = preg_replace('#' . preg_quote($match[0]) . '#', $replacement, $content);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Import the medias that use the SPIP shortcodes [anchor_text->img]
|
||
if ( preg_match_all('#\[(.*?)->(doc|img|emb|pdf)(\d+)\]#', $content, $matches, PREG_SET_ORDER) > 0 ) {
|
||
foreach ($matches as $match ) {
|
||
$anchor_text = $match[1];
|
||
// $doc_embed_type = $match[2]; // doc | img | emb | pdf
|
||
$doc_id = $match[3];
|
||
$document = $this->get_document($doc_id);
|
||
if ( !empty($document) ) {
|
||
$filename = $this->media_path . $document['fichier'];
|
||
// Description
|
||
$description = !empty($document['descriptif'])? ' data-description="' . $document['descriptif'] . '"' : '';
|
||
|
||
$replacement = '<a href="' . $filename . '"' . $description . '>' . $anchor_text . '</a>';
|
||
$content = preg_replace('#' . preg_quote($match[0]) . '#', $replacement, $content);
|
||
}
|
||
}
|
||
}
|
||
return $content;
|
||
}
|
||
|
||
/**
|
||
* Get the matching WP category ID from a SPIP category
|
||
*
|
||
* @since 2.5.0
|
||
*
|
||
* @param int $category_id SPIP category ID
|
||
* @param array $imported_categories Mapping table of SPIP and WP categories IDs
|
||
* @return array List of categories IDs
|
||
*/
|
||
public function get_wp_category_ids($category_id, $imported_categories) {
|
||
$categories_ids = array();
|
||
if ( array_key_exists($category_id, $imported_categories) ) {
|
||
$categories_ids[] = $imported_categories[$category_id];
|
||
}
|
||
if ( count($categories_ids) == 0 ) {
|
||
$categories_ids[] = 1; // default category
|
||
}
|
||
return $categories_ids;
|
||
}
|
||
|
||
/**
|
||
* Stop the import
|
||
*
|
||
*/
|
||
public function stop_import() {
|
||
update_option('fgs2wp_stop_import', true);
|
||
}
|
||
|
||
/**
|
||
* Test if the import needs to stop
|
||
*
|
||
* @return boolean Import needs to stop or not
|
||
*/
|
||
public function import_stopped() {
|
||
return get_option('fgs2wp_stop_import');
|
||
}
|
||
|
||
/**
|
||
* Get Spip categories
|
||
*
|
||
* @param int $limit Number of categories max
|
||
* @return array of Categories
|
||
*/
|
||
protected function get_categories($limit=1000) {
|
||
$categories = array();
|
||
|
||
$prefix = $this->plugin_options['prefix'];
|
||
$last_category_id = (int)get_option('fgs2wp_last_category_id'); // to restore the import where it left
|
||
$sql = "
|
||
SELECT r.id_rubrique, r.id_parent, r.titre, r.descriptif, r.texte
|
||
FROM ${prefix}rubriques r
|
||
WHERE r.id_rubrique > '$last_category_id'
|
||
ORDER BY r.id_rubrique
|
||
LIMIT $limit
|
||
";
|
||
$sql = apply_filters('fgs2wp_get_categories_sql', $sql, $prefix);
|
||
$categories = $this->spip_query($sql);
|
||
$categories = apply_filters('fgs2wp_get_categories', $categories);
|
||
|
||
return $categories;
|
||
}
|
||
|
||
/**
|
||
* Get Spip articles
|
||
*
|
||
* @param int $limit Number of articles max
|
||
* @return array of articles
|
||
*/
|
||
protected function get_articles($limit=1000) {
|
||
$articles = array();
|
||
|
||
$last_spip_article_id = (int)get_option('fgs2wp_last_spip_article_id'); // to restore the import where it left
|
||
$prefix = $this->plugin_options['prefix'];
|
||
|
||
// Hooks for adding extra cols and extra joins
|
||
$extra_cols = apply_filters('fgs2wp_get_posts_add_extra_cols', '', 'article');
|
||
$extra_joins = apply_filters('fgs2wp_get_posts_add_extra_joins', '', 'article');
|
||
|
||
$sql = "
|
||
SELECT a.id_article AS id, a.titre, a.id_rubrique, a.chapo, a.texte, a.date, a.statut, a.visites, a.accepter_forum
|
||
$extra_cols
|
||
FROM ${prefix}articles a
|
||
$extra_joins
|
||
WHERE a.statut NOT IN ('refuse', 'poubelle') -- don't get the cancelled and the removed articles
|
||
AND a.id_article > '$last_spip_article_id'
|
||
ORDER BY a.id_article
|
||
LIMIT $limit
|
||
";
|
||
$sql = apply_filters('fgs2wp_get_posts_sql', $sql, $prefix, $extra_cols, $extra_joins, $last_spip_article_id, $limit);
|
||
|
||
$articles = $this->spip_query($sql);
|
||
return $articles;
|
||
}
|
||
|
||
/**
|
||
* Get Spip news
|
||
*
|
||
* @param int $limit Number of news max
|
||
* @return array of news
|
||
*/
|
||
protected function get_news($limit=1000) {
|
||
$news = array();
|
||
|
||
$last_spip_news_id = (int)get_option('fgs2wp_last_spip_news_id'); // to restore the import where it left
|
||
$prefix = $this->plugin_options['prefix'];
|
||
|
||
// Hooks for adding extra cols and extra joins
|
||
$extra_cols = apply_filters('fgs2wp_get_posts_add_extra_cols', '', 'breve');
|
||
$extra_joins = apply_filters('fgs2wp_get_posts_add_extra_joins', '', 'breve');
|
||
|
||
$sql = "
|
||
SELECT b.id_breve AS id, b.titre, b.id_rubrique, b.texte, b.date_heure, b.statut, b.lien_titre, b.lien_url
|
||
$extra_cols
|
||
FROM ${prefix}breves b
|
||
$extra_joins
|
||
WHERE b.statut NOT IN ('refuse', 'poubelle') -- don't get the cancelled and the removed news
|
||
AND b.id_breve > '$last_spip_news_id'
|
||
ORDER BY b.id_breve
|
||
LIMIT $limit
|
||
";
|
||
$sql = apply_filters('fgs2wp_get_posts_sql', $sql, $prefix, $extra_cols, $extra_joins, $last_spip_news_id, $limit);
|
||
|
||
$news = $this->spip_query($sql);
|
||
return $news;
|
||
}
|
||
|
||
/**
|
||
* Get the featured image of an article or from a news
|
||
*
|
||
* @param int $post_id
|
||
* @param string $object_type article | breve
|
||
* @return string Image path
|
||
*/
|
||
protected function get_featured_image($post_id, $object_type) {
|
||
$images_path = trailingslashit($this->get_media_root_path()) . $this->media_path;
|
||
|
||
// Object type
|
||
switch ( $object_type ) {
|
||
case 'article': $prefix = 'arton'; break;
|
||
case 'breve': $prefix = 'breveon'; break;
|
||
default: return ''; // unknown type
|
||
}
|
||
|
||
// Extensions
|
||
$extensions = array('jpg', 'JPG', 'png', 'PNG', 'gif', 'GIF');
|
||
foreach ( $extensions as $extension ) {
|
||
$image_file_path = $images_path . $prefix . $post_id . '.' . $extension;
|
||
if ( $this->file_exists($image_file_path) ) {
|
||
return $image_file_path;
|
||
}
|
||
}
|
||
return '';
|
||
}
|
||
|
||
/**
|
||
* Get the media root path
|
||
*
|
||
* @since 2.3.0
|
||
*
|
||
* @return string Media root path
|
||
*/
|
||
public function get_media_root_path() {
|
||
$path = '';
|
||
switch ( $this->plugin_options['media_import_method'] ) {
|
||
case 'http':
|
||
$path = $this->plugin_options['url'];
|
||
break;
|
||
case 'local':
|
||
$path = $this->plugin_options['root_directory'];
|
||
break;
|
||
}
|
||
return $path;
|
||
}
|
||
|
||
/**
|
||
* Test if a file exists
|
||
*
|
||
* @since 2.3.0
|
||
*
|
||
* @param string $filePath
|
||
* @return boolean True if the file exists
|
||
*/
|
||
public function file_exists($filePath) {
|
||
switch ( $this->plugin_options['media_import_method'] ) {
|
||
case 'http':
|
||
return $this->url_exists($filePath);
|
||
case 'local':
|
||
return file_exists($filePath);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Test if a remote file exists
|
||
*
|
||
* @param string $filePath
|
||
* @return boolean True if the file exists
|
||
*/
|
||
public function url_exists($filePath) {
|
||
$url = str_replace(' ', '%20', $filePath);
|
||
|
||
// Try the get_headers method
|
||
$headers = @get_headers($url);
|
||
$result = preg_match("/200/", $headers[0]);
|
||
|
||
if ( !$result && strpos($filePath, 'https:') !== 0 ) {
|
||
// Try the fsock method
|
||
$url = str_replace('http://', '', $url);
|
||
if ( strstr($url, '/') ) {
|
||
$url = explode('/', $url, 2);
|
||
$url[1] = '/' . $url[1];
|
||
} else {
|
||
$url = array($url, '/');
|
||
}
|
||
|
||
$fh = fsockopen($url[0], 80);
|
||
if ( $fh ) {
|
||
fputs($fh,'GET ' . $url[1] . " HTTP/1.1\nHost:" . $url[0] . "\n");
|
||
fputs($fh,"User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36\n\n");
|
||
$response = fread($fh, 22);
|
||
fclose($fh);
|
||
$result = (strpos($response, '200') !== false);
|
||
} else {
|
||
$result = false;
|
||
}
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Get the image path
|
||
*
|
||
* @return string Image path
|
||
*/
|
||
public function get_image_path() {
|
||
$dir_img = $this->get_spip_meta('dir_img');
|
||
if ( empty($dir_img) ) {
|
||
$dir_img = 'IMG/';
|
||
}
|
||
return $dir_img;
|
||
}
|
||
|
||
/**
|
||
* Get the SPIP version
|
||
*
|
||
* @return string SPIP version
|
||
*/
|
||
private function get_spip_version() {
|
||
$version = 0;
|
||
$raw_plugin_info = $this->get_spip_meta('plugin');
|
||
if ( strpos($raw_plugin_info, 'a:') !== false ) {
|
||
$plugin_info = @unserialize($raw_plugin_info);
|
||
if ( !$plugin_info ) {
|
||
$plugin_info = @unserialize(utf8_decode($raw_plugin_info));
|
||
}
|
||
$version = isset($plugin_info['SPIP']['version'])? $plugin_info['SPIP']['version']: 0;
|
||
} else {
|
||
$version_installee = $this->get_spip_meta('version_installee');
|
||
$version = !empty($version_installee)? $version_installee: 0;
|
||
}
|
||
return $version;
|
||
}
|
||
|
||
/**
|
||
* Get the meta value from the SPIP meta table
|
||
*
|
||
* @param string $meta_key
|
||
* @return string meta value
|
||
*/
|
||
public function get_spip_meta($meta_key) {
|
||
$meta_value = '';
|
||
|
||
$prefix = $this->plugin_options['prefix'];
|
||
$sql = "
|
||
SELECT m.valeur
|
||
FROM ${prefix}meta m
|
||
WHERE m.nom = '$meta_key'
|
||
LIMIT 1
|
||
";
|
||
$result = $this->spip_query($sql);
|
||
if ( isset($result[0]['valeur']) ) {
|
||
$meta_value = $result[0]['valeur'];
|
||
}
|
||
return $meta_value;
|
||
}
|
||
|
||
/**
|
||
* Test if the texts are encoded as blob
|
||
*
|
||
* @return bool
|
||
*/
|
||
private function is_text_encoded_as_blob() {
|
||
global $spip_db;
|
||
$blob_encoded = false;
|
||
|
||
$prefix = $this->plugin_options['prefix'];
|
||
$table = 'articles';
|
||
$column = 'texte';
|
||
switch ( $this->plugin_options['driver'] ) {
|
||
case 'mysql':
|
||
$sql = "SHOW COLUMNS FROM ${prefix}${table} LIKE '$column'";
|
||
break;
|
||
case 'sqlite':
|
||
$sql = "PRAGMA table_info(${prefix}${table})";
|
||
break;
|
||
}
|
||
$query = $spip_db->query($sql, PDO::FETCH_ASSOC);
|
||
if ( $query !== false ) {
|
||
if ( $this->plugin_options['driver'] == 'sqlite' ) {
|
||
// SQLite
|
||
$result = $query->fetchAll();
|
||
foreach ( $result as $row ) {
|
||
if ( isset($row['name']) && ($row['name'] == $column) ) {
|
||
if ( preg_match('/blob/', $row['type']) ) {
|
||
$blob_encoded = true;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
// MySQL
|
||
$result = $query->fetch();
|
||
if ( isset($result['Type']) && preg_match('/blob/', $result['Type']) ) {
|
||
$blob_encoded = true;
|
||
}
|
||
}
|
||
}
|
||
return $blob_encoded;
|
||
}
|
||
|
||
/**
|
||
* Import post medias from content
|
||
*
|
||
* @param string $content post content
|
||
* @param date $post_date Post date (for storing media)
|
||
* @param array $options Options
|
||
* @return array:
|
||
* array media: Medias imported
|
||
* int media_count: Medias count
|
||
*/
|
||
public function import_media_from_content($content, $post_date, $options=array()) {
|
||
$media = array();
|
||
$media_count = 0;
|
||
$matches = array();
|
||
$alt_matches = array();
|
||
$title_matches = array();
|
||
$description_matches = array();
|
||
|
||
if ( preg_match_all('#<(img|a)(.*?)(src|href)="(.*?)"(.*?)>#', $content, $matches, PREG_SET_ORDER) > 0 ) {
|
||
if ( is_array($matches) ) {
|
||
foreach ($matches as $match ) {
|
||
$filename = $match[4];
|
||
$other_attributes = $match[2] . $match[5];
|
||
// Image Alt
|
||
$image_alt = '';
|
||
if (preg_match('#alt="(.*?)"#', $other_attributes, $alt_matches) ) {
|
||
$image_alt = wp_strip_all_tags(stripslashes($alt_matches[1]), true);
|
||
}
|
||
// Image caption
|
||
$image_caption = '';
|
||
if (preg_match('#title="(.*?)"#', $other_attributes, $title_matches) ) {
|
||
$image_caption = $title_matches[1];
|
||
}
|
||
// Image description
|
||
$image_description = '';
|
||
if (preg_match('#data-description="(.*?)"#', $other_attributes, $description_matches) ) {
|
||
$image_description = $description_matches[1];
|
||
}
|
||
$attachment_id = $this->import_media($image_alt, $filename, $post_date, $options, $image_caption, $image_description);
|
||
if ( $attachment_id !== false ) {
|
||
$media_count++;
|
||
$media[$filename] = $attachment_id;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return array(
|
||
'media' => $media,
|
||
'media_count' => $media_count
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Import a media
|
||
*
|
||
* @param string $name Image name
|
||
* @param string $filename Image URL
|
||
* @param date $date Date
|
||
* @param array $options Options
|
||
* @param string $image_caption Image caption
|
||
* @param string $image_description Image description
|
||
* @return int attachment ID or false
|
||
*/
|
||
public function import_media($name, $filename, $date, $options=array(), $image_caption='', $image_description='') {
|
||
if ( $date == '0000-00-00 00:00:00' ) {
|
||
$date = date('Y-m-d H:i:s');
|
||
}
|
||
$import_external = ($this->plugin_options['import_external'] == 1) || (isset($options['force_external']) && $options['force_external'] );
|
||
|
||
$filename = urldecode(html_entity_decode($filename)); // for filenames with spaces or accents
|
||
|
||
$filetype = wp_check_filetype($filename);
|
||
if ( empty($filetype['type']) || ($filetype['type'] == 'text/html') ) { // Unrecognized file type
|
||
return false;
|
||
}
|
||
|
||
$media_root_path = $this->get_media_root_path();
|
||
|
||
// Upload the file from the Spip web site to WordPress upload dir
|
||
if ( preg_match('/^http/', $filename) ) {
|
||
if ( $import_external || // External file
|
||
preg_match('#^' . $media_root_path . '#', $filename) // Local file
|
||
) {
|
||
$old_filename = $filename;
|
||
} else {
|
||
return false;
|
||
}
|
||
} elseif ( strpos($filename, $media_root_path) !== 0 ) { // Don't add the media_root_path if it has already been added
|
||
if ( strpos($filename, '/') === 0 ) { // Avoid a double slash
|
||
$old_filename = untrailingslashit($media_root_path) . $filename;
|
||
} else {
|
||
$old_filename = trailingslashit($media_root_path) . $filename;
|
||
}
|
||
} else {
|
||
$old_filename = $filename;
|
||
}
|
||
if ( $this->plugin_options['media_import_method'] == 'http' ) {
|
||
$old_filename = str_replace(" ", "%20", $old_filename); // for filenames with spaces
|
||
}
|
||
$img_dir = strftime('%Y/%m', strtotime($date));
|
||
$uploads = wp_upload_dir($img_dir);
|
||
$new_upload_dir = $uploads['path'];
|
||
|
||
$new_filename = $filename;
|
||
if ( $this->plugin_options['import_duplicates'] == 1 ) {
|
||
// Images with duplicate names
|
||
$new_filename = preg_replace('#.*'. untrailingslashit($this->media_path) . '/#', '', $new_filename);
|
||
$new_filename = str_replace('http://', '', $new_filename);
|
||
$new_filename = str_replace('/', '_', $new_filename);
|
||
}
|
||
|
||
$basename = basename($new_filename);
|
||
$basename = sanitize_file_name($basename);
|
||
$new_full_filename = $new_upload_dir . '/' . $basename;
|
||
|
||
if ( $this->plugin_options['force_media_import'] || !file_exists($new_full_filename) || (filesize($new_full_filename) == 0) ) {
|
||
// print "Copy \"$old_filename\" => $new_full_filename<br />";
|
||
switch ( $this->plugin_options['media_import_method'] ) {
|
||
case 'http':
|
||
// HTTP remote copy
|
||
if ( ! @$this->remote_copy($old_filename, $new_full_filename) ) {
|
||
$error = error_get_last();
|
||
$error_message = $error['message'];
|
||
$this->display_admin_error("Can't copy $old_filename to $new_full_filename : $error_message");
|
||
return false;
|
||
}
|
||
break;
|
||
case 'local':
|
||
// Local copy
|
||
if ( !copy($old_filename, $new_full_filename) ) {
|
||
$error = error_get_last();
|
||
$error_message = $error['message'];
|
||
$this->display_admin_error("Can't copy $old_filename to $new_full_filename : $error_message");
|
||
return false;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
$post_title = !empty($name)? $name : preg_replace('/\.[^.]+$/', '', $basename);
|
||
|
||
// Image Alt
|
||
$image_alt = '';
|
||
if ( !empty($name) ) {
|
||
$image_alt = wp_strip_all_tags(stripslashes($name), true);
|
||
}
|
||
|
||
// GUID
|
||
$upload_dir = wp_upload_dir();
|
||
$guid = str_replace($upload_dir['basedir'], $upload_dir['baseurl'], $new_full_filename);
|
||
|
||
$attachment_id = $this->insert_attachment($post_title, $basename, $new_full_filename, $guid, $date, $filetype['type'], $image_alt, $image_caption, $image_description);
|
||
return $attachment_id;
|
||
}
|
||
|
||
/**
|
||
* Check if the attachment exists in the database
|
||
*
|
||
* @param string $name
|
||
* @return object Post
|
||
*/
|
||
private function get_attachment_from_name($name) {
|
||
$name = preg_replace('/\.[^.]+$/', '', basename($name));
|
||
$r = array(
|
||
'name' => $name,
|
||
'post_type' => 'attachment',
|
||
'numberposts' => 1,
|
||
);
|
||
$posts_array = get_posts($r);
|
||
if ( is_array($posts_array) && (count($posts_array) > 0) ) {
|
||
return $posts_array[0];
|
||
}
|
||
else {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Save the attachment and generates its metadata
|
||
*
|
||
* @param string $attachment_title Attachment name
|
||
* @param string $basename Original attachment filename
|
||
* @param string $new_full_filename New attachment filename with path
|
||
* @param string $guid GUID
|
||
* @param date $date Date
|
||
* @param string $filetype File type
|
||
* @param string $image_alt Image description
|
||
* @param string $image_caption Image caption
|
||
* @param string $image_description Image description
|
||
* @return int|false Attachment ID or false
|
||
*/
|
||
public function insert_attachment($attachment_title, $basename, $new_full_filename, $guid, $date, $filetype, $image_alt='', $image_caption='', $image_description='') {
|
||
$post_name = 'attachment-' . sanitize_title($attachment_title); // Prefix the post name to avoid wrong redirect to a post with the same name
|
||
|
||
// If the attachment does not exist yet, insert it in the database
|
||
$attachment_id = 0;
|
||
$attachment = $this->get_attachment_from_name($post_name);
|
||
if ( $attachment ) {
|
||
$attached_file = basename(get_attached_file($attachment->ID));
|
||
if ( $attached_file == $basename ) { // Check if the filename is the same (in case of the legend is not unique)
|
||
$attachment_id = $attachment->ID;
|
||
}
|
||
}
|
||
if ( $attachment_id == 0 ) {
|
||
$attachment_data = array(
|
||
'guid' => $guid,
|
||
'post_date' => $date,
|
||
'post_mime_type' => $filetype,
|
||
'post_name' => $post_name,
|
||
'post_title' => $attachment_title,
|
||
'post_status' => 'inherit',
|
||
'post_content' => $image_description,
|
||
'post_excerpt' => $image_caption,
|
||
);
|
||
$attachment_id = wp_insert_attachment($attachment_data, $new_full_filename);
|
||
add_post_meta($attachment_id, '_fgs2wp_imported', 1, true); // To delete the imported attachments
|
||
}
|
||
|
||
if ( !empty($attachment_id) ) {
|
||
if ( preg_match('/(image|audio|video)/', $filetype) ) { // Image, audio or video
|
||
// you must first include the image.php file
|
||
// for the function wp_generate_attachment_metadata() to work
|
||
require_once(ABSPATH . 'wp-admin/includes/image.php');
|
||
$attach_data = wp_generate_attachment_metadata( $attachment_id, $new_full_filename );
|
||
wp_update_attachment_metadata($attachment_id, $attach_data);
|
||
|
||
// Image Alt
|
||
if ( !empty($image_alt) ) {
|
||
update_post_meta($attachment_id, '_wp_attachment_image_alt', addslashes($image_alt)); // update_post_meta expects slashed
|
||
}
|
||
}
|
||
return $attachment_id;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get a document by its ID
|
||
*
|
||
* @param int $doc_id SPIP document ID
|
||
* @return array document data
|
||
*/
|
||
private function get_document($doc_id) {
|
||
$document = array();
|
||
$prefix = $this->plugin_options['prefix'];
|
||
|
||
$sql = "
|
||
SELECT d.id_document, d.fichier, d.titre, d.descriptif, d.taille, d.date
|
||
FROM ${prefix}documents d
|
||
WHERE d.id_document = '$doc_id'
|
||
LIMIT 1
|
||
";
|
||
$documents = $this->spip_query($sql);
|
||
if ( isset($documents[0]) ) {
|
||
$document = $documents[0];
|
||
}
|
||
return $document;
|
||
}
|
||
|
||
/**
|
||
* Process the post content
|
||
*
|
||
* @param string $content Post content
|
||
* @param array $post_media Post medias
|
||
* @return string Processed post content
|
||
*/
|
||
public function process_content($content, $post_media=array()) {
|
||
|
||
if ( !empty($content) ) {
|
||
$content = $this->replace_articles_shortcodes($content);
|
||
|
||
$content = $this->spip_format($content);
|
||
|
||
$content = preg_replace("/\\\\+'/", "'", $content); // Fix the multiple escapes of '
|
||
|
||
// Replace media URLs with the new URLs
|
||
$content = $this->process_content_media_links($content, $post_media);
|
||
|
||
// Replace video links
|
||
$content = $this->process_video_links($content);
|
||
|
||
// For importing backslashes
|
||
$content = addslashes($content);
|
||
|
||
$content = apply_filters('fgs2wp_process_content', $content);
|
||
}
|
||
|
||
return $content;
|
||
}
|
||
|
||
/**
|
||
* Replace media URLs with the new URLs
|
||
*
|
||
* @param string $content Post content
|
||
* @param array $post_media Post medias
|
||
* @return string Processed post content
|
||
*/
|
||
private function process_content_media_links($content, $post_media) {
|
||
$matches = array();
|
||
$matches_caption = array();
|
||
|
||
if ( is_array($post_media) ) {
|
||
|
||
// Get the attachments attributes
|
||
$attachments_found = false;
|
||
$medias = array();
|
||
foreach ( $post_media as $old_filename => $attachment_id ) {
|
||
$media = array();
|
||
$media['attachment_id'] = $attachment_id;
|
||
$media['url_old_filename'] = urlencode($old_filename); // for filenames with spaces
|
||
if ( preg_match('/image/', get_post_mime_type($attachment_id)) ) {
|
||
// Image
|
||
$image_src = wp_get_attachment_image_src($attachment_id, 'full');
|
||
$media['new_url'] = $image_src[0];
|
||
$media['width'] = $image_src[1];
|
||
$media['height'] = $image_src[2];
|
||
} else {
|
||
// Other media
|
||
$media['new_url'] = wp_get_attachment_url($attachment_id);
|
||
}
|
||
$medias[$old_filename] = $media;
|
||
$attachments_found = true;
|
||
}
|
||
if ( $attachments_found ) {
|
||
|
||
// Remove the links from the content
|
||
$this->post_link_count = 0;
|
||
$this->post_link = array();
|
||
$content = preg_replace_callback('#<(a) (.*?)(href)=(.*?)</a>#i', array($this, 'remove_links'), $content);
|
||
$content = preg_replace_callback('#<(img) (.*?)(src)=(.*?)>#i', array($this, 'remove_links'), $content);
|
||
|
||
// Process the stored medias links
|
||
foreach ($this->post_link as &$link) {
|
||
|
||
$new_link = $link['old_link'];
|
||
$alignment = '';
|
||
if ( preg_match('/(align="|float: )(left|right|center)/', $new_link, $matches) ) {
|
||
$alignment = 'align' . $matches[2];
|
||
}
|
||
if ( preg_match_all('#(src|href)="(.*?)"#i', $new_link, $matches, PREG_SET_ORDER) ) {
|
||
$caption = '';
|
||
foreach ( $matches as $match ) {
|
||
$old_filename = $match[2];
|
||
$link_type = ($match[1] == 'src')? 'img': 'a';
|
||
if ( array_key_exists($old_filename, $medias) ) {
|
||
$media = $medias[$old_filename];
|
||
if ( array_key_exists('new_url', $media) ) {
|
||
if ( (strpos($new_link, $old_filename) > 0) || (strpos($new_link, $media['url_old_filename']) > 0) ) {
|
||
// URL encode the filename
|
||
$new_filename = basename($media['new_url']);
|
||
$encoded_new_filename = rawurlencode($new_filename);
|
||
$new_url = str_replace($new_filename, $encoded_new_filename, $media['new_url']);
|
||
$new_link = preg_replace('#(' . preg_quote($old_filename) . '|' . preg_quote($media['url_old_filename']) . ')#', $new_url, $new_link, 1);
|
||
|
||
if ( $link_type == 'img' ) { // images only
|
||
// Define the width and the height of the image if it isn't defined yet
|
||
if ((strpos($new_link, 'width=') === false) && (strpos($new_link, 'height=') === false)) {
|
||
$width_assertion = isset($media['width']) && ($media['width'] != 0)? ' width="' . $media['width'] . '"' : '';
|
||
$height_assertion = isset($media['height']) && ($media['height'] != 0)? ' height="' . $media['height'] . '"' : '';
|
||
} else {
|
||
$width_assertion = '';
|
||
$height_assertion = '';
|
||
}
|
||
|
||
// Caption shortcode
|
||
if ( preg_match('/class=".*caption.*?"/', $link['old_link']) ) {
|
||
if ( preg_match('/title="(.*?)"/', $link['old_link'], $matches_caption) ) {
|
||
$caption_value = str_replace('%', '%%', $matches_caption[1]);
|
||
$align_value = ($alignment != '')? $alignment : 'alignnone';
|
||
$caption = '[caption id="attachment_' . $media['attachment_id'] . '" align="' . $align_value . '"' . $width_assertion . ']%s' . $caption_value . '[/caption]';
|
||
}
|
||
}
|
||
|
||
$align_class = ($alignment != '')? $alignment . ' ' : '';
|
||
$new_link = preg_replace('#<img(.*?)( class="(.*?)")?(.*) />#', "<img$1 class=\"$3 " . $align_class . 'size-full wp-image-' . $media['attachment_id'] . "\"$4" . $width_assertion . $height_assertion . ' />', $new_link);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Add the caption
|
||
if ( $caption != '' ) {
|
||
$new_link = sprintf($caption, $new_link);
|
||
}
|
||
}
|
||
$link['new_link'] = $new_link;
|
||
}
|
||
|
||
// Reinsert the converted medias links
|
||
$content = preg_replace_callback('#__fg_link_(\d+)__#', array($this, 'restore_links'), $content);
|
||
}
|
||
}
|
||
return $content;
|
||
}
|
||
|
||
/**
|
||
* Remove all the links from the content and replace them with a specific tag
|
||
*
|
||
* @param array $matches Result of the preg_match
|
||
* @return string Replacement
|
||
*/
|
||
private function remove_links($matches) {
|
||
$this->post_link[] = array('old_link' => $matches[0]);
|
||
return '__fg_link_' . $this->post_link_count++ . '__';
|
||
}
|
||
|
||
/**
|
||
* Restore the links in the content and replace them with the new calculated link
|
||
*
|
||
* @param array $matches Result of the preg_match
|
||
* @return string Replacement
|
||
*/
|
||
private function restore_links($matches) {
|
||
$link = $this->post_link[$matches[1]];
|
||
$new_link = array_key_exists('new_link', $link)? $link['new_link'] : $link['old_link'];
|
||
return $new_link;
|
||
}
|
||
|
||
/**
|
||
* Add a link between a media and a post (parent id + thumbnail)
|
||
*
|
||
* @param int $post_id Post ID
|
||
* @param array $post_data Post data
|
||
* @param array $post_media Post medias IDs
|
||
* @param boolean $set_featured_image Set the featured image?
|
||
*/
|
||
public function add_post_media($post_id, $post_data, $post_media, $set_featured_image=true) {
|
||
$thumbnail_is_set = false;
|
||
if ( is_array($post_media) ) {
|
||
foreach ( $post_media as $attachment_id ) {
|
||
$attachment = get_post($attachment_id);
|
||
if ( !empty($attachment) ) {
|
||
$attachment->post_parent = $post_id; // Attach the post to the media
|
||
$attachment->post_date = $post_data['post_date'] ;// Define the media's date
|
||
wp_update_post($attachment);
|
||
|
||
// Set the featured image. If not defined, it is the first image of the content.
|
||
if ( $set_featured_image && !$thumbnail_is_set ) {
|
||
set_post_thumbnail($post_id, $attachment_id);
|
||
$thumbnail_is_set = true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Modify the video links
|
||
*
|
||
* @param string $content Content
|
||
* @return string Content
|
||
*/
|
||
private function process_video_links($content) {
|
||
if ( strpos($content, '{"video"') !== false ) {
|
||
$content = preg_replace('/(<p>)?{"video":"(.*?)".*?}(<\/p>)?/', "$2", $content);
|
||
}
|
||
return $content;
|
||
}
|
||
|
||
/**
|
||
* Modify the internal links of all posts
|
||
*
|
||
* @return array:
|
||
* int links_count: Links count
|
||
*/
|
||
private function modify_links() {
|
||
$links_count = 0;
|
||
$step = 1000; // to limit the results
|
||
$offset = 0;
|
||
$matches = array();
|
||
|
||
// Set the list of previously imported categories
|
||
$this->imported_categories = $this->get_term_metas_by_metakey('_fgs2wp_old_category_id');
|
||
|
||
// Hook for doing other actions before modifying the links
|
||
do_action('fgs2wp_pre_modify_links');
|
||
|
||
do {
|
||
$args = array(
|
||
'numberposts' => $step,
|
||
'offset' => $offset,
|
||
'orderby' => 'ID',
|
||
'order' => 'ASC',
|
||
'post_type' => 'any',
|
||
'post_status' => 'any',
|
||
);
|
||
$posts = get_posts($args);
|
||
foreach ( $posts as $post ) {
|
||
$post = apply_filters('fgs2wp_post_get_post', $post); // Used to translate the links
|
||
$content = $post->post_content;
|
||
if ( preg_match_all('#<a(.*?)href="(.*?)"(.*?)>#', $content, $matches, PREG_SET_ORDER) > 0 ) {
|
||
if ( is_array($matches) ) {
|
||
foreach ( $matches as $match ) {
|
||
$link = $match[2];
|
||
list($link_without_anchor, $anchor_link) = $this->split_anchor_link($link); // Split the anchor link
|
||
// Is it an internal link ?
|
||
if ( !empty($link_without_anchor) && $this->is_internal_link($link_without_anchor) ) {
|
||
$new_link = '';
|
||
if ( preg_match('/^rub(\d+)$/', $link_without_anchor, $matches) ) { // Is it a link to a category?
|
||
$new_link = $this->get_category_link($matches[1], $post);
|
||
} else {
|
||
list($article_id, $object_type) = $this->find_article_id_in_link($link_without_anchor); // Is it a link to an article or to a news?
|
||
if ( $article_id != 0 ) {
|
||
$new_link = $this->get_article_link($article_id, $object_type, $post);
|
||
}
|
||
}
|
||
if ( !empty($new_link) ) {
|
||
if ( !empty($anchor_link) ) {
|
||
$new_link .= '#' . $anchor_link;
|
||
}
|
||
$content = str_replace("href=\"$link\"", "href=\"$new_link\"", $content);
|
||
// Update the post
|
||
wp_update_post(array(
|
||
'ID' => $post->ID,
|
||
'post_content' => $content,
|
||
));
|
||
$links_count++;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
$offset += $step;
|
||
} while ( ($posts != null) && (count($posts) > 0) );
|
||
|
||
// Hook for doing other actions after modifying the links
|
||
do_action('fgs2wp_post_modify_links');
|
||
|
||
return array('links_count' => $links_count);
|
||
}
|
||
|
||
/**
|
||
* Test if the link is an internal link or not
|
||
*
|
||
* @since 2.36.3
|
||
*
|
||
* @param string $link
|
||
* @return bool
|
||
*/
|
||
private function is_internal_link($link) {
|
||
$result = (preg_match("#^".$this->plugin_options['url']."#", $link) > 0) ||
|
||
(preg_match("#^(http|//)#", $link) == 0);
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Find an article ID in a link
|
||
*
|
||
* @param string $link Link
|
||
* @return array [Article ID, Object type]
|
||
*/
|
||
private function find_article_id_in_link($link) {
|
||
$article_id = 0;
|
||
$object_type = 'article';
|
||
$matches = array();
|
||
if ( is_numeric($link) ) {
|
||
$article_id = $link;
|
||
} elseif ( preg_match('/(article|breve)(\d+)/', $link, $matches)) { // article12.html or spip.php?article12 or breve12.html or spip.php?breve12
|
||
$object_type = $matches[1];
|
||
$article_id = $matches[2];
|
||
} elseif ( preg_match('/id_(article|breve)=(\d+)/', $link, $matches)) { // spip.php?page=article&id_article=12 or spip.php?page=breve&id_breve=12
|
||
$object_type = $matches[1];
|
||
$article_id = $matches[2];
|
||
}
|
||
return array($article_id, $object_type);
|
||
}
|
||
|
||
/**
|
||
* Get the WordPress article link matching the SPIP article ID
|
||
*
|
||
* @since 2.18.0
|
||
*
|
||
* @param int $article_id SPIP article ID
|
||
* @param string $object_type article | breve
|
||
* @param array $post Post
|
||
* @return string New link
|
||
*/
|
||
private function get_article_link($article_id, $object_type, $post) {
|
||
$new_link = '';
|
||
if ( $object_type == 'breve' ) {
|
||
// News
|
||
$wp_post_id = $this->get_wp_post_id_from_spip_news_id($article_id);
|
||
} else {
|
||
// Article
|
||
$wp_post_id = $this->get_wp_post_id_from_spip_article_id($article_id);
|
||
}
|
||
if ( !empty($wp_post_id) ) {
|
||
$wp_post_id = apply_filters('fgs2wp_post_get_post_by_spip_id', $wp_post_id, $post); // Used to get the ID of the translated post
|
||
$new_link = get_permalink($wp_post_id);
|
||
}
|
||
return $new_link;
|
||
}
|
||
|
||
/**
|
||
* Get the WordPress category link matching the SPIP category ID
|
||
*
|
||
* @since 2.18.0
|
||
*
|
||
* @param int $category_id SPIP Category ID
|
||
* @return string New link
|
||
*/
|
||
private function get_category_link($category_id) {
|
||
$new_link = '';
|
||
$wp_category_id = $this->get_wp_category_ids($category_id, $this->imported_categories);
|
||
if ( count($wp_category_id) > 0 ) {
|
||
$new_link = get_category_link($wp_category_id[0]);
|
||
}
|
||
return $new_link;
|
||
}
|
||
|
||
/**
|
||
* Split a link by its anchor link
|
||
*
|
||
* @param string $link Original link
|
||
* @return array(string link, string anchor_link) [link without anchor, anchor_link]
|
||
*/
|
||
private function split_anchor_link($link) {
|
||
$pos = strpos($link, '#');
|
||
if ( $pos !== false ) {
|
||
// anchor link found
|
||
$link_without_anchor = substr($link, 0, $pos);
|
||
$anchor_link = substr($link, $pos + 1);
|
||
return array($link_without_anchor, $anchor_link);
|
||
} else {
|
||
// anchor link not found
|
||
return array($link, '');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Copy a remote file
|
||
* in replacement of the copy function
|
||
*
|
||
* @param string $url URL of the source file
|
||
* @param string $path destination file
|
||
* @return boolean
|
||
*/
|
||
public function remote_copy($url, $path) {
|
||
$result = false;
|
||
|
||
if ( !$this->plugin_options['force_media_import'] && file_exists($path) && (filesize($path) > 0) ) {
|
||
// Don't download the file if already downloaded
|
||
return true;
|
||
}
|
||
|
||
$response = wp_remote_get($url, array(
|
||
'timeout' => $this->plugin_options['timeout'],
|
||
'sslverify' => false,
|
||
'user-agent' => 'Mozilla/5.0 AppleWebKit (KHTML, like Gecko) Chrome/ Safari/', // the default "WordPress..." user agent is rejected with some NGINX config
|
||
)); // Uses WordPress HTTP API
|
||
|
||
if ( is_wp_error($response) ) {
|
||
trigger_error($response->get_error_message(), E_USER_WARNING);
|
||
} elseif ( $response['response']['code'] != 200 ) {
|
||
trigger_error($response['response']['message'], E_USER_WARNING);
|
||
} else {
|
||
$content_type = wp_remote_retrieve_header($response, 'content-type');
|
||
if ( preg_match('/^text/', $content_type) ) {
|
||
// Not a media
|
||
trigger_error('Not a media', E_USER_WARNING);
|
||
} else {
|
||
file_put_contents($path, wp_remote_retrieve_body($response));
|
||
$result = true;
|
||
}
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Recount the items for a taxonomy
|
||
*
|
||
* @return boolean
|
||
*/
|
||
private function terms_tax_count($taxonomy) {
|
||
$terms = get_terms(array($taxonomy));
|
||
// Get the term taxonomies
|
||
$terms_taxonomies = array();
|
||
foreach ( $terms as $term ) {
|
||
$terms_taxonomies[] = $term->term_taxonomy_id;
|
||
}
|
||
if ( !empty($terms_taxonomies) ) {
|
||
return wp_update_term_count_now($terms_taxonomies, $taxonomy);
|
||
} else {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Recount the items for each category and tag
|
||
*
|
||
* @return boolean
|
||
*/
|
||
private function terms_count() {
|
||
$result = $this->terms_tax_count('category');
|
||
$result |= $this->terms_tax_count('post_tag');
|
||
}
|
||
|
||
/**
|
||
* Returns the imported posts mapped with their Spip ID
|
||
*
|
||
* @return array of post IDs [spip_article_id => wordpress_post_id]
|
||
*/
|
||
public function get_imported_spip_articles() {
|
||
global $wpdb;
|
||
$posts = array();
|
||
|
||
$sql = "SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_fgs2wp_old_article_id'";
|
||
$results = $wpdb->get_results($sql);
|
||
foreach ( $results as $result ) {
|
||
$posts[$result->meta_value] = $result->post_id;
|
||
}
|
||
ksort($posts);
|
||
return $posts;
|
||
}
|
||
|
||
/**
|
||
* Returns the imported posts mapped with their Spip ID
|
||
*
|
||
* @return array of post IDs [spip_news_id => wordpress_post_id]
|
||
*/
|
||
public function get_imported_spip_news() {
|
||
global $wpdb;
|
||
$posts = array();
|
||
|
||
$sql = "SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_fgs2wp_old_news_id'";
|
||
$results = $wpdb->get_results($sql);
|
||
foreach ( $results as $result ) {
|
||
$posts[$result->meta_value] = $result->post_id;
|
||
}
|
||
ksort($posts);
|
||
return $posts;
|
||
}
|
||
|
||
/**
|
||
* Returns the imported users mapped with their Spip ID
|
||
*
|
||
* @return array of user IDs [spip_user_id => wordpress_user_id]
|
||
*/
|
||
public function get_imported_spip_users() {
|
||
global $wpdb;
|
||
$users = array();
|
||
|
||
$sql = "SELECT user_id, meta_value FROM {$wpdb->usermeta} WHERE meta_key = '_fgs2wp_old_user_id'";
|
||
$results = $wpdb->get_results($sql);
|
||
foreach ( $results as $result ) {
|
||
$users[$result->meta_value] = $result->user_id;
|
||
}
|
||
ksort($users);
|
||
return $users;
|
||
}
|
||
|
||
/**
|
||
* Test if a column exists
|
||
*
|
||
* @param string $table Table name
|
||
* @param string $column Column name
|
||
* @return bool
|
||
*/
|
||
public function column_exists($table, $column) {
|
||
global $spip_db;
|
||
|
||
$cache_key = 'fgs2wp_column_exists:' . $table . '.' . $column;
|
||
$found = false;
|
||
$column_exists = wp_cache_get($cache_key, '', false, $found);
|
||
if ( $found === false ) {
|
||
$column_exists = false;
|
||
try {
|
||
$prefix = $this->plugin_options['prefix'];
|
||
|
||
switch ( $this->plugin_options['driver'] ) {
|
||
case 'mysql':
|
||
$sql = "SHOW COLUMNS FROM ${prefix}${table} LIKE '$column'";
|
||
break;
|
||
case 'sqlite':
|
||
$sql = "PRAGMA table_info(${prefix}${table})";
|
||
break;
|
||
}
|
||
$query = $spip_db->query($sql, PDO::FETCH_ASSOC);
|
||
if ( $query !== false ) {
|
||
if ( $this->plugin_options['driver'] == 'sqlite' ) {
|
||
// SQLite
|
||
$result = $query->fetchAll();
|
||
foreach ( $result as $row ) {
|
||
if ( isset($row['name']) && ($row['name'] == $column) ) {
|
||
$column_exists = true;
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
// MySQL
|
||
$result = $query->fetch();
|
||
$column_exists = !empty($result);
|
||
}
|
||
}
|
||
} catch ( PDOException $e ) {}
|
||
|
||
// Store the result in cache for the current request
|
||
wp_cache_set($cache_key, $column_exists);
|
||
}
|
||
return $column_exists;
|
||
}
|
||
|
||
/**
|
||
* Test if a table exists
|
||
*
|
||
* @param string $table Table name
|
||
* @return bool
|
||
*/
|
||
public function table_exists($table) {
|
||
global $spip_db;
|
||
|
||
$cache_key = 'fgs2wp_table_exists:' . $table;
|
||
$found = false;
|
||
$table_exists = wp_cache_get($cache_key, '', false, $found);
|
||
if ( $found === false ) {
|
||
$table_exists = false;
|
||
try {
|
||
$prefix = $this->plugin_options['prefix'];
|
||
|
||
switch ( $this->plugin_options['driver'] ) {
|
||
case 'mysql':
|
||
$sql = "SHOW TABLES LIKE '${prefix}${table}'";
|
||
break;
|
||
case 'sqlite':
|
||
$sql = "SELECT name FROM sqlite_master WHERE type='table' AND name='${prefix}${table}';";
|
||
break;
|
||
}
|
||
$query = $spip_db->query($sql, PDO::FETCH_ASSOC);
|
||
if ( $query !== false ) {
|
||
$result = $query->fetch();
|
||
$table_exists = !empty($result);
|
||
}
|
||
} catch ( PDOException $e ) {}
|
||
|
||
// Store the result in cache for the current request
|
||
wp_cache_set($cache_key, $table_exists);
|
||
}
|
||
return $table_exists;
|
||
}
|
||
|
||
/**
|
||
* Get all the term metas corresponding to a meta key
|
||
*
|
||
* @param string $meta_key Meta key
|
||
* @return array List of term metas: term_id => meta_value
|
||
*/
|
||
public function get_term_metas_by_metakey($meta_key) {
|
||
global $wpdb;
|
||
$metas = array();
|
||
|
||
$sql = "SELECT term_id, meta_value FROM {$wpdb->termmeta} WHERE meta_key = '$meta_key'";
|
||
$results = $wpdb->get_results($sql);
|
||
foreach ( $results as $result ) {
|
||
$metas[$result->meta_value] = $result->term_id;
|
||
}
|
||
ksort($metas);
|
||
return $metas;
|
||
}
|
||
|
||
/**
|
||
* Returns the imported post ID corresponding to a SPIP article ID
|
||
*
|
||
* @param int $spip_id SPIP article ID
|
||
* @return int WordPress post ID
|
||
*/
|
||
public function get_wp_post_id_from_spip_article_id($spip_id) {
|
||
$post_id = $this->get_wp_post_id_from_meta('_fgs2wp_old_article_id', $spip_id);
|
||
return $post_id;
|
||
}
|
||
|
||
/**
|
||
* Returns the imported post ID corresponding to a SPIP news ID
|
||
*
|
||
* @param int $spip_id SPIP news ID
|
||
* @return int WordPress post ID
|
||
*/
|
||
public function get_wp_post_id_from_spip_news_id($spip_id) {
|
||
$post_id = $this->get_wp_post_id_from_meta('_fgs2wp_old_news_id', $spip_id);
|
||
return $post_id;
|
||
}
|
||
|
||
/**
|
||
* Returns the imported post ID corresponding to a meta key and value
|
||
*
|
||
* @param string $meta_key Meta key
|
||
* @param string $meta_value Meta value
|
||
* @return int WordPress post ID
|
||
*/
|
||
public function get_wp_post_id_from_meta($meta_key, $meta_value) {
|
||
global $wpdb;
|
||
|
||
$sql = "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '$meta_key' AND meta_value = '$meta_value' LIMIT 1";
|
||
$post_id = $wpdb->get_var($sql);
|
||
return $post_id;
|
||
}
|
||
|
||
/**
|
||
* Sanitize a date
|
||
*
|
||
* @param date $date Date
|
||
* @return date
|
||
*/
|
||
public function sanitize_date($date) {
|
||
$date = preg_replace('#-00#', '-01', $date); // For the dates having day = 00
|
||
return $date;
|
||
}
|
||
}
|
||
}
|