I have written a bulk import script where I import posts with the wp_insert_post() function using taxonomy names. Basically there are 4000 cities, and I want to add them as posts such as:
New York to London
New York to Amsterdam
New York to Berlin
etc...
But I'm getting an internal server error after adding a few thousand posts. I expect the total posts added to be 16,000,000 [4,000 * 4,000]
Here is the code:
<?php
require_once "wp-load.php";
ini_set("memory_limit",-1);
set_time_limit(0);
ignore_user_abort(true);
$term_query = new WP_Term_Query( array( 'taxonomy' => 'cities' ) );
if ( ! empty( $term_query->terms ) ) {
wp_defer_term_counting( true );
define( 'WP_IMPORTING', true );
foreach ( $term_query ->terms as $term ) {
$city1 = $term->name;
foreach ( $term_query ->terms as $inner_city ) {
$city2 = $inner_city->name;
$postTitle = $city1 . ' to ' . $city2;
$postSlug = $city1 . '-to-' . $city2;
$LowerPostSlug = strtolower($postSlug);
$post_args = array(
'post_title' => $postTitle,
'post_status' => 'publish',
'post_name' => $postSlug,
'post_author' => $user_ID,
'post_type' => 'conversion',
);
$found_post_title = get_page_by_title( $postTitle, OBJECT, 'city_post' );
$found_post_id = $found_post_title->ID;
if ( FALSE === get_post_status( $found_post_id ) ):
$returned_post_id = wp_insert_post( $post_args );
update_field( 'city_1', $city1, $returned_post_id ); # SET CUSTOM FIELD FOR city 1
update_field( 'city_2', $city2, $returned_post_id ); # SET CUSTOM FIELD FOR city 2
echo $postTitle . '</br>';
endif;
}
}
wp_defer_term_counting( false );
}
Related
I'm trying to extract an xml feed for about 30k products.
In the lower one, the output reaches the level of 7-8 thousand and does not continue. I need to include all products in the output.
Can I split the process or output files into parts, would something like this require a lot of code?
Or if anyone has any other ideas, I'm open to that, as this seems to be an important issue I need to resolve.
I get data from database with WP_Query() loop starts with foreach and outputs with XMLWriter().
<?php
add_action( 'wp_loaded', 'product_feeds_output_writer');
function product_feeds_output_writer() {
$args = array(
'post_type' => 'product', // Total product 30k.
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => '_stock_status',
'value' => 'instock',
'compare' => '='
)
)
);
$query = new WP_Query();
if (! $posts = $query->query( $args ) ) {
$error = new WP_Error( '003', 'No products found.' );
wp_send_json_error( $error );
}
$bloginfo = array(
'name' => get_bloginfo('name'),
'url' => get_bloginfo('url'),
'description' => get_bloginfo('description')
);
$xml = new XMLWriter();
$xml->openURI( $_SERVER['DOCUMENT_ROOT'] . '/wp-content/uploads/woo-products-feed-generator/XMLWriter.xml' );
$xml->startDocument('1.0','UTF-8');
$xml->setIndent( 4 );
$xml->startElement('rss');
$xml->writeAttribute('version', '2.0');
$xml->writeAttribute('xmlns:g', 'http://base.google.com/ns/1.0');
$xml->startElement('channel');
$xml->writeElement('title', $bloginfo['name']);
$xml->writeElement('link', $bloginfo['url']);
$xml->writeElement('description', $bloginfo['description']);
foreach ( $posts as $post ) {
$product = wc_get_product( $post->ID );
$bir = random_int( 0, 9 );
$on = random_int( 10, 99 );
$yuz = random_int( 100, 999 );
$bin = random_int( 1000, 9999 );
$mil = random_int( 1000000, 9999999 );
$id = $product->get_id();
$title = $product->get_title();
$link = $product->get_permalink();
$description = $product->get_description();
$price = $product->get_regular_price() ?: $product->get_price();
$sale_price = $product->get_sale_price() ?: '';
$availability = $product->get_stock_status() == 'instock' ? 'in_stock' : 'out_of_stock';
$brand = $product->get_attribute( 'pa_marka' );
$image_link = $product->get_meta('_product_image_thumbnail') ?: wp_get_attachment_url( $product->get_image_id() );
$type = implode( '', wp_get_post_terms( $product->id, 'product_cat', array('fields' => 'names') ) );
$xml->startElement('item');
$xml->writeElement( 'g:id', $id );
$xml->writeElement( 'g:title', $title );
$xml->writeElement( 'g:description', $description );
$xml->writeElement( 'g:link', $link );
$xml->writeElement( 'g:price', $price.' '.'TRY' );
if( $sale_price ) {
$xml->writeElement( 'g:sale_price', $sale_price.' '.'TRY' );
}
$xml->writeElement( 'g:availability', $availability );
$xml->writeElement( 'g:brand', $brand );
//$xml->writeElement( 'g:google_product_category', $track );
$xml->writeElement( 'g:product_type', $type );
$xml->writeElement( 'g:identifier_exists', 'yes' );
$xml->writeElement( 'g:gtin', $mil.'-'.'K'.$yuz.'DK' );
$xml->writeElement( 'g:mpn', $bin.'BS'.'-'.'L'.$on.$bir.'ZP' );
$xml->writeElement( 'g:condition', 'Yeni' );
//$xml->writeElement( 'g:shipping', $track );
$xml->writeElement( 'g:image_link', $image_link );
if( $attachment_images = $product->get_gallery_image_ids() ) {
$attachment_images = array_slice( $attachment_images, 0, 10 );
foreach( $attachment_images as $attachment_id ) {
$image_link = wp_get_attachment_url( $attachment_id );
$xml->writeElement( 'g:additional_image_link', $image_link );
}
}
$xml->writeElement( 'g:material', 'Polipropilen' );
if( $value = $product->get_attribute( 'pa_renk' ) ) {
$xml->startElement('g:product_detail');
$xml->writeElement('g:section_name', 'Additional information' );
$xml->writeElement('g:attribute_name', 'Renk' );
$xml->writeElement('g:attribute_value', $value );
$xml->endElement();
}
if( $value = $product->get_attribute( 'pa_beden' ) ) {
$xml->startElement('g:product_detail');
$xml->writeElement('g:section_name', 'Additional information' );
$xml->writeElement('g:attribute_name', 'Beden' );
$xml->writeElement('g:attribute_value', $value );
$xml->endElement();
}
$xml->endElement();
}
$xml->endElement();
$xml->endElement();
$xml->endDocument();
$xml->flush();
unset($xml);
}
Would going through the WooCommerce REST API not be a better approach?
I believe the endpoint for products is :
/wp-json/wc/v3/products
You should be able to page jump through the page= url parameter:
/wp-json/wc/v3/products?page=1&per_page=5000
Parameter
Description
page
(integer) Current page of the collection. Default is 1.
per_page
(integer) Maximum number of items to be returned in result set. Default is 10.
#See https://woocommerce.github.io/woocommerce-rest-api-docs/#list-all-products
I have created a Wordpress site where users register on the front-end and add information about themselves. On registration I am forcing the user_nicename to be name-surname. I am then automatically creating 2 custom post types that act as profile pages for the new users. I am using the user_nicename as the title of both.
The problem is obviously if two people register with the same name.
So I would like to check the database before the user_nicename is updated to check if it already exists. If it does I would like to add an integer (in sequence) to the end of the user_nicename.
For instance:
John-Smith
John-Smith-2
John-Smith-3
Etc.
The code I have tried is as follows, but I'm not having any luck. The custom post types generate fine, but the user_nicename is not being appended with an integer.
Any help would be much appreciated!
add_action( 'user_registration_after_register_user_action', 'ur_insert_username', 1, 3 );
function ur_insert_username( $valid_form_data, $form_id, $user_id ) {
global $wpdb;
$firstname = isset( $valid_form_data['first_name'] ) ? $valid_form_data['first_name']->value : '';
$lastname = isset( $valid_form_data['last_name'] ) ? $valid_form_data['last_name']->value : '';
{
$custom_nicename = sanitize_title_with_dashes( $firstname . '-' . $lastname);
{
$i = 1;
do {
$user = get_user_by('login', $custom_nicename);
if( ! empty( $user ) ) {
$i++;
$custom_nicename = $custom_nicename ."-" . $i;
}
}
while ( ! empty( $user ) );
}
$wpdb->update(
$wpdb->users,
['user_nicename' => $custom_nicename],
['ID' => $user_id]
);
}
{
$user_post_athlete = array(
'post_title' => $custom_nicename,
'post_status' => 'publish', // <- here is to publish
'post_type' => 'athlete', // <- change to your cpt
'post_author' => $user_id
);
$user_post_rivalry = array(
'post_title' => $custom_nicename,
'post_status' => 'publish', // <- here is to publish
'post_type' => 'rivalry', // <- change to your cpt
'post_author' => $user_id
);
// Insert the post into the database
$post_id = wp_insert_post( $user_post_athlete );
$post_id = wp_insert_post( $user_post_rivalry );
}
}
I will suggest you to manage post type for user profile using post_author.
I guess you are adding post by code using wp_insert_post , so add "post_author" field to store user id in it. Wordpress will automatically manage slug of two different posts with same title. And you can associate posts and user using "post_author" field.
https://developer.wordpress.org/reference/functions/wp_insert_post/
Editing my answer
get_user_by('login' will not work reason being login is 'username' and you need to search 'nickname'. You need to get user details by below code
$user_data=get_users(array(
'meta_key' => 'nickname',
'meta_value' => 'jaytesh'
));
echo "user id is".$user_data[0]->ID;
And Your code will change to (approx code)
add_action( 'user_registration_after_register_user_action', 'ur_insert_username', 1, 3 );
function ur_insert_username( $valid_form_data, $form_id, $user_id ) {
global $wpdb;
$firstname = isset( $valid_form_data['first_name'] ) ? $valid_form_data['first_name']->value : '';
$lastname = isset( $valid_form_data['last_name'] ) ? $valid_form_data['last_name']->value : '';
{
$custom_nicename = sanitize_title_with_dashes( $firstname . '-' . $lastname);
{
$i = 1;
do {
$user_data=get_users(array(
'meta_key' => 'nickname',
'meta_value' => $custom_nicename
));
if( ! empty( $user_data[0]->ID ) ) {
$i++;
$custom_nicename = $custom_nicename ."-" . $i;
}
}
while ( ! empty( $user_data[0]->ID ) );
}
$wpdb->update(
$wpdb->users,
['user_nicename' => $custom_nicename],
['ID' => $user_id]
);
}
{
$user_post_athlete = array(
'post_title' => $custom_nicename,
'post_status' => 'publish', // <- here is to publish
'post_type' => 'athlete', // <- change to your cpt
'post_author' => $user_id
);
$user_post_rivalry = array(
'post_title' => $custom_nicename,
'post_status' => 'publish', // <- here is to publish
'post_type' => 'rivalry', // <- change to your cpt
'post_author' => $user_id
);
// Insert the post into the database
$post_id = wp_insert_post( $user_post_athlete );
$post_id = wp_insert_post( $user_post_rivalry );
}
}
I want to print (meta_value) from all fields
"Post_views_count" from table (post_meta) But provided that this happens in every category.
I want to count every visit inaide selected category , and in the end appear the name of category and every category generate visitors inside it .
This is the code that i used it and work good but the page are too slowly due to recurrent queries
<?php
$args = array(
'orderby' => 'name',
'parent' => 0,
'depth' => 0
);
// Extract all categories
$categories = get_categories( $args );
foreach ( $categories as $category ) {
// Extract all posts within each category
$args = array(
'cat' => $category->term_id,
'orderby' =>'post_date',
'post_type' => 'post',
'posts_per_page' => '-1',
);
$query = new WP_Query( $args );
// Views variable
$allview_cat = 0;
if ( $query->have_posts() ) {
$posttype = get_post_type(get_the_ID());
while ( $query->have_posts() ) {
$query->the_post();
$do_not_duplicate[] = $post->ID;
// Query that extracts all fields containing post_views_count + post id
$post_id = $wpdb->get_results("SELECT meta_value FROM $wpdb->postmeta WHERE (meta_key = 'post_views_count' AND post_id = $post->ID );");
$post_id = array_map(function($item){
return $item->{'meta_value'};
}
,$post_id);
foreach($post_id as $m_key => $m_value) {
$allview_cat = $m_value + $allview_cat ."<br>";
}
} // end while
} // end if
// Views variable
echo $allview_cat;
}
?>
<?php
$args = array(
'orderby' => 'name',
'parent' => 0,
'depth' => 0
);
$categories = get_categories( $args );
foreach ( $categories as $category ) {
$cat_id = $category->term_id;
$args_post = array(
'cat' => $cat_id,
'post_type' => 'post',
'posts_per_page' => '-1',
);
$query = new WP_Query( $args_post );
$allview = array();
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$post_id = get_the_ID();
if ( !isset( $allview[$cat_id] ) {
$allview[$cat_id] = 0;
}
$post_views_count = get_post_meta( $post_id, 'post_views_count' );
$allview[$cat_id] = (int)$allview[$cat_id] + (int)$post_views_count;
}
}
}
//display results
foreach ( $allview as $cat => $value ) {
echo $cat . ' = ' . $value;
}
?>
I'm adding new products (car listings) to my WooCommerce shop in bulk in PHP. I'm looping through rows in a custom data table and adding them as WooCommerce products.
I'm able to save each product and add the default meta (ie. description, price, sku, visibility, etc). However, I am not able to set custom product meta. Am I doing this in the wrong order?
Below is the code in my FOREACH loop that saves each row (but the "set_meta_data" is not working).
foreach ( $cars as $car ) {
set_time_limit(60);
$product = new WC_Product_Simple();
$product->set_name( $car->heading );
$product->set_status( 'publish' );
$product->set_slug( $car->heading . '-' . uniqid() );
$product->set_description( $car->seller_comments );
$product->set_regular_price( $car->price );
$product->set_sku( $car->vehicle_id );
$product->set_virtual( true );
$product->set_meta_data( array(
'neg_miles' => $car->miles,
'neg_year' => $car->year,
'neg_trim' => $car->trim,
'neg_drivetrain' => $car->drivetrain,
'neg_fueltype' => $car->fuel_type,
'neg_transmission' => $car->transmission,
'neg_doors' => $car->doors,
'neg_cylinders' => $car->cylinders,
'neg_color_ext' => $car->color,
'neg_color_int' => $car->interior_color,
'neg_is_certified' => $car->is_certified,
'neg_single_owner' => $car->carfax_1_owner,
'neg_engine' => $car->engine,
'neg_latitude' => $car->latitude,
'neg_longitude' => $car->longitude
) );
$product->save();
$product_id = $product->get_id();
if( !term_exists( $car->make, 'product_cat' ) ) {
$make = wp_insert_term( $car->make, 'product_cat' );
$model = wp_insert_term( $car->model, 'product_cat', array( 'parent' => $make['term_id'] ) );
} else {
$make = term_exists( $car->make, 'product_cat' );
if( !term_exists( $car->model, 'product_cat' ) ) {
$model = wp_insert_term( $car->model, 'product_cat', array( 'parent' => $make['term_id'] ) );
} else {
$model = term_exists( $car->model, 'product_cat' );
}
}
wp_set_object_terms( $product_id, array( intval($make['term_id']), intval($model['term_id']) ), 'product_cat' );
if( !empty( $car->body_type ) ) {
if( !term_exists( $car->body_type, 'neg_body_style' ) ) {
$body = wp_insert_term( $car->body_type, 'neg_body_style' );
} else {
$body = term_exists( $car->body_type, 'neg_body_style' );
}
wp_set_object_terms( $product_id, array( intval($body['term_id']) ), 'neg_body_style' );
}
$last_id = $car->ID;
}
set_meta_data method require another piece of meta structure (with id).
I think is better use update_meta_data method in loop:
$product->update_meta_data('neg_miles', $car->miles);
I've created a number of custom fields for custom taxonomy. Got no problem pulling their values inside the query. But in this case, I get them repeating as many times as I have posts in this taxonomy.
This is the code with it inside the loop
$tables_terms = $atts['custom'];
$tabargs = array(
'posts_per_page' => -1,
'offset' => 0,
'post_type' => 'customtables',
'tax_query' => array(
array(
'taxonomy' => 'tables',
'field' => 'slug',
'terms' => array(
$tables_terms
)
)
)
);
$tabs = new WP_Query( $tabargs );
if( $tabs->have_posts() ){
while( $tabs->have_posts() ) : $tabs->the_post();
$terms = get_the_terms( get_the_ID(), 'tables' );
foreach ( $terms as $term ) {
$t_id = $term->term_id;
$term_meta = get_option( "taxonomy_$t_id" );
echo $term_meta['term_1'];
}
endwhile;
wp_reset_postdata();
echo $custom;
}
How do I get these to show once, outside the loop?
You can use, get_term_meta;
get_term_meta retrieves metadata for a term.
get_term_meta( $term->term_id, 'your_term_name', true )
So the following code actually worked for me
$term_slug = $tables_terms;
$taxonomies = get_taxonomies();
foreach ( $taxonomies as $tax_type_key => $taxonomy ) {
if ( $term_object = get_term_by( 'slug', $term_slug , $taxonomy ) ) {
break;
}
}
$t_id = $term_object->term_id;
$term_meta = get_option( "taxonomy_$t_id" );
and from there on, I simply echoed each meta like this
echo $term_meta['term_1'];
Try Like that:
Store your output in a array and check when store it that value already exist or not.
$tables_terms = $atts['custom'];
$tabargs = array(
'posts_per_page' => -1,
'offset' => 0,
'post_type' => 'customtables',
'tax_query' => array(
array(
'taxonomy' => 'tables',
'field' => 'slug',
'terms' => array(
$tables_terms
)
)
)
);
$tabs = new WP_Query( $tabargs );
$term_meta_array = array();
if( $tabs->have_posts() ){
while( $tabs->have_posts() ) : $tabs->the_post();
$terms = get_the_terms( get_the_ID(), 'tables' );
foreach ( $terms as $term ) {
$t_id = $term->term_id;
$term_meta = get_option( "taxonomy_$t_id" );
echo $term_meta['term_1'];
if(!in_array($term_meta['term_1'], $term_meta_array)) array_push($$term_meta_array, $term_meta['term_1']);
}
endwhile;
wp_reset_postdata();
echo $custom;
foreach($term_meta_array as $st){
echo $st;
}
}