I need to add variations to my Woocommerce products programmatically and I borrowed the code from this answer thread:
Create programmatically a WooCommerce product variation with new attribute values
It works, but gives me two variations when I pass this data array:
$variation_data = array(
'attributes' => array(
'kidssize' => '2'
),
'sku' => '',
'regular_price' => '120',
'sale_price' => '',
'stock_qty' => '',
);
My guess is that funcntion fires two times.
Since i am a noob in php and backend in general all I know how to call a function is from some template file and visiting the page.
And to prevent other visitors from triggering it I use
if(isset($_GET['**parameter Only I know**']))
… wrap and call it going to the page with set parameter;
I understand that this is a really bad way for doing that, but how do I do it otherwise if I need to call function once and never use it again?
And is even firing twice a problem here or is it something wrong with my array?
EDIT:
Here's a detailed process of what i do:
i put the function from the link above in functions.php,
then put the call in footer.php of my theme with above mentioned wrap (the parameter is irrelevant - it could be anything, because it's just used as a trigger)
and go to the page with said parameter to trigger the call,
load the page only once and look for the result in admin panel.
And it has 2 variations always, even if i add more attributes to an array it will return 2 variatons of the last attributes array item;
Related
I am facing a problem to add such a product to the cart.
I manage to create the booking with:
$new_booking = get_wc_booking ($new_booking_data);
$new_booking -> create ($status);
But then I tried to apply these different methods without success:
add_cart_item_data ($cart_item_meta, $product_id); // error 500
or
$ new_booking_object -> add_cart_item ($cart_item_meta); // error 500
The $cart_item_meta object I create is like the following (some keys are duplicative, like for example start and start_date, because I observed in the code that both names are used, and I wanted to be sure to send at least the correct one ;-) ). BTW, by comparing with standard bookings created via the plugin form, I can be sure that the values I set in the array have the correct format.
$cart_item_meta = array(
'all_day' => false,
'cost' => $price,
'customer_id' => 1,
'user_id' => 1,
'date_created' => '',
'date_modified' => '',
'end' => $endDate,
'end_date' => $endDate,
'google_calendar_event_id' => 0,
'order_id' => $order->get_id(),
'order_item_id' => 0,
'parent_id' => 0,
'person_counts' => array($addPaxId => $pax),
'persons' => array($addPaxId => $pax),
'product_id' => $prodId,
'resource_id' => $resourceId,
'start' => $startDate,
'start_date' => $startDate,
'status' => 'in-cart',
'local_timezone' => 'Europe/Brussels',
);
I do get a record in the "posts" table, with the same specifics as a normal booking created by the normal way. In particular, I get post_type = wc_booking, and post_status = in-cart. But the cart remains empty.
I have compared all the entries in the database, and I can't see what is missing. But I'm definitely missing some of the understanding of the mechanics of WooCommerce ...
Does someone can help me to find a way to pass the final step: putting the created booking in the cart ? Thanks!
Well, maybe someone will be interested to know how I worked around, as so far I couldn't find a complete programming solution.
The products I want to book programmatically and add to the cart are existing products in my WooCommerce store. My purpose is just to use my own form to allow the customer to better understand what he books (I'm managing a flight simulators center with several machines), and the native WC Bookings form is not clear enough for me, and moreover it is really heavy and slow.
So after gathering customers info with my own form (simulator, duration, participants, timeslot), my problem was to put all this in the cart. I could achieve to create the relevant booking in the database, but not add it to the cart.
I observed that when you book via the standard form, you send a POST to the server on the same product page, including the following parameters (random data for example):
wc_bookings_field_persons_xxxx => 2 // 'xxxx' is the ID of the related 'bookable_person' in 'posts'
wc_bookings_field_start_date_month => 11 // November (sample)
wc_bookings_field_start_date_day => 26 // the 26th (sample)
wc_bookings_field_start_date_year => 2021 // Year (sample)
wc_bookings_field_start_date_time => 2021-11-26T15:00:00+0100
wc_bookings_field_start_date_local_timezone => Europe/Brussels
add-to-cart => 1147 // the product ID in 'posts'
So the simplest solution is to create a POST call (via form + button or button + ajax), setting the action/ajax url to the related product after filling the fields here above with the custom form...
EDIT: while I was thinking this was the solution, I discovered that it worked only when another tab in my browser previously 'opened the door' by adding the same product in the standard way. But when this tab is closed (or timeout), the above method fails and just open the product page. The 302 redirect that was operating stops to work for un unknown reason, and we get the standard 200 straight forward. No Cart.
So the question is still pending.
First things first:
This is my first question posted on stackoverflow. Put another way, this is the first problem I could not solve by myself with your help (huge thanks to all of you, you make the world go round!).
My question is related to an answer given by #LoictheAztec to another question (I originally planned to post my question in the comments of that post but being the lurker that I am/was, I lack the reputation to do so): https://stackoverflow.com/a/47766413/13263330
I have created a variable product and would like to add new attribute values to this product programmatically.
I copied and slightly modified the code from the link above but when I tried to execute it, I received the following errors:
Notice: wc_get_product was called incorrectly. wc_get_product should not be called before the woocommerce_init, woocommerce_after_register_taxonomy and woocommerce_after_register_post_type actions have finished. Backtrace: require_once('wp-load.php'), require_once('wp-config.php'), require_once('wp-settings.php'), do_action('plugins_loaded'), WP_Hook->do_action, WP_Hook->apply_filters, execute_active_snippets, execute_snippet, eval, create_product_variation, wc_get_product, wc_doing_it_wrong
Fatal error: Uncaught Error: Call to a member function get_name() on boolean
The problem mainly seems to be about the following line of code in the link posted above:
'post_title' => $product->get_name()
Just as a reminder and for convenience reasons, the product variable is defined as follows:
$product = wc_get_product($product_id)
The attribute values are correctly added to the variable product, so the code does what I expected and intended it to do but the site still crashes.
As far as I understand the situation, problems (and their causes) occuring could be related to:
The modifications I made in the code (already checked with default code and example given by #LoictheAztec within his post, same problem)
As always, compatibility issues with plugins and/or theme (already checked, deactivated all other plugins and changed to default theme; also tried code with fresh WP installation)
According to an answer given to someone having a similar problem (https://github.com/woocommerce/woocommerce/issues/23160), the issue can also be caused by the $product variable not being correctly "associated with a valid product" (not sure about this one but I think the "parent" variable product already created is fine) or "the product no longer existing" (can definitely rule this one out).
Any help whatsoever is highly appreciated.
If you are using Code Snippets plugins, Please try following code. (Run example code within woocommerce hook)
add_action('woocommerce_after_register_post_type', 'test_create_product_variation');
function test_create_product_variation(){
$parent_id = 746; // Or get the variable product id dynamically
// The variation data
$variation_data = array(
'attributes' => array(
'size' => 'M',
'color' => 'Green',
),
'sku' => '',
'regular_price' => '22.00',
'sale_price' => '',
'stock_qty' => 10,
);
// The function to be run
create_product_variation( $parent_id, $variation_data );
}
I'm currently working on a gallery system using cakephp. In it, we have paginated each image album so each page contains a set number of images at most. I have attained this by using:
$this->paginate = array(
'conditions' => array(
'Item.album_id' => $id
),
'order' => array(
'Item.added' => 'desc'
),
'limit' => '50'
);
On my view controller. With this, I can show all the items on each page with no problems.
I'm currently, however, facing a single issue: I need to show, after all the items in the current page, a button that leads to the next page. This is not a problem, except that by design the button that says NEXT PAGE should have an item from the next page as its background.
I have looked around, trying to figure out a way to pull an item from the next page of a paginated system in cakephp without luck. Has anyone done this, or does anyone have a clue how to go about it?
You have to query the preview image manually in the current page.
To access the page number you can use $this->params in the action. Then you have to query images with 'limit' and 'page' parameters as mentioned in the documentation.
After that set the image URL like this:
$this->set('preview_image_url', $queried_url);
Then in the view use inline styling to set the background for the next button.
With Alto's help, I ended up doing this (Putting it here just in case anyone wonders exactly how I did it):
$CurrPage = $this->params['paging']['Item']['page'];
$NextParams = array(
'limit' => 1,
//'page' => $CurrPage + 1,
'order' => array(
'Item.added' => 'desc'
),
'offset' => $CurrPage*50
//'order' =>('rand()')
);
$NextImage = $this->Item->find('first', $NextParams);
$this->set('NextImage', $NextImage);
This gives me the first item from the following page, which is good enough for me. Note the commented 'order' =>('rand()') - I tried to grab a random item from the following page but, alas, it seems like Cake first scrambles all items and THEN paginates. There's probably a way around this, but for now this one did it for me.
Also, using 'page' => $CurrPage + 1 didn't seem to work, with the system instead returning a seemingly randomly chosen image. That's why I instead defaulted to using 'offset' => $CurrPage*50, where 50 is the amount of items per page I'm showing.
Is there anyway to modify the content shown in a SugarCRM Subpanel without relying on Action Hooks?
Right now to edit content for a Subpanel field I have to use the hooks like this...
$hook_array['process_record']
And in the Class method that I assign the Hook to call I can then change a field in the Subpanel like this...
$bean->name = '<a href="/index.php?action=ajaxui#ajaxUILoc=index.php%3Fmodule%3Dproje_Web_Project_Tasks%26action%3DDetailView%26record%3D'
.$bean->id.'" rel="popover" data-content="'
.$bean->description.'" data-original-title="">'.$bean->name.'</a>';
The main and major problem we have with this method is it works great until you do either of these actions....
Add an item using the Quick Create form
Change a page using the Subpanel paging buttons
In either case, it reloads the Subpanel data without running this hook code on the data, so the result is pretty major as the Subpanel fields that you have edited are no longer edited and show up as normal.
Here is a basic example...this shows 2-3 fields that have been edited using the Hook method above...
Now after paging or quick-creating a new record in the Subpanel, it reloads the Subpanel data and does not apply the Hooked code so you can see the result looks like this...
I know that ListView has a much more reliable and flexible method for editing it's content using the get_list_view_data() method I am able to apply the same edits and have them work all the time!
So I am hoping there is a similar method to edit Subpanel data and have it always apply the edits to that data? From what I have seen in my research so far, the only solution that will work as expected all the time, is to make a completely new Custom Field Type!
I am really hoping that is not the ONLY way as that is a major pain to do that for each type of field that I need to edit in the Subpanels and just doesn't feel right when there are easy ways to edit everything else except SubPanel data.
Does anyone have any ideas, suggestions, tips, help, please do share with me on this matter as it is the main problem I have had since I started developing with SugarCRM in the past few months?
You can change the data by writing a custom query to get data for your subpanel.
So inside your bean (this case Contacts) do a functions:
function get_project_list() {
$query = "SELECT project, info, matching, column, names FROM projects WHERE contact_id = '" . $this->id . "' AND deleted = 0"
return $query;
}
and then in subpanel definition set the data source like this:
$layout_defs["Contacts"]["subpanel_setup"]['projects'] = array(
'order' => 10,
'sort_order' => 'desc',
'sort_by' => 'name',
'title_key' => 'LBL_PROJECTS_TITLE',
'subpanel_name' => 'contact_projects',
'module'=>'projects',
'get_subpanel_data' => 'function:get_project_list',
'function_parameters'=>array('type'=>'urgent'), // this is optional if you decide to sent parameters to the function if do this dont forget to define your function with function get_project_list($params)
'top_buttons' => array (... buttons that you need go here..),
);
Since sql is quite powerful you can modify your subpanel data any way you like, well more or less :)
I have a strange problem when using the wp_update_nav_menu_item function in a multisite installation.
It normally works when I execute this from within wp-admin. However, now I've been tasked with writing a handler script to auto-create a site, add a number of default pages, add a menu and populate the menu with those pages.
Here is the code in question:
$miid = wp_update_nav_menu_item($menu_id, 0, array(
'menu-item-title' => $post['post_title'],
'menu-item-object' => 'page',
'menu-item-object-id' => $pid,
'menu-item-type' => 'post_type',
'menu-item-status' => 'publish',
'menu-item-parent-id' => $navParentID,
'menu-item-position' => $post['menu_order']));
I've ensured that all of the values passed in to the function are correct and match with those which would be passed in when I call this function from within wp-admin dashboard.
The blog gets created successfully, as do the default pages, and the menu. When this executes it does return a $menu_item_db_id value indicating it worked successfully but nothing has actually been added to the menu and calling something like print_r(wp_get_nav_menu_object($menu_id)); returns nothing.
When I call the same exact function with the same exact inputs from a page within wp-admin everything works fine.
I've considered that perhaps the current blog context was not set correctly and have used this snippet to validate that I'm in the correct blog:
//Ensure we're updating the correct blog
$blogid = get_current_blog_id();
switch_to_blog($blogid);
echo get_current_blog_id()."<br/>";
Has anyone else encountered this issue?
I've had exactly the same problem..
The solution was to create item and menu relationship for each item :
wp_set_object_terms($item_id, $menu_id, 'nav_menu');
For some reason it was not created in wp_update_nav_menu_item