Import variables products after export - wordpress

I have export my variations product from woocomerce using standart WP export stuff, how to import them back?
When I use import WP write to me all done, but in products variations did not appear

It took me hours to figure out why the post_parent field (for WooCommerce product Variations, in my case) wouldn't import using the integrated WordPress Export/Import. I ended up looking in the import plugin files and that's where I found the answer. It turns out it only applies the post_parent field, if the parent ID being referenced is contained in the same import. Which is silly since Products and Variations have to be exported as separate XML files.
Anyway, I temporarily added one line of code to the wordpress-importer.php file to get my import to work. Obviously, you shouldn't go around hacking plugins, but this is what worked for me:
$post_parent = (int) $post['post_parent'];
if ( $post_parent ) {
// if we already know the parent, map it to the new local ID
if ( isset( $this->processed_posts[$post_parent] ) ) {
$post_parent = $this->processed_posts[$post_parent];
// otherwise record the parent for later
} else {
$this->post_orphans[intval($post['post_id'])] = $post_parent;
$post_parent = 0;
}
$post_parent = (int) $post['post_parent']; // ADDED THIS LINE
}

Problem was in field post_parent. I don't know why, but in database this field set 0 and not from .xml file.
My resolve of problem:
Set manually in db parent post id

Related

Import data from csv into a specific post

I have multiple posts that has multiple custom fields on it. Now i need to add these fields from a excel/csv file. These files contain lots of info about this post. The problem i run into is that i don't see a way to import this content automatically. I don't seem to be able to use wp all import for this because it create a new item for each record and thats not what i want. All records need to be added as a custom field/repeater field.
If anyone has an idea on how to do this it would be much appreciated.
I tried to import this data using WP all import without succes.
function add_some_fields($file_url) {
$data= array_map('str_getcsv', file($file_url));
foreach ($data as $item) {
$post_id = $item[0]; // I hope you have post_id in that CSV file somewhere
$field_name = $item[1] ; // ACF field name IF YOU HAVE IT IN CSV if not set manually, or make an array with names
$col1 = $item[2]; //Value
add_row( $field_name, $col1, $post_id ); //add row (https://www.advancedcustomfields.com/resources/add_row/)
}
}
Call from where you want and how you want, usually I use condition in footer checking if custom GET parameter passed and if Yes then run function.

Woocommerce product categories are missing (not displaying) when adding product

I have recently come across a problem where i can't assign products to categories as the categories aren't displaying in the meta box when adding products. Here is the example:
Once i add the new category it seems to disappear when the page is reloaded. You can see that it says 6 items but it doesn't show any categories. Here is an example:
OP created a Wisdom of the Ancients post for me with this one.
I turned on debugging and saw an error discussed in this question:
How to resolve "ORDER BY clause is not in SELECT list" caused MySQL 5.7 with SELECT DISTINCT and ORDER BY. I was using a Managed MySQL service from Digital Ocean and couldn't modify the global settings or my.cnf files.
For my future self and other wanderers. My issue was that MySQL's 'ANSI' mode includes 'ONLY_FULL_GROUP_BY'.
WordPress filters out 'ONLY_FULL_GROUP_BY' by default in /wp-includes/wp-db.php but my Managed SQL server had ANSI set by default as well.
My solution was to make a crappy little WordPress plugin that would make sure they both got removed every session.
https://fishy.getgit.co/fishy/remove-ansi-sql-mode
Or just Copy/Pasta:
<?php
/*
Plugin Name: Remove ANSI SQL_MODE
Version: 1.0
Description: Removes the 'ANSI' SQL MODE if it exists as it contains 'ONLY_FULL_GROUP_BY' since MySQL 5.7.5. See https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_ansi
*/
class Remove_Ansi_Sql_Mode {
static function init(){
add_action('init', array( __CLASS__, 'strip_ansi_mode' ) );
}
static function strip_ansi_mode(){
global $wpdb;
// Copied from /wp-includes/wp-db.php
$incompatible_modes = array(
'NO_ZERO_DATE',
'ONLY_FULL_GROUP_BY',
'STRICT_TRANS_TABLES',
'STRICT_ALL_TABLES',
'TRADITIONAL',
'ANSI' // Adding ANSI
);
$sql_modes = explode(',', $wpdb->get_col( "SELECT ##SESSION.sql_mode" )[0]);
foreach ($sql_modes as $key => $value) {
if(in_array($value, $incompatible_modes)){
unset($sql_modes[$key]);
}
}
$wpdb->set_sql_mode($sql_modes);
}
}
Remove_Ansi_Sql_Mode::init();
I had this same issue after updating to WooCommerce 3.6. Solved it by deactivating the WP Term Images plugin.
Try this, it's working for you

WP All Import Pro: Polylang compatibility

I'm trying to import data from an Excel sheet into WordPress with the Pro version of WP All Import. We are using Polylang for multi language support. I wonder how to manage importing the content into the correct language versions. I discovered that there is a hidden taxonomy "language" which I can manually set to "de" for setting language to German. But how do I link corresponding translations? Any ideas how to solve this, maybe with some custom functions? Thank you in advance!
I have found a better solution.
if ( !function_exists( 'pll_save_post_translations' ) ) {
require_once '/include/api.php'; }
$arr = array();
$result = pll_save_post_translations(['en' => 21398, 'ro'=>21396]);
//where 21398 and 21396 are the post_id and 'en' and 'ro' the nicenames of the languages.
Put this code in your functions.php and run it only once (meaning you refresh the page only once as admin after you put it). Then delete the code from functions.php. It does not actually create errors, just don't risk it, don't run it twice.
Before you do that, you must import the products in both (in my case) languages. Meaning you import them in one language (you select one language from the top admin bar) and then in another session you import them in the other language (you select the other language) and also if you see "Show private taxonomies" in WP All import, put one language code there. One for each session. After the products in both languages have been imported, you run the code above to tell WordPress that "this post_id is the translation of that post_id".
I hope it helps.
Ah, and you get the post_id in a nice table which you can edit in excel by exporting the products with Wordpress Export (it is pre-installed when you install WordPress, I think). You find it in Dashboard in Tools/Export.
And put
$result = pll_save_post_translations(['en' => 56465, 'ro'=>654864]);
as many times as you need
$result = pll_save_post_translations(['en' => 9999, 'ro'=>34654]);
$result = pll_save_post_translations(['en' => 98641, 'ro'=>98651]); .
for each correlation.
You can do it easier in Excel, you have the correlating id's on two separate columns then put this formula on the next row
=concatenate("$result = pll_save_post_translations(['en' =>",CELL A1,"
'ro'=>",CELL B1,"]);")
Apply it downwards. Select the column you have just concatenated. Paste it under the code in functions.php. Save. Refresh. Delete code from functions.php. Refresh. Booyah.
Please note that I'm currently using both Polylang and Wp All Import/Export Pro versions.
Also, this is currently not 'outdated' code. It relies on an undocumented feature, that was suggested directly from the wp all import team. I'm speaking simply of the additional parameter $data passed by the pmxi_saved_post action.
That said, I know polylang devs are currently working on an addon for this specific issue. Anyway, I managed to do it in this way, for now:
1 -> when you export data, there are 2 polylang-related fields: languages and post_translations. Export them too.
2 -> when you import your data, on the wpallimport screen, create 2 more custom fields and save the 2 above. See attachment below. Now you've got the translations data with every post.
3 -> set this filter:
global $language_codes;
$language_codes = array( // sample lang data
'italiano' => 'it'
,'english' => 'en'
,'espanol' => 'es'
,'francais' => 'fr'
,'deutsch' => 'de'
);
add_action('pmxi_saved_post', 'set_imports_lang', 10, 2);
// using undocumented param $data
// action firm is the following (in fact, it passes 3 params): do_action( 'pmxi_saved_post', $pid, $rootNodes[$i], $is_update );
function set_imports_lang($post_id, $data){
global $language_codes;
// 'lingue' is italian, I guess it will be 'languages' in english: it's one of the 2 fields we saved before
pll_set_post_language($post_id, $language_codes[sanitize_title($data->lingue)]);
}
At this point you have just set each post's original language, nothing more. Now we have to link translations each other. We'll do this with a function that we have to run ONLY 1 TIME. It will run simply reloading any wp screen/page.
function set_imports_translations(){
global $wpdb;
global $language_codes;
// substitute 'enews' with your own post type
$list = $wpdb->get_results("
SELECT
m.post_id, m.meta_value pll, group_concat(concat_ws(':', m2.meta_value, m.post_id)) ids
FROM
$wpdb->posts p
INNER JOIN $wpdb->postmeta m ON p.ID = m.post_id
INNER JOIN $wpdb->postmeta m2 ON m.post_id = m2.post_id AND m2.meta_key = '_import_language_name'
WHERE
p.post_type = 'enews' AND m.meta_key = '_import_translations_id'
GROUP BY pll
");
// query results are something like this:
// 10258 pll_57e92254c445f 10258:Italiano,10259:English,10260:Español,10261:Français,10262:Deutsch
// 10263 pll_57e922552b8c6 10263:Italiano,10264:English,10265:Español,10266:Deutsch
// 10267 pll_57e9225587124 10267:Italiano
// extract data from the third column string
foreach($list as $item){
$ids = explode(',',$item->ids);
$list = array();
foreach($ids as $id){
$data = explode(':',$id);
$list[$language_codes[sanitize_title($data[0])]] = intval($data[1]);
}
//set the translations
pll_save_post_translations($list);
}
}
set_imports_translations();
That's all. :) Ah, the attachment mentioned above:

woocommerce add function when admin changes product's attributes

I am relatively new to woocommerce development so I am sorry if this question might be too trivial but I need help.
I need in my application a way to make some checks when an admin makes changes to a product in woocommerce.
For example, I want to create a log file of all the changes that occurred on products. Who made them, when and what was the change (price, inventory, description, etc.).
I understand that there are hooks in woocommerce that I can use. Which ones can help me do something like that?
Use post_updated hook for this purpose, place the following code in your functions.php
function product_update_handler( $id, $before_data, $after_data ) {
if( $before_data->post_type == "product" ) {
$current_user = wp_get_current_user();
error_log( $before_data->post_title ." has been updated by ".$current_user->user_login );
}
}
add_action('post_updated', 'product_update_handler', 0, 3);
you have two product objects ( before update, after update ) with the above hook, you can compare both object and log the changes.

Hook before deleting a file in wordpress

Few days ago, I was assigned to task in wordpress. This task is to limit media folder capacity for each user. For example, each user can upload only files only for 100MB. I found a really nice post, which explained and used hooks named wp_handle_upload_prefilter and wp_handle_upload for retrieving the file size and storing them before upload.
Right now, I need to know, or hook some function when user presses "Delete permanently" in media folder, so that I can recalculate the capacity of media folder for specific user. Can anyone help me with this?
In case anyone else needs to react to deleted media, this was my solution to get around the issue that there's no delete media action:
function get_media_item_args( $args ) {
if ($args["delete"] && $_GET["action" == "delete-post"])
{
$current_post_id = !empty( $_GET['id'] ) ? (int) $_GET['id'] : 0;
if ($current_post_id > 0)
{
//Do your thing here.
}
}
return $args;
}
add_filter( 'get_media_item_args', 'get_media_item_args', 10, 1 );
Maybe you can use delete_attachment hook for that. However, this one only affect files that is already attached to post.

Resources