Programmatically adding a WC Booking in the cart fails - php

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.

Related

How can I fire a custom function just once in Woocommerce

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;

Cakephp - Getting items from next page in current page?

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.

WordPress user actions log

I want to log every action that the users do. What's the best way to do this and why? Using Custom post types to insert every action as a new post or using user_meta and save details in a multidimensional array? The data would look like this:
array(
array(
'type' => 'comment',
'time' => 1416335275,
'comment_id' => 210
),
array(
'type' => 'post'
'time' => 1416335275,
'post_id' => 450
),
array(
'type' => 'visited'
'visit_type' => 'page',
'time' => 1416335275,
'page_id' => 378
),
// ... etc.
)
I don't ask how to do this, just what do you think is the best way to store that data.
Relevant question: Why in the world would you want to do this?
OK, well to answer this is a generalized sense, Wordpress is a program that interfaces a database with HTTP requests. So you'd have to capture the content of each HTTP request, and probably filter that through requests that contain logged in users versus not logged in users. To be really specific you'd also have to capture the state of the database at each intersection! Sounds like a nightmare.
Probably you have something much more specific in mind than: "I want to log every action that the users do."
The best way to store data relevant to a user, is via the user meta system. For example:
http://codex.wordpress.org/Function_Reference/add_user_meta

how to create a custom drupal 7 edit page

Im a TOTAL newbie to drupal development so please help me here, ok i have created a custom module which so far creates a custom database how do i go about creating a list page in the backend that i can use to manage each item in the DB and how do i go about creating a custom edit form to manage the insert/ edit / delete of each item
function rollover_res_schema() {
$rollover_res = array();
$rollover_res['rollover_res'] = array(
// Example (partial) specification for table "node".
'description' => 'Positioning for rollovers',
'fields' => array(
'rollover_res_id' => array(
'description' => 'The primary identifier for a node.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'rollover_res_actual' => array(
'description' => 'The main rollover plain text.',
'type' => 'text',
'length' => 255,
'not null' => TRUE,
),
),
'indexes' => array(
'rollover_res_id' => array('rollover_res_id'),
),
'primary key' => array('rollover_res_id'),
);
return $rollover_res;
}
If you're a total newbie to Drupal development you should not be writing ANY code for the first month or two and you shouldn't do custom database code the first 6 months.
Start with learning about Fields and Views and once you grasp these you can add one of Display Suite, Context or Panels.
The key to learning how to do things in drupal is:
1) google search how
2) see how other modules do it. In this case, look at some core modules, such as the block module. In there you'll see the schema in .install, and you'll see some functions that create forms for saving new blocks, such as block_add_block_form. You'll need to read up on the form API. But basically, you'll create a form hook to display a form, a menu hook to create a page to hold the form, and a hook to submit the form. If you grep through your code base, you'll see many of examples that you can copy. In fact, there are drupal example modules you can download that cover most of the basics: https://www.drupal.org/project/examples
But to learn how to interact with the database, you could find a module that does something similar to what you're doing and look at how it uses hook_menu to set up page callbacks, forms for editing data.

How do I add another attribute to order_aggregated_created table?

I’ve been scratching my head for days on this one. Any help or a push in the right direction would be greatly appreciated.
I’ve extended the sales report under Reports->Sales->Orders and created my own custom filters to filer the report by channels.
Each order has a ‘channel_name’ attribute to identify whether the order came from eBay, Amazon, etc.
Now I cannot for the life of me figure out how sales/order_aggregated_created table that is used to generate the reports is created. Where does the magic happen? I want to add ‘channel_name’ to the order_aggregated_created table to be able to filter by this attribute, but I cannot figure out how to this.
Diagram for order_aggregated_created table with its attributes:
http://www.magento-exchange.com/wp-content/uploads/2010/11/MAGENTO-SALES-ORDER-ER.png
Mage_Sales_Model_Resource_Report_Order_Collection is where the magic starts in retrieving the sales totals, particularly if I understood this correctly inside
protected function _getSelectedColumns(){...}
if (!$this->isTotals()) {
$this->_selectedColumns = array(
'period' => $this->_periodFormat,
'orders_count' => 'SUM(orders_count)',
'total_qty_ordered' => 'SUM(total_qty_ordered)',
'total_qty_invoiced' => 'SUM(total_qty_invoiced)',
'total_income_amount' => 'SUM(total_income_amount)',
'total_revenue_amount' => 'SUM(total_revenue_amount)',
'total_profit_amount' => 'SUM(total_profit_amount)',
'total_invoiced_amount' => 'SUM(total_invoiced_amount)',
'total_canceled_amount' => 'SUM(total_canceled_amount)',
'total_paid_amount' => 'SUM(total_paid_amount)',
'total_refunded_amount' => 'SUM(total_refunded_amount)',
'total_tax_amount' => 'SUM(total_tax_amount)',
'total_tax_amount_actual' => 'SUM(total_tax_amount_actual)',
'total_shipping_amount' => 'SUM(total_shipping_amount)',
'total_shipping_amount_actual' => 'SUM(total_shipping_amount_actual)',
'total_discount_amount' => 'SUM(total_discount_amount)',
'total_discount_amount_actual' => 'SUM(total_discount_amount_actual)',
);
}
If would be awesome if I can just ‘channel_name’ =>$this->_channelName, and be on my merry way.
After a lot and lot of research it turns out that sales/order_aggregated_created table gets generated in here:
Mage_Sales_Model_Resource_Report_Order_Createdat
now I've looked here before seemed like exactly what I needed, but any changes I made would not reflect in Magento reports especially inside the sales/order_aggregated_created table.
I found out that Mage_Sales_Model_Resource_Report_Order_Createdat only gets called when you refresh the statistics inside Reports->Sales->Orders, only then a NEW sales/order_aggregated_created table is generated! So for anyone looking to filter the order sales report by a custom attribute, look inside: /app/code/core/Mage/Sales/Model/Resource/Report/Order/Createat.php

Categories