I'm trying to import images from a remote server and set it to custom fields. Importing and generating a attachment id is working, but something is messing with the custom fields. I don't know if is a thread issue or something.
Here's my code:
$sql = 'SELECT * FROM produto';
$retval = mysql_query( $sql, $connection) ;
while($row = mysql_fetch_array($retval, MYSQL_ASSOC))
{
$file = $row['imagem'];
$filename = basename($file);
$upload_file = wp_upload_bits($filename, null, file_get_contents($file));
if (!$upload_file['error']) {
$wp_filetype = wp_check_filetype($filename, null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_parent' => $parent_post_id,
'post_title' => preg_replace('/\.[^.]+$/', '', $filename),
'post_content' => '',
'post_status' => 'inherit'
);
$attachment_id = wp_insert_attachment( $attachment, $upload_file['file'], $parent_post_id );
$imgs[$row['modelo']][]['imagem'] = $attachment_id;
if (!is_wp_error($attachment_id)) {
require_once(ABSPATH . "wp-admin" . '/includes/image.php');
$attachment_data = wp_generate_attachment_metadata( $attachment_id, $upload_file['file'] );
wp_update_attachment_metadata( $attachment_id, $attachment_data );
}
}
}
foreach ($imgs as $key => $value) {
$args = array(
'post_type' => 'produto',
'meta_key' => 'identifier1',
'meta_value' => $key);
// The Query
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
update_field('imagens', $value, get_the_ID());
}
}
/* Restore original Post Data */
wp_reset_postdata();
}
If I try to set 20 itens on this custom field, it works perfectly. But when I need to run this loop with 250 results, it breaks.
What am I doing wrong?
Thanks!
I had to migrate one non wp database to a wp ready database, and the database had over 10k images. I also set up the import to do it all at once (I just uploaded not only posts, but images and all the meta data, pages, etc.).
The thing is that importing something at once will most likely time out the server, and you'll get only first n
imported images, the rest won't work because of the timeout or some similar error.
The workaround is to put your script in a function that will be called with AJAX, and will import one image at the time. You just need to tweak it a bit to fetch one image at the time.
I'd first check if the $imgs
array is full - all your images from old database are present with all the data attached.
If it is, you just need to add something like this
<?php
add_action( 'wp_ajax_import_image', 'import_image_callback' );
add_action( 'wp_ajax_nopriv_import_image', 'import_image_callback' ); // this is only if you're importing from the front end. If in the back end this is not necessary
/**
* AJAX callback iumport image function
*
*/
function import_image(){
$img = $_POST['img'];
$args = array(
'post_type' => 'produto',
'meta_key' => 'identifier1',
'meta_value' => $img
);
// The Query
$image_query = new WP_Query( $args );
if ( $image_query->have_posts() ) {
while ( $image_query->have_posts() ) {
$image_query->the_post();
update_field('imagens', $img['image_value'], get_the_ID());//You'll need to see what you need from the array value here, I just placed dummy image_value as I don't know what the $img array contains
}
}
/* Restore original Post Data */
wp_reset_postdata();
}
Then you'll call this function using AJAX. Now you'll probably have to save your images as JSON object and localize it. That way you'll be able to use that array in your JavaScript to fetch one image at the time with something like this:
jQuery(document).ready(function($) {
"use strict";
var images = localized_object.images_array; //JSON array
for (var i = 0; i < images.length; i++) {
var img = images[i]; //something like this - you'll see if this works 100%, but the gist is the same
upload_image(img); // Call the AJAX callback function
}
function upload_image(image){
$.ajax({
type: "POST",
url: localized_object.ajaxurl, //localize this if you're doing this from the from the front end. If you're using it in back end just use ajaxurl.
data: {
'action': 'import_image',
'img': image,
},
success: function(response) {
console.log('Image imported');
},
error : function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR + ' :: ' + textStatus + ' :: ' + errorThrown);
}
});
}
});
Now since I don't know how your DB dump looks like this is not 100% guaranteed to work, but it gives you a good idea how to do it.
Hope this helps :)