Woocommerce Product Creation Automation - php

I'm trying to develop a program that creates woocommerce products based on the media that were uploaded in the wordpress library.
All products have the same settings, the only things that change is the photo and the download.
With some research I managed to develop the following code that is running in functions.php:
add_action( 'init', 'product_automation');
function product_automation() {
$loopProdutos = new WP_Query([
'post_type' => 'product',
'posts_per_page' => -1
]);
$arrayProduct = (array) $loopProdutos->posts;
// Picking up all the products from the store
$idImgProduct = [];
foreach($arrayProduct as $product) {
$produto = wc_get_product($product->ID);
$idImgProduct[] = $produto->image_id;
}
// Taking all photo IDs from existing products
$loopImagens = new WP_Query([
'post_type' => 'attachment',
'post_mime_type' => 'image',
'orderby' => 'post_date',
'order' => 'desc',
'posts_per_page' => -1,
'post_status' => 'inherit'
]);
$arrayImg = (array) $loopImagens->posts;
// Taking all uploaded photos
$idImg = [];
foreach($arrayImg as $image) {
$idImg[] = $image->ID;
}
// Getting all uploaded photo IDs
$newIds = array_diff($idImg, $idImgProduct);
// Seeing which IDs do not yet exist
$newProductsArray = [];
// Array with new products
foreach($newIds as $idImagem) {
$objProduct = new WC_Product_Simple();
$objProduct->set_name("Foto");
$objProduct->set_status("publish");
$objProduct->set_catalog_visibility('visible');
$objProduct->set_price(15.00);
$objProduct->set_regular_price(15.00);
$objProduct->set_sold_individually(true);
$objProduct->set_image_id($idImagem);
$objProduct->set_downloadable(true);
$objProduct->set_virtual(true);
// Create a simple product
$src_img = wp_get_attachment_image_src( $idImagem, 'full');
$img_meta = wp_get_attachment_metadata( $idImagem, false );
$file_title = $img_meta['image_meta']['title'];
$file_url = reset($src_img);
$file_md5 = md5($file_url);
$download = new WC_Product_Download();
$download->set_name($file_title);
$download->set_id($file_md5);
$download->set_file($file_url);
$downloads[$md5_num] = $download;
$objProduct->set_downloads($downloads);
// Code to automatically add download link to product
$newProductsArray[] = $objProduct;
}
for ($i = 0; $i < count($newProductsArray); $i++) {
$newProductsArray[$i]->save();
}
//Loop to save each new product
}
The code works great. The problem is that it creates more products than anticipated.
For example, if I have 10 photos in my library, it creates 16 or 20 products (each photo generates more than one product).
I cannot find the error. Need help.😅

Here you go, I've tested it and it seems to work, apart from "attaching the image to the post" (I mean, it shows as product featured image, but under Media it says it's not attached to anything and you can't "detach").
I found another hook, which should work better than wp_handle_upload, and also fixed a couple of bugs (image title and downloads array):
add_action( 'add_attachment', 'bbloomer_product_automation', 9999 );
function bbloomer_product_automation( $image_id ) {
$product = new WC_Product_Simple();
$product->set_name( 'Foto' );
$product->set_status( 'publish' );
$product->set_catalog_visibility( 'visible' );
$product->set_price( 15 );
$product->set_regular_price( 15 );
$product->set_sold_individually( true );
$product->set_image_id( $image_id );
$product->set_downloadable( true );
$product->set_virtual( true );
$src_img = wp_get_attachment_image_src( $image_id, 'full' );
$file_title = get_the_title( $image_id ); // CORRECT GET IMAGE TITLE
$file_url = reset( $src_img );
$file_md5 = md5( $file_url );
$download = new WC_Product_Download();
$download->set_name( $file_title );
$download->set_id( $file_md5 );
$download->set_file( $file_url );
$downloads[$file_md5] = $download; // BUG FIXED
$product->set_downloads( $downloads );
$product->save();
}

Related

Loop All Attachment URL In Posts Wordpress

I Want to loop all attachment url and save new html.
Sorry, I only script kiddies. I only understand some code.
This my script php
function get_all_image_clickable($content) {
global $post;
$args_img = array(
'order' => 'ASC',
'post_type' => 'attachment',
'post_parent' => $post->ID,
'post_mime_type' => 'image',
'post_status' => null,
"what_to_show" =>"posts",
"showposts" =>-1,
"post_mime_type" =>"image"
);
$attachments = get_posts($args_img);
$i = 0;
$dom = new DOMDocument('UTF-8');
#$dom->loadHTML( utf8_decode($content) ); // Decode to simple ISO to avoid accent errors
$dom->preserveWhiteSpace = false;
$images = $dom->getElementsByTagName('img');
if( count($images) > 0 ) {
foreach ($images as $image) {
$width = $image->getAttribute('width'); // get the widths of each image
if( $width >= 860) { // if image is less than 860, add their old classes back in plus our new class
$clone_img = $image->cloneNode(); //clone node images
// Create DIV container
foreach ($attachments as $attachment) {
$parent = get_post($post->post_parent);
if($parent->post_status == "publish"){
$image_wrap = $dom->createElement('a');
$image_wrap->setAttribute('class', 'img-gallery' );
$image_wrap->setAttribute('href', get_attachment_link($attachment->ID));
}
$i++;
wp_reset_postdata();
}
$image_wrap->appendChild( $clone_img ); // Add to image to new container
$image->parentNode->replaceChild( $image_wrap, $image ); // Replace img object with all new elements
}
} // end if count
$content = $dom->saveHTML();
}
return $content;
}
add_filter( 'the_content' , 'get_all_image_clickable' , 15 );
i want to get all attachment url on its own image.
Sorry, my english bad.

How can I display the featured icon on frontend?

Hello I applied the code I found here.
But I can't figure out how can I call this image on frontend.
I tried this so far:
$args = array('post_type' => 'katastima');
$the_query = new WP_Query($args);
while ( $the_query->have_posts() ) : $the_query->next_post();
$id= $the_query->post->ID;
$location = get_post_meta($id, 'listingimagediv', true);
echo $location;
endwhile;
but I guess this is not the correct way to get the image link from the custom metabox.
Any suggestions?
Thanks in advance.
You get the photo ID from get_post_meta
So the next step is to get the url of the image, see here
$size = 'full';
$icon = null;
$attr = array( "class" => "img-responsive" );
echo wp_get_attachment_image( $location, $size, $icon, $attr );

How to update or save multiple checkbox on update post meta in wordpress?

I can successfully create a post and also update or insert the data to the custom fields.
But i've no Idea how to update or check the multiselect checkboxes.
Below is the code for creating a post with featured image and inserting custom fields.
Please suggest me to add also the multiple select checboxes.
<?php
error_reporting(E_ALL);
#ini_set('display_errors', 1);
require('wp-load.php');
global $user_ID;
$title = $_REQUEST['title'];
$content = $_REQUEST['content'];
$status = $_REQUEST['status'];
$date = $_REQUEST['date'];
$type = $_REQUEST['type'];
$bedrooms = $_REQUEST['bedrooms'];
$bathrooms = $_REQUEST['bathrooms'];
$floor = $_REQUEST['floor'];
$sqft = $_REQUEST['sqft'];
$afterfee = $_REQUEST['afterfee'];
$sp = $_REQUEST['saleprice'];
echo $title;
echo $content;
echo $status;
echo $type;
echo $bedrooms;
echo $bathrooms;
$new_post = array(
'post_title' => $title,
'post_content' => $content,
'post_status' => $status,
'post_date' => $date,
'post_author' => $user_ID,
'post_type' => $type,
'post_category' => array(0)
);
$id = wp_insert_post($new_post);
update_post_meta($id,'fave_property_bedrooms',$bedrooms);
update_post_meta($id,'fave_property_bathrooms',$bathrooms);
update_post_meta($id,'fave_video_url','www.google.com');
update_post_meta($id,'fave_property_price_postfix',$afterfee);
update_post_meta($id,'fave_property_land_postfix',$sqft);
update_post_meta($id,'fave_property_land',$floor);
update_post_meta($id,'fave_property_price_prefix','Start From');
update_post_meta($id,'fave_property_price_postfix','Per Month');
update_post_meta($id,'fave_property_price',$sp);
$post_id=$id;
// only need these if performing outside of admin environment
require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
// example image
$image = 'https://clevertechie.com/img/main/php-curl-tutorial.png';
// magic sideload image returns an HTML image, not an ID
$media = media_sideload_image($image, $post_id);
// therefore we must find it so we can set it as featured ID
if(!empty($media) && !is_wp_error($media)){
$args = array(
'post_type' => 'attachment',
'posts_per_page' => -1,
'post_status' => 'any',
'post_parent' => $post_id
);
// reference new image to set as featured
$attachments = get_posts($args);
if(isset($attachments) && is_array($attachments)){
foreach($attachments as $attachment){
// grab source of full size images (so no 300x150 nonsense in path)
$image = wp_get_attachment_image_src($attachment->ID, 'full');
// determine if in the $media image we created, the string of the URL exists
if(strpos($media, $image[0]) !== false){
// if so, we found our image. set it as thumbnail
set_post_thumbnail($post_id, $attachment->ID);
// only want one image
break;
}
}
}
}
?>

wordpress, inserting values into custom post type not working

When processing the form i want the values to be inserted into the custom post type products.
Here is what i have done so far
$art_title = $_POST['art_title'];
$i = 0;
foreach($art_title as $value) {
$art_title = $_POST['art_title'][$i];
$art_width = $_POST['art_width'][$i];
$art_height = $_POST['art_height'][$i];
$art_price = $_POST['art_price'][$i];
$art_creation_date = $_POST['art_creation_date'][$i];
$art_upload = $_FILE['art_upload'][$i];
// Add the content of the form to $post as an array
$new_post = array(
'post_title' => $art_title,
'post_status' => 'draft',
'post_type' => 'products'
);
//save the new post
$pid = wp_insert_post($new_post);
$attachment_id = media_handle_upload( 'art_upload', $pid );
if ( is_wp_error( $attachment_id ) ) {
// There was an error uploading the image.
} else {
// The image was uploaded successfully!
}
$i++;
}
I used media_handle_upload along with the post id but this isn't working.
What i want to know is how do i insert these $_POST values into the custom post type products along with the image as product_image?
The custom post type is the woocommerce products.
Any help greatly appreciated. An example would be great.
please replace this line
$art_upload = $_FILE['art_upload'][$i];
to
$art_upload = $_FILES['art_upload'][$i];

Add file from server wordpress plugin checking and limit of 999 files

I am using this wordpress plugin in order to add files from server and I have 2 issues. Files are not being skipped, therefore I needed to alter the code myself in order to add a checking process, but the problem is that the checking process is very slow for each file. Second issue is that the plugin can't add more than 999 files at once and I need to add about 50000 files to the media library.
Code that I altered to check if the file is in the media library and skip it:
class.add-from-server.php
function handle_imports() {
if ( !empty($_POST['files']) && !empty($_POST['cwd']) ) {
$query_images_args = array(
'post_name' => trim ( $post_name ), 'post_type' => 'attachment', 'post_mime_type' =>'image', 'post_status' => 'inherit', 'posts_per_page' => -1,
);
$query_images = new WP_Query( $query_images_args );
$images = array();
foreach ( $query_images->posts as $image) {
$image_trim = wp_get_attachment_url( $image->ID );
$image_trim = explode('/', $image_trim);
$images[] = end($image_trim);
}
// $images is the array with the filenames where I stock the media library files
$files = array_map('stripslashes', $_POST['files']);
$cwd = trailingslashit(stripslashes($_POST['cwd']));
$post_id = isset($_REQUEST['post_id']) ? intval($_REQUEST['post_id']) : 0;
$import_date = isset($_REQUEST['import-date']) ? $_REQUEST['import-date'] : 'file';
$import_to_gallery = isset($_POST['gallery']) && 'on' == $_POST['gallery'];
if ( ! $import_to_gallery && !isset($_REQUEST['cwd']) )
$import_to_gallery = true; // cwd should always be set, if it's not, and neither is gallery, this must be the first page load.
if ( ! $import_to_gallery )
$post_id = 0;
flush();
wp_ob_end_flush_all();
foreach ( (array)$files as $file ) {
if (!in_array($file, $images)) {
// here I ask if the image that I want to add is in the media library or not
$filename = $cwd . $file;
$id = $this->handle_import_file($filename, $post_id, $import_date);
if ( is_wp_error($id) ) {
echo '<div class="updated error"><p>' . sprintf(__('<em>%s</em> was <strong>not</strong> imported due to an error: %s', 'add-from-server'), esc_html($file), $id->get_error_message() ) . '</p></div>';
} else {
//increment the gallery count
if ( $import_to_gallery )
echo "<script type='text/javascript'>jQuery('#attachments-count').text(1 * jQuery('#attachments-count').text() + 1);</script>";
echo '<div class="updated"><p>' . sprintf(__('<em>%s</em> has been added to Media library', 'add-from-server'), esc_html($file)) . '</p></div>';
}
flush();
wp_ob_end_flush_all();
} else {
echo '<div class="updated error">File '.$file.' had been skipped because it is already in the media library.</div>';
}
}
}
}
So please help
1. How can I speed up the checking process, want to mention that this code is the one that slowing down the process (true that I have 10000 images in the media library):
$query_images_args = array(
'post_name' => trim ( $post_name ), 'post_type' => 'attachment', 'post_mime_type' =>'image', 'post_status' => 'inherit', 'posts_per_page' => -1,
);
$query_images = new WP_Query( $query_images_args );
$images = array();
foreach ( $query_images->posts as $image) {
$image_trim = wp_get_attachment_url( $image->ID );
$image_trim = explode('/', $image_trim);
$images[] = end($image_trim);
}
Second issue the one with the 999 files limit, how to overcome this limit? I believe is related to the wordpress code but don't know how to by pass it.
Okay, I'm not going to answer your question directly because I don't understand why you're using a plugin to do this but ... what you're trying to do is easy enough without the use of a plugin.
First, you need to loop a directory, then check if the media exists, and if not, add the media to the media library.
function thisismyurl_add_media_to_library() {
global $wpdb;
$file_count = 0;
/* if the user isn't an admin user, don't do anything */
if ( ! current_user_can( 'manage_options' ) )
return;
/* (you'll want to reset this to your path */
$file_path = ABSPATH . '/import/path/to/files/';
/* get a list of all files in a specific directory */
$files = glob( $file_path . '*.jpg');
if ( ! empty( $files ) ) {
/* now we loop the files */
foreach ( $files as $file ) {
unset( $post_id );
/* it's likely that a server will time out with too many files so we're going to limit it to 999 new files */
if ( $file_count < 999 ) {
$filename = str_replace( $file_path, '', $file );
/* check to see if the image already exists */
$post_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s", $filename ) );
/* the file does not exist */
if ( empty( $post_id ) ) {
/* only count new files when checking for the file count */
$file_count++;
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . basename( $filename ),
'post_mime_type' => wp_check_filetype( basename( $file ), null ),
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_content' => '',
'post_status' => 'inherit'
);
wp_insert_attachment( $attachment, $filename );
/* this is commented out for now, but if you uncomment it, the code will delete each file after it's been inserted */
/*
if ( $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s", $filename ) ) )
unlink( $file );
*/
} /* if */
}
} /* foreach */
} /* if */
}
add_action( 'wp_head', 'thisismyurl_add_media_to_library' );

Categories