Working with serialized data in Wordpress - wordpress

I have the following string of serialized data in a Wordpress custom field:
$first_string = 'a:9:{s:5:"email";s:13:"test#test.com";s:4:"name";s:15:"Werner
Etsebeth";s:8:"address1";s:17:"1 Giligans
Island";s:8:"address2";s:1:"5";s:4:"city";s:9:"Cape
Town";s:5:"state";s:2:"AL";s:3:"zip";s:4:"7460";s:7:"
country";s:2:"US";s:5:"phone";s:0:"";}
$second_string = 'a:1:{i:4;a:1:{i:0;a:6:
{s:3:"SKU";s:0:"";s:4:"name";s:12:"Hypnotherapy";s:3:"url";s:72:"http://localhost
/mindworksa.co.za/wordpress/store/products/hypnotherapy
/";s:5:"price";s:5:"50.00";s:8:"quantity";s:1:"1";s:8:"download";s:0:"";}}}'
How do I assign the info to variables so I can access individually eg $SKU = "", $name = etc.
I've never worked with serialized data before and any help would be greatly appreciated.
Many thanks

I am unable to unserialize your example (did you paste it in correctly?) but Wordpress uses serialize() to serialize objects to store them in the database.
You can unserialize them using unserialize().
A quick example:
$serialized = 'a:3:{i:0;s:5:"apple";i:1;s:6:"banana";i:2;s:6:"orange";}';
var_dump(unserialize($serialized));
Output:
Array
(
[0] => apple
[1] => banana
[2] => orange
)

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.

Symfony 5 Convert string to datetime

In Symfony 5 I have a form where users enter into text fields and also a date. This is then redirected into a display controller that displays matching rows from the database. The date needed to be converted into a string for the redirect to work.
$firstName = $findPt->getFirstName();
$surname = $findPt->getSurname();
$username = $findPt->getUsername();
$dob = $findPt->getDateOfBirth();
$dobStringValue = $dob->format('Y-m-d');
return $this->redirectToRoute('app_displayClients', ['firstName' => $firstName,
'surname' => $surname,
'username' => $username,
'dob' => $dobStringValue]);
However in the display controller I then need to convert it back into a datetime to use it but that doesn't seem possible. I've tried various options, such as $dobDateTime= new DateTime($dateStr);
Please let me know if this question isn't clear or you need more information.
Many thanks in advance for any help.
You can reconvert it using DateTime::createFromFormat
$dobStringValue = $dob->format('Y-m-d');
$dobReconverted = \DateTime::createFromFormat('Y-m-d', $dobStringValue);
Thanks Agnohendrix, that was helpful. I didn't need to format as it was already a string but used $dobReconverted = \DateTime::createFromFormat('Y-m-d', $dobStringValue);
The \ seemed to have been what made it work, maybe this is something to do with using Symfony.
It works with "\Datetime" and not with "Datetime" because "Datetime" needs to be defined with a "use Datetime" to work; that's why the error "Did you forget a use statement for..." came out.

How to reliably retrieve product attribute data?

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.

Symfony 2 custom DQL request inside an array field

I'm trying to make a custom request in my repository with a WHERE clause inside an array field. I tried something like that, not working, but can better show my problem :
$qb ->andWhere( "p.addresses[:index] = :address" )
->setParameter( "index" , $p_idLang )
->setParameter( "address" , $p_address );
Extracted from the documentation about array type:
Maps and converts array data based on PHP serialization. If you need
to store an exact representation of your array data, you should
consider using this type as it uses serialization to represent an
exact copy of your array as string in the database. Values retrieved
from the database are always converted to PHP’s array type using
deserialization or null if no data is present.
Your query doesn't make sense. You have a few options though:
Retrieve p.adresses and check using php if p.adresses[$index] = $address
Try something much less reliable but that could work:
$val_length = strlen($p_address);
$qb ->andWhere( "p.addresses LIKE :indexAddress" )
->setParameter( "indexAddress" , "%i:$p_idLang;s:$val_length:$p_address%" );
Create a new entity and a relation oneToMany between this entity and the new one.
I'd definetely try option 3. Option 1 isn't an option if the array is big or will become big in the future. I wouldn't go for option 2, but as an experiment could be worth trying.

Adding an array of an array at Amazon DynamoDB

I know that AmazonDB supports number, string, number set and string set as item types. But, how about a set of an string set (array of array, or multidimensional array)?
In case it's possible, this is the only way I found to do that, which didn't work (using PHP):
$units_frequencies["id"][0] = "400";
$units_frequencies["id"][1] = "401";
$units_frequencies["id"][2] = "402";
$units_frequencies["frequency"][0] = "20";
$units_frequencies["frequency"][1] = "30";
$units_frequencies["frequency"][2] = "50";
// item that will be inserted
$item = array(
'id' => array(AmazonDynamoDB::TYPE_STRING => $id),
'arrays_field' => array(
AmazonDynamoDB::TYPE_ARRAY_OF_STRINGS => array(
AmazonDynamoDB::TYPE_ARRAY_OF_STRINGS => $units_frequencies)));
I don't want to have two columns (one for $units_frequencies["id"] and $units_frequencies["frequency"]) because the second one can have two index with the same values, which is not allowed by Dynamo.
Thanks in advance.
It doesn't.
At least while looking at AttributeValue.class (AWS Java SDK)
I also couldn't find any hint on the documentation site except for those dealing with int, string, set of string or set of int
You can eventually serialize your object. More info at https://java.awsblog.com/post/Tx1K7U34AOZBLJ2/Using-Custom-Marshallers-to-Store-Complex-Objects-in-Amazon-DynamoDB

Resources