web-dev-qa-db-fra.com

Importation de pièces jointes WordPress dans les répertoires personnalisés dans wp-content/uploads /

J'espère que quelqu'un pourra faire la lumière sur ce problème que j'essaie de résoudre, même si je modifie simplement mon processus de réflexion quant à la manière de résoudre ce problème.

J'importe une application Web CMS personnalisée basée sur CakePHP dans WordPress en parcourant la base de données, en effectuant de nombreuses requêtes SQL, en construisant des matrices et en générant le fichier XML nécessaire pour l'importation à l'aide de l'outil d'importation WordPress.

Actuellement, j'ai réussi à importer des catégories, des balises et des messages/pages sans problème, pas de problème, mais ce sont les images qui semblent poser problème. Le format actuel des images dans le CMS basé sur CakePHP est images/année/mois/jour/post_id/nom_image.ext

Autant que je sache, WordPress par défaut ne peut stocker que des supports dans wp-content/uploads ou wp-content/uploads/year/month

Ce que j'ai fait est de copier tous les dossiers d'images du répertoire d'applications CakePPH dans mon répertoire WordPress wp-content/uploads, ainsi un exemple d'image aura ce chemin: http://localhost/wordpress_site/wp-content/uploads/2013/01/01/12345/image.jpg

Dans mon fichier XML WordPress que je suis en train de générer, j'ai défini les propriétés attachment_url et GIUD comme ci-dessus, en faisant référence à la nouvelle image que je place dans mon répertoire de téléchargement. J'ai même défini le chemin du fichier dans les métadonnées serialzied de l'élément de pièce jointe dans le fichier XML.

Si j'exécute le processus d'importation sans cocher l'option "Télécharger et importer les pièces jointes" dans WordPress, j'obtiens des erreurs indiquant que le support ne peut pas être importé ...

Si je vérifie l'option "Télécharger et importer les pièces jointes", les images sont situées dans le chemin personnalisé que j'ai spécifié ci-dessus, mais elles sont redimensionnées en fonction des dimensions de la vignette, etc., et l'image est toujours placée dans un année/mois. /image.jpg chemin. Ainsi, tout ce que WordPress avait fait était de lire le fichier à cet emplacement (personnalisé), mais de définir le chemin final vers un fichier WordPress standard, en déplaçant l'image et ses vignettes générées à l'emplacement souhaité.

Est-ce que quelqu'un connaît un moyen d'avoir simplement le média dans un chemin personnalisé dans le dossier de téléchargement ET de forcer WordPress à accepter et à utiliser ce chemin lors d'une importation?

Je comprends que, via des actions et des points d'ancrage, je peux modifier la structure du chemin de téléchargement, mais uniquement dans WordPress et uniquement lors du téléchargement de contenu multimédia via le gestionnaire de publication/page/multimédia, et non lors d'une importation. La dernière chose que je veux faire est de pirater le script d'importation.

Toute aide, conseils ou conseils seront plus qu'appréciés.

3
SimonDowdles

Oui, vous pouvez ajouter par programme la pièce jointe.

$upl = wp_upload_dir();
$target = $upl['basedir'] . '/YOUR_CUSTOM_FOLDERS/YOUR_FILE';
$filetype = wp_check_filetype($target);

$attachment = array(
    'post_mime_type' => $filetype['type'],
    'post_title' =>  $YOUR_FILE_TITLE,
    'post_content' => '',
    'post_status' => 'inherit'
);

wp_insert_attachment( $attachment, $target, $POST_ID_TO_ATTACH_TO );

Cela indiquera à Wordpress qu'il existe une pièce jointe dans $ target et que vous pouvez éventuellement la joindre à une publication avec le dernier paramètre de l'appel à wp_insert_attachment.

2
tobbr

Pour toutes les personnes confrontées au même dilemme que moi, il existe en fait de nombreuses ressources en ligne qui dictent comment résoudre ce problème. J'ai trouvé que le meilleur moyen de trouver la solution consistait en fait à rechercher quelque chose comme Importer des pièces jointes WordPress par programme, ce qui a entraîné un nombre considérable de solutions.

Merci à @tobbr pour ses précieux conseils qui m'ont orienté dans la bonne direction. Ma dernière solution consistait à créer un plugin, puis à parcourir la base de données des anciens sites (CakePHP) pour obtenir les anciennes images et leurs chemins, puis à utiliser celles-ci pour importer les pièces jointes dans WordPress.

Le point important à prendre en compte ici est que j’ai cloné le répertoire des images de sites anciens dans mon répertoire de téléchargement WordPress. Les anciens chemins d’image étaient les suivants:

CAKE_ROOT/app/WebRoot/images/2012/10/2/12345/image_name.jpg

Où 12345 = l'ID de l'entrée d'image dans la base de données (qui deviendrait l'ID de la pièce jointe lors de l'importation dans WordPress. J'ai donc déplacé le dossier ENTIRE images ci-dessus dans mon répertoire de téléchargement WordPress, de sorte que ma structure de dossiers d'images WordPress se présente comme suit:

WP_ROOT/wp-content/uploads/2012/10/2/12345/image_name.jpg

Il est important de noter qu'avant de commencer même à importer des pièces jointes par programme, vos images DOIVENT habiter quelque part (n'importe où) dans votre répertoire de téléchargements WordPress. Assurez-vous également que vous disposez des autorisations nécessaires. Pour faciliter l'importation, j'ai exécuté une commande chmod -R 777 sur mon dossier de téléchargement avant de commencer.

J'ai ensuite écrit le plugin, qui était loin d'être aussi compliqué que je l'imaginais, donc le voici pour tous ceux qui ont besoin de faire une tâche similaire:

<?php
/*
Plugin Name: Image Importer
Plugin URI: 
Description:
Author: xxxxx
Version: 1.0
Author URI: 
*/

error_reporting(E_ALL);

add_action( 'admin_menu', 'sd_plugin_menu' );

function sd_plugin_menu() {
    add_options_page( 'My Plugin Options', 'My Image Importer', 'manage_options', 'sd-image-importer', 'sd_image_importer' );
}

function sd_image_importer() {
    if ( !current_user_can( 'manage_options' ) )  {
        wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
    }

    echo '<div style="overflow:hidden;padding:20px;margin:20px 0 0 0;border:1px solid #ccc;font-size:14px;color:#666;">';

    if($_REQUEST['getfiles'] == 1) {

    // Make a MySQL Connection
    $con = mysqli_connect("xxx", "xxx", "xxx") or die(mysql_error());
    mysqli_select_db($con,"xxxx") or die(mysqli_error($con));

    // Retrieve all the data from the images table
    $result = mysqli_query($con,"SELECT * FROM cake_attached_images WHERE created > '2012-10-01' AND created < '2012-10-02'") or die(mysql_error($con));  

    // pre buffer empty array so as not to create one on each iteration of DB
    $files = array();

        while ($row = mysqli_fetch_array($result,MYSQL_ASSOC)) {
            $year = date('Y', strtotime($row['created']));
            $month = date('m', strtotime($row['created']));
            $day = ltrim(date('d', strtotime($row['created'])),0);
            $id = $row['id'];
            $foreign_key = $row['foreign_key'];
            $caption = $row['caption'];
            $filename = $row['filename'];

            $files[$id] = array(
                'id' => $id,
                'foreign_key' => $foreign_key,
                'path' => "$year/$month/$day/$id/$filename",
            );
        };
    }; // End if getfiles param present in URL

    if($_REQUEST['insert'] == 1){

        global $wpdb; 

        foreach($files as $file){

          $wp_filetype = wp_check_filetype(basename($wp_upload_dir['baseurl'].'/'.$file['path']), null );
          $wp_upload_dir = wp_upload_dir();

          $attachment = array(
             'guid' => $wp_upload_dir['baseurl'].'/'. $file['path'], 
             'post_mime_type' => $wp_filetype['type'],
             'post_title' => preg_replace('/\.[^.]+$/', '', basename($wp_upload_dir['baseurl'].'/'.$file['path'])),
             'post_content' => '',
             'post_status' => 'inherit',
             'post_parent' => $file['foreign_key']
          );

          // Insert attachment, newly added attachmnet ID is returned...
          $attach_id = wp_insert_attachment( $attachment, $wp_upload_dir['path'].'/'. $file['path'], $file['foreign_key'] );
          // The file MUST be included to make use of the wp_generate_attachment_metadata function below
          require_once(ABSPATH . 'wp-admin/includes/image.php');
          // Generate metadata from newly added attachment above
          $attach_data = wp_generate_attachment_metadata( $attach_id, $wp_upload_dir['path'].'/'. $file['path'] );
          // Updates atttachment metadata for newly added attachmnet based on the generated metadata above
          if(wp_update_attachment_metadata( $attach_id, $attach_data )){
            // Optional, can be sued to set the added attachmnet as the featured image on the post
            add_post_meta($file['foreign_key'], '_thumbnail_id', $attach_id, true);
            // Simple outout to indicate if attachmnet was added or not, for debugging
            echo '<span style="color:green;">Attachment successfully added for post with ID <strong>'.$file['foreign_key'].'</strong>, path of new attachment is at <strong>'.$wp_upload_dir['baseurl'].'/'.$file['path'].'</strong></span><br/>';
          }else{
            echo '<span style="color:red;">Failed to generate new attachment for post with ID <strong>'.$file['foreign_key'].'</strong></span><br/>';
          }

        }
    } // end if insert param present in URL request

    $files = null;

    echo '</div>';
}?>

ET ICI IS UNE FONCTION BONUS:

Je suis tombé sur APRÈS avoir écrit le plugin. Cependant, si vous n’en avez que quelques-unes (j’ai eu plus de 100 000 images à importer!), Il existe une fonction TRÈS pratique dans WordPress appelée media_sideload_image qui récupère une image à partir d’une URL distante et la joint à un message. de votre choix, ça vaut vraiment le coup de regarder. Obtenez plus d'informations au codex: http://codex.wordpress.org/Function_Reference/media_sideload_image


Voici quelques liens vers des ressources WordPress Codex qui m'ont aidé:

  1. http://codex.wordpress.org/Function_Reference/wp_insert_attachment - Insertion de pièces jointes par programme
  2. http://codex.wordpress.org/Function_Reference/wp_update_attachment_metadata - Mise à jour des métadonnées pour la pièce jointe nouvellement ajoutée add_post_meta - Si vous souhaitez définir la nouvelle image ajoutée en tant qu'image sélectionnée

Autres sites externes qui m'ont aidé:

  1. http://www.zdnet.com/blog/diy-it/programmatically-importing-thousands-of-featured-image-post-thumbnails-into-wordpress/118 - ZDNet
  2. http://nlb-creations.com/2012/09/26/how-to-programmatically-import-media-files-to-wordpress/ - NB Créations
  3. Programmez des images par URL et enregistrez-les dans le dossier de téléchargement - WordPress Answers
  4. Création par programmation de pièces jointes à partir d'URL locales et définition de l'image sélectionnée - Réponses WordPress

J'espère que cela aide quelqu'un comme il m'a fait. Simon

1
SimonDowdles