Serialized data issue in wordpress - wordpress

I am facing an issue in wordpress serialized data. I am developing a custom plugin which is in relation with woocommerce. I have added a checkout section in woocommerce settings section. Also I am providing same settings update form in my plugin section which is new menu option in left menu.
when I am saving data through woocommerce setting section it stores data in in wp_options table as serialized data. Below is example :
a:18:{s:7:"enabled";s:3:"yes";s:9:"test_mode";s:2:"no";s:19:"is_application_name";s:0:"";s:10:"is_api_key";s:0:"";s:17:"order_customtable";s:0:"";s:16:"order_customflds";s:0:"";s:23:"order_product_customfld";s:0:"";s:14:"is_merchant_id";s:0:"";s:5:"title";s:12:"Infusionsoft";s:9:"tax_label";s:9:"Sales Tax";s:16:"is_free_shipping";s:2:"no";s:11:"description";s:20:"Pay via
Infusionsoft";s:5:"cards";s:16:"VISA
MASTERCARD";s:14:"wooorderstatus";s:0:"";s:14:"thanks_message";s:39:"Thank
you. Your order has been
received";s:5:"debug";s:2:"no";s:11:"debug_email";s:0:"";s:13:"http_post_key";s:0:"";}
From my plugin page, on form submit I am getting field values and creating an array as below :
Array (
[enabled] => yes
[test_mode] => no
[is_application_name] =>
[is_api_key] =>
[order_customtable] =>
[order_customflds] =>
[order_product_customfld] =>
[is_merchant_id] =>
[title] => Infusionsoft
[tax_label] => Sales Tax
[is_free_shipping] => no
[description] => Pay via Infusionsoft
[cards] => VISA MASTERCARD
[wooorderstatus] =>
[thanks_message] => Thank you. Your order has been received
[debug] => no
[debug_email] =>
[http_post_key] => )
Now serializing and updating option using function update_option it will save data in in data base as below string :
s:597:"a:18:{s:7:"enabled";s:3:"yes";s:9:"test_mode";s:2:"no";s:19:"is_application_name";s:0:"";s:10:"is_api_key";s:0:"";s:17:"order_customtable";s:0:"";s:16:"order_customflds";s:0:"";s:23:"order_product_customfld";s:0:"";s:14:"is_merchant_id";s:0:"";s:5:"title";s:12:"Infusionsoft";s:9:"tax_label";s:9:"Sales Tax";s:16:"is_free_shipping";s:2:"no";s:11:"description";s:20:"Pay via
Infusionsoft";s:5:"cards";s:15:"VISA
MASTERCARD";s:14:"wooorderstatus";s:0:"";s:14:"thanks_message";s:39:"Thank
you. Your order has been
received";s:5:"debug";s:2:"no";s:11:"debug_email";s:0:"";s:13:"http_post_key";s:0:"";}";
Please help me in this issue.

Don't serialize the array yourself, update_option will do it if needed.
https://developer.wordpress.org/reference/functions/update_option/

Related

Google Analytics Custom Metrics not showing up

I want to push the products profit of a transaction to Google Analytics.
With this i want to generate a report where i can see the total Product revenue and it's profit for each product that has been ordered.
i'm using this api to push custom metrics to analytics (Measurement protocol api)
I have made several custom metrics in analytics, for example:
Productsprofit (Scope hit, decimal)
Productsprofit2 (Scope Product, decimal)
I've googled several times and i think i need to use the Scope Hit for this type of tracking, am i right?
I've used the api to push the metric with the right indexes to Analytics
$analytics->setTransactionId('test'.$orderId)
->setAffiliation('Testshop')
->setRevenue(number_format($orderTotalPrice,2,'.',''))
->setTax(number_format($taxTotal,2,'.',''))
->setShipping(number_format($shippingTotal,2,'.',''))
->setCouponCode('');
foreach($orderInfo['orderDetails'] as $orderDetail) {
// Include a product, only required fields are SKU and Name
$productData1 = [
'sku' => $orderDetail['model'],
'name' => $orderDetail['name'],
'brand' => '',
'category' => '',
'variant' => '',
'price' => number_format($orderDetail['price'], 2, '.', ''),
'quantity' => $orderDetail['aantal'],
'coupon_code' => '',
'position' => 0,
'custom_metric_3'=>50.45, //<-- test data (Hit)
'custom_metric_4'=>15.50 //<-- test data (Product)
];
$analytics->addProduct($productData1);
}
// Don't forget to set the product action, in this case to PURCHASE
$analytics->setProductActionToPurchase();
// Finally, you must send a hit, in this case we send an Event
$analytics->setEventCategory('Checkout')
->setEventAction('Purchase')
->sendEvent();
I've created a custom report and added these metric to my report. But both metrics stay empty in my report.
Does anyone know what i'm doing wrong ? or what might solve my problem?
Thanks in advance!
In the PHP library that you are using, custom metrics and dimensions are set in a different manner depending on the scope, for Product scope you use the product array like you did, for Hit scope you use the setCustomMetric method. In your code this would look like:
$analytics->setTransactionId('test'.$orderId)
->setAffiliation('Testshop')
->setRevenue(number_format($orderTotalPrice,2,'.',''))
->setTax(number_format($taxTotal,2,'.',''))
->setShipping(number_format($shippingTotal,2,'.',''));
foreach($orderInfo['orderDetails'] as $orderDetail) {
$productData1 = [
'sku' => $orderDetail['model'],
'name' => $orderDetail['name'],
'brand' => 'the brand',
'category' => 'test category',
'variant' => 'variant x',
'price' => number_format($orderDetail['price'], 2, '.', ''),
'quantity' => $orderDetail['qty'],
'coupon_code' => 'coupon used',
'custom_metric_4' => 15.50,
];
$analytics->addProduct($productData1);
}
$analytics->setProductActionToPurchase();
$analytics->setCustomMetric(50.45, 3);
$analytics->setEventCategory('Checkout')
->setEventAction('Purchase')
->sendEvent();
Notice the call to $analytics->setCustomMetric(50.45, 3); before sending the hit. This should send the right data, the rest is creating or looking at the right report in Google Analytics.

Sort and paginate by custom date field with Wordpress / ACF / Timber

I'll try to describe what it is I want to achieve, please let me know if too much/not enough detail!
I'm making a site that needs to have documents uploaded to it. These documents will belong to one only of four categories and there will be one page per category. On this page, by default all documents will display. Users will also be able to view only the documents from each year by clicking a link.
It also needs to have pagination so a max of 10 documents are displayed per page.
So how I would ideally like to do this is to make a custom post type (documents) which would then display an ACF custom field set. The field set would have three fields (doc_type, doc_file and release_date). doc_type would be a select field of the four categories, doc_file a file upload and release_date a datepicker field.
When you click on a page, the controller would select by doc_type to only show the documents that belong to that category.
I want to order by release_date and use the year from this field as the display text of my links. For the actual href, I'm imagining something like /path/to/page.php?year=2017.
So there's a few problems here: first is that I am not sure if what I want to do is even possible - let alone a good way of doing things - with WordPress. I'm more used to pure PHP and mySQL, and so I might be trying to shoehorn more general solutions into WP. Can anyone confirm if it's possible to achieve what I want?
Second, I'm specifically running into some issues when I try to execute this plan.
I can successfully get each page to only display the documents that belong to it, like so (although I'm generating $last by grabbing info from the URI, which seems dodgy).
$docArgs = array(
'post_type' => 'documents',
'meta_key' => 'doc_type',
'meta_value' => $last,
);
$context['documents'] = Timber::get_posts($docArgs);
When I try to get my sorting on though, de nada:
$docArgs = array(
'post_type' => 'documents',
'meta_key' => 'doc_type',
'meta_value' => $last,
'meta_query' => array(
array(
'key' => 'release_date',
'orderby' => 'meta_value_num',
'order' => DESC,
),
),
);
I assume I've got the syntax wrong, but I'm basically really confused about the whole thing. Any suggestions?

Symfony2 - related entity contains 'isDefault' property how to use in related entity form

I have 2 related entities, e.g. Book and Publisher (Book has one publisher, publisher has many books).
When editing\adding a Book I want to present a select of the Publishers.
Publishers has a property 'isDefault' on of the Publisher records will be marked as isDefault TRUE.
How do I make use of this in my add/edit form to pre-select the default Publisher?
I would recommend injecting publisherRepository as a service into your form.
And then declare a field something like this:
$builder->add('publishers', 'choice', array(
'choices' => $this->publisherRepository->findAll(),
'data' => $this->publisherRepository->findOneBy(['isDefault' => true]),
));

Restrictions for app tab pages?

is there a way to install the app to the page with restrictions to the visitors country or age?
I am programming an app which will be only available for Users of distinct coutries.
However, I am planning to install the app as a tab on a Facebook page that is international with no restrictions. And I don't want users from other countries seeing my app.
Is this possible?
Regards,
Flashbaer
It should be possible according to https://developers.facebook.com/docs/reference/fbml/restricted-to/
Whatever settings I use result in that the tab isn't available for non-signed in users and is always available for signed in users. I don't think I'm doing anything wrong.
This is the code I use:
self::$facebookClient = new Facebook(array(
'appId' => $appId,
'secret' => $appSecret,
));
$restrictions = array(
'location' => 'AR,AT',
// 'type' => 'alcohol',
// 'age' => '50+',
);
var_dump($fb->api('/'.$appId.'?restrictions='.urlencode(json_encode($restrictions)), 'POST'));
var_dump($fb->api('/'.$appId.'?fields=restrictions'));

How do I persist form data across an "access denied" page in Drupal?

We're building a small sub-site that, on the front page, has a one input box form that users can submit. From there, they're taken to a page with a few more associated form fields (add more details, tag it, etc.) with the first main form field already filled in. This works splendidly, thus far.
The problem comes for users that are not logged in. When they submit that first form, they're taken to a (LoginToboggan based) login page that allows them to login. After they login, they redirect to the second form page, but the first main form field isn't filled in -- in other words, the form data didn't persist.
How can we store that data and have it persist across the access denied page?
You could save the data in a cookie that would be passed to the page after the login page.
Assuming that you are using the Form API to create the form, and that you have a field called "fieldname" in the function to generate the form:
function my_form() {
$form['fieldname'] = array (
'#type' => 'textfield',
'#title' => 'Some fieldname'
);
// Second field if you need to save another
$form['fieldname2'] = array (
'#type' => 'textfield',
'#title' => 'Some other fieldname'
);
}
Set the cookie(s) in the submit handler for your form:
function my_form_submit($form, &$form_state) {
// Set the cookie with their data before they are redirected to login
// Use the array syntax if you have one than one related cookie to save,
// otherwise just use setcookie("fieldname",...
setcookie("saved_data[fieldname]", $form_state['values']['fieldname']);
// Your other code
}
After they login and are redirected to page two of your form, you can read the value of the cookie(s) and if they exist, insert them into the default values of the fields:
function my_form() {
if (isset($_COOKIE['saved_data[fieldname]'])) {
$default_fieldname = $_COOKIE['saved_data[fieldname]'];
}
else {
$default_fieldname = '';
}
// Same check for the second field
if (isset($_COOKIE['saved_data[fieldname2]']))...
$form['fieldname'] = array (
'#type' => 'textfield',
'#title' => 'Some fieldname',
'#default_value' => $default_fieldname
);
// Second field if used
$form['fieldname2'] = array (
'#type' => 'textfield',
'#title' => 'Some other fieldname',
'#default_value' => $default_fieldname2
);
}
The cookies(s) will be presented on each page load after they are set, so it doesn't matter if there are several failed login attempts or other page views in between. You should probably delete the cookies after they're used or set a short expiration time so that they are cleaned up automatically.
I don't know if there is a good way to transfer form data from two entirely different forms in Drupal, especially in the context of access denied. The best choices I can find would be to:
Use the url to send the data for the field.
You could also save the data in the db, but it might be a bit tricky to extract the data again.

Resources