How to reliably retrieve product attribute data? - woocommerce

On a site where I started with WooCommerce version 2.. and then upgraded through newer releases (3.0.0, 3.0.1, ... 3.0.4), I'm noticing an inconsistency in how the order item meta data is stored for product attributes.
When using an attribute "Class Date" for variations, when an order is placed for some products in the store, the meta data for Class Date is stored using the key "pa_class-date". But for other products, the data for that same attribute is stored using the key "class-date".
My code for fetching attribute data looks like this:
$items = $order->get_items();
if ( isset($item['item_meta']['class-date']) ) {
$class_date = $item['item_meta']['class-date'];
} elseif ( isset($item['item_meta']['pa_class-date']) ) {
$class_date = $item['item_meta']['pa_class-date'];
} else {
error_log("Missing class date. We tried pa_class-date and class-date, but both are empty");
}
I would like to be able to simplify this to just look in one key or the other (pa_class-date or class-date, not both). Is that possible?
Here is what a dump of the order meta data looks like for the purchase of two different products. This one uses pa_class-date.
[467] => stdClass Object
(
[key] => pa_class-date
[value] => 2017-09-01
[display_key] => Class Date
[display_value] => <p>2017-09-01</p>
)
But for a different product, the data stored using the key "class-date":
26-Apr-2017 16:26:06 UTC] Array
(
[480] => stdClass Object
(
[key] => class-date
[value] => 2017-05-18
[display_key] => Class Date
[display_value] => <p>2017-05-18</p>
)
What causes the inconsistency in which key is used to store the data?
What is the most reliable (futureproof) way to retrieve the data?

This inconsistency is possible. But its inconsistent data entry rather. When you add attribute to Products >> Attributes, they become part of woocommerce system. Then you can map them to variation by just selecting on product details page.
However, when you add "Custom Attribute" directly from product details page, that data will be specific for that product and can cause inconsistency.

Related

Drupal Commerce: Can't get variation type machine name from product variation object

I successfully receive product variation object by its id
$variation = \Drupal::entityTypeManager()->getStorage('commerce_product_variation')->load(8);
Then I successfully receive its structure like
(
[variation_id] => Array
(
[x-default] => 8
)
[type] => Array
(
[x-default] => router
)
[uuid] => Array
(
[x-default] => a44c2c31-2131-4c99-82a6-856b566d97cf
)
...
by print_r() like
echo '<pre>';
print_r($variation);
echo '</pre>';
Now if I try to get SKU through $variation->sku->value, I get it
But if I try to get variation type machine name through $variation->type->value I get nothing (and gettype($variation->type->value) returns NULL).
Still, we see it in the structure with the value router
Why and how to get the machine name ?
It's strange: the print_r() shows the way is $variation->type->value
But I've just successfully got it by
$variation->type[0]->target_id
This answer may be useful for someone who stumbles upon this post in the future
To get the machine name of the variation type from a product variation object in Drupal 9 Commerce, you can use the following code:
<?php
use Drupal\commerce\PurchasableEntityInterface;
// Load the product variation object.
$product_variation = ...;
// Ensure the object is a valid product variation.
if ($product_variation instanceof PurchasableEntityInterface) {
// Get the variation type.
$variation_type = $product_variation->getPurchasedEntity()->bundle();
// Get the variation type machine name.
$variation_type_machine_name = $variation_type->id();
// Use the variation type machine name as needed.
...
}
This code uses the PurchasableEntityInterface to ensure that the loaded object is a valid product variation. The getPurchasedEntity() method is used to get the underlying entity that represents the variation, and the bundle() method is used to get the variation type. The variation type machine name can then be obtained using the id() method.

WooCommerce, WP all import - Find product ID by attribute value

I want to update WooCommerce products by the WP All import. I have 2 independent xml files (from the first one I'm getting prices, from the second one descriptions). For some reasons product's _sku is {code} from the first one xml not {ean}. So I put {ean} into product attribute pa_ean to match the products from the first one and the second one xml.
Now I don't know how to write the php function to return product_id so WP All import could update right products with right descriptions.
Do you have any unique identifier that are same for the product in both files? Like product_key or something. If you have it you can store it as custom meta for that product and get product by that meta key, something like below ↓
function check_if_product_exist($rawDataFromFile) {
global $products;
// Get WC_Product Objects
$products = wc_get_products([
'meta_key' => 'your_meta_key',
'meta_value' => $rawDataFromFile->your_key
]);
if (!empty($products)) {
return $products[0];
}
return null;
}
I put {ean} to Custom field, not to Attribute and after that I can easily use it in WP All import.

Alter views search api solr result

I am using search api and Solr, When I echo the result variable , it gave me the following results
stdClass Object
(
[entity] => 442415
[_entity_properties] => Array
(
[search_api_relevance] => 1
[search_api_excerpt] =>
[search_api_item_id] => 442415
)
)
In views i added ( custom text field, that is global variable), With this nid 442415, i will do certain node load operation and finally,
i will get price for the specific product. This code block will execute inside the foreach.
_views_pre_render
Please guideme,
which hook i should use , _views_post_execute or _views_pre_render ?
How to assign new value in to which variable and how to print that in tpl
Finally, i want to display the price on each item
This link resolved my problem.
Solution approach
function mymodule_views_pre_render(&$view) {
if($view->name == 'my_view') {
foreach($view->result as &$row) {
$row->_entity_properties['nothing'] = 'new value';
}
}
}
views-view-field--view-name--display-name--nothing.tpl.php
print $row->_entity_properties['nothing'];

Gravity Forms get merge tag token value

I am doing some customization for catching gravity form results on form submission. I get feed['meta'] array on form submission. But some fields have merge tag values like '{form_title}'. I need to get real value of the field instead of tokens. Following is the array I get on form submission.
Array
(
[name] => contact_test
[form_id] => 1
[contact_count] => 2
[type] => Contacts
[signature_text_2] => {Name (Prefix):2.2}{Name (Suffix):2.8}
[signature_html_2] => {Name (Suffix):2.8}{Name (Prefix):2.2}
)
I am having issues with last 2 fields where merge tags tokens are present. I need to fetch value of the corresponding fields.
GFCommon::replace_variables() worked for me. Just need to pass the token like {Name (Prefix):2.2}, form object, lead object. Remaining all are format specific options. The function is in gravityforms common.php file.

Sugarcrm : how to auto-populate field with related fields in QUICKCREATE view?

My configuration :
Sugar Entreprise 6.5.16
What i want to achieve :
When creating a contact by the quickcreate view (ie by clicking on "Create" in the Contact subpanel), i want to bring back any address informations from the related account chosen.
IE : I'm in my dashlet "My Contacts" on my home, i want to edit a contact. Sugar opens the popup, and i change the Account related to the contact. I chose, ie Microsoft. So, now that this account is chosen, i want Sugar to auto-fill the contact's address fields with the related account's address information.
What i've tested :
I saw this one :
How to autopopulate a field in SugarCRM form
and johndope's blog article (which is reaaaally helpful)
http://johndopenotes.wordpress.com/2013/03/18/sugarcrm-populating-fields-using-a-relate-field/
So i've created my SugarRoot/custom/Extension/modules/Contacts/Ext/Vardefs/sugarfield_account_name.php
and added this :
$dictionary['Contacts']['fields']['account_name']['populate_list'] = array('id','name','Accounts');
$dictionary['Contacts']['fields']['account_name']['field_list'] = array('account_id','account_name','primary_address_street');
And then, i edited my SugarRoot/custom/modules/Contacts/metadata/quickcreatedefs.php
and added this :
array (
'name' => 'account_name',
'displayParams' =>
array (
'key' => 'billing',
'copy' => 'primary',
'billingKey' => 'primary',
'additionalFields' =>
array (
'phone_office' => 'phone_work',
),
),
),
After a quick Rebuild and Repair, i've tested it, and nothing is happening.
I have to say that i've already done the exactly same thing for editviewdefs.php and it works...
So please, help me with this! :)
Recommendation from https://community.sugarcrm.com/sugarcrm/topics/auto_fill_related_field_from_parent_module_to_child_module
Example for Companies. Try adapt this code for your needs.
In custom/modules//views/view.quickcreate.php
Extend ViewQuickCreate class to set the corresponding $_REQUEST variable in preDisplay.
Remember that this is used by the + at the top right as well in case you have Contracts there so check that there is a parent and that it's a Company first.
class ContractViewQuickcreate extends ViewQuickcreate
function preDisplay(){
parent::preDisplay();
if (isset($_REQUEST['parent_id']) && $_REQUEST['parent_id'] != '' && isset($_REQUEST['parent_type']) && $_REQUEST['parent_type'] == 'Companies'){
$comp = new Company();
$comp->retrieve($_REQUEST['parent_id']);
//say the fields are company_id and company_name in Companies
//and company_id_c and company_name_c in Contracts
//assuming company is a relate field you'll need to map both
$_REQUEST['company_id_c'] = $comp->company_id;
$_REQUEST['company_name_c'] = $comp->company_name;
}
}
}

Resources