Problems accessing and updating data within serialized array - php

I was hoping someone might be able to help me out or point me in the right direction. I've spent a week trying to figure out how to access and update the weight field in WP ecommerce and Ive had no success at accessing it and updating new values.
The script I'm using access a website to scrape comic book info. It then parses the data from the xml file and assigns variables for the second is for values that are specific to WP Ecommerce.
The whole script works beautifully and creates product pages for each comic book and all data is added into each product. Except for one! and I've been stuck for a week trying to figure out how to access the meta and update it. That's the _wpsc_product_metadata array for weight and weight_unit and other meta values that are stored within.
A comic weighs roughly 3 ounces and I've been trying to assign this value to each card as it's created "3" and "ounce" - I've been unsuccessful.
I've tried probably over so many different ways from digging into the ecommerce code to looking on the net, reading about multidimensional arrays, serialized arrays and it isn't clicking in my noggin'. Keep in mind I've only been programming in PHP for the past month, and prior to a month ago I knew nothing about code other than when I dabbled in C and C++ 15 years ago. Back then, it was mainly copying existing code and changing the outputs in MUDS (multi-user dungeons) - back when online gaming was text-based, lol.
I assumed I could access WP Ecommerce meta by using:
get_post_meta($post_id, '_wpsc_product_metadata', true); That did not work.
Other methods of accomplishing this I tried:
get_post_meta(get_the_id($post_id), '_wpsc_product_metadata', true); // no success
I tried specific product ids using it like so:
get_the_id(300), or just '300', i've used single quotes double quotes no qoutes, "{}", etc etc etc etc
Now when I've used:
get_post_meta($post_id, ''); //while in the loop
The values for SKU and price are outputted but not what's within _wpsc_product_metadata
Then when i use this:
$product_data['meta'] = array();
$product_data['meta'] = maybe_unserialize(get_post_meta('$post_id', '' ));
This is what I get when I print_r
Array ( [_wpsc_price] => Array ( [0] => Array ( [0] => 19.99 ) )
[_wpsc_sku] => Array ( [0] => Array ( [0] => 978-0-7851-5209-5 ) ) )
So I tried one more thing I went into a specific product and i manually set weight to 5 and I changed the code as follows:
$product_data['meta'] = array();
$product_data['meta'] = maybe_unserialize(get_post_meta( '44317', '' ));
This is the output:
Array ( [_wpsc_stock] => Array ( [0] => Array ( [0] => ) )
[_wpsc_product_metadata] => Array ( [0] => Array ( [0] =>
a:19:{s:25:"wpec_taxes_taxable_amount";s:0:"";s:13:"external_link";s:0:
"";s:18:"external_link_text";s:0:"";s:20:"external_link_target";s:0:"";s:6:
"weight";s:3:"0.3";s:11:"weight_unit";s:5:"pound";s:10:"dimensions";a:6:
{s:6:"height";s:1:"0";s:11:"height_unit";s:2:"in";s:5:"width";s:2:"0
";s:10:"width_unit";s:2:"in";s:6:"length";s:1:"0";s:11:"length_unit";
s:2:"in";}s:8:"shipping";a:{s:5:"local";s:1:"0";s:13:"international";s:1:"0";}
s:14:"merchant_notes";s:0:"";s:8:"engraved";s:1:"0";s:23:
"can_have_uploaded_image";s:1:"0";s:15:"enable_comments";s:0:"";
s:24:"unpublish_when_none_left";s:1:"0";s:11:"no_shipping";s:1:"0";s:16:
"quantity_limited";s:1:"0";s:7:"special";s:1:"0";s:17:"display_weight_as";s:5:
"pound";s:16:"table_rate_price";a:2:{s:8:"quantity";a:0:{}s:11:"table_price";a:0:
{}}s:17:"google_prohibited";s:1:"0";} ) ) [_wpsc_special_price] => Array ( [0] =>
Array ( [0] => 0 ) ) [_edit_last] => Array ( [0] => Array ( [0] => 1 ) )
[_edit_lock] => Array ( [0] => Array ( [0] => 1333358836:1 ) ) [_wpsc_sku] =>
Array ( [0] => Array ( [0] => 978-0-7851-6421-0 ) ) [_wpsc_price] => Array
( [0] => Array ( [0] => 24.99 ) ) [_wpsc_is_donation] => Array ( [0] => Array (
[0] => 0 ) ) [_wpsc_currency] => Array ( [0] => Array ( [0] => a:0:{} ) ) )
I was hoping, no I'm begging that someone might be able to enlighten me and show me how to access and update this data that is stored in _wpsc_product_metadata specifically weight and weight_unit and it would be even better if you do know how, you could show me an example of updating a newly created posts weight to a value and changing the default weight_unit from pounds to ounces.
Here is the code for reference:
<?php
function scraping_comic()
{
$html = file_get_html('http://site-to-strip.com/');
$matches = str_replace (' ', ' ', $article);
foreach($html->find('li.browse_result') as $article)
{
// get comic title
$item['title'] = trim($article->find('h4', 0)->find('span',0)->outertext);
// get comic title url
$item['title_url'] = trim($article->find('h4', 0)->find('a.grid-hidden',0)->href);
// get comic image
$item['image_url'] = trim($article->find('img.main_thumb',0)->src);
// get comic excerpt
$item['excerpt'] = trim($article->find('p.browse_result_description_release', 0)->plaintext);
// get comic sales info
$item['on_sale'] = trim($article->find('.browse_comics_release_dates', 0)->plaintext);
// strip numbers and punctuations
$item['title2'] = trim(preg_replace("/[^A-Za-z-\t\n\s]/","",$article->find('h4',0)->find('span',0)->plaintext));
$item['title3'] = trim(preg_replace("/[^A-Za-z]/","",$article->find('h4',0)->find('span',0)->plaintext));
$ret[] = $item;
}
$html->clear();
unset($html);
return $ret;
}
$ret = scraping_comic();
if ( ! empty($ret))
{
foreach($ret as $v)
{
//download the image
$url = $v['image_url'];
$title = $v['title3'];
$now = time();
$num = date("w");
if ($num == 0)
{ $sub = 6; }
else { $sub = ($num-1); }
$WeekMon = mktime(0, 0, 0, date("m", $now) , date("d", $now)-$sub, date("Y", $now));
$todayh = getdate($WeekMon);
$d = $todayh[mday];
$m = $todayh[mon];
$y = $todayh[year];
$date_stamp = $d.$m.$y;
//scrape inside pages
$scrape = 'http://domain.com';
$comic_details = $v['title_url'];
$comic_details_url = $scrape.$comic_details;
$url2 = file_get_html($comic_details_url);
foreach($url2->find('.comics_detail_lead_left_panel_content') as $the_details);
$matches = str_replace (' ', ' ', $the_details);
{
$item2['image2_url'] = trim($the_details->find('img.frame-img',0)->src);
$item2['full_desc'] = trim($the_details->find('p',0)->plaintext);
$item2['data'] = trim($the_details->find('dl',0)->plaintext);
}
$url2->clear();
unset($url2);
//download medium-sized image
$root2 = ('/home/****/public_html/wp-content/blogs.dir/14/files/comics/' .$title.$date_stamp. '-medium.jpg');
$image2 = $item2['image2_url'];
copy($image2, $root2);
unset($root2);
unset($image2);
//match specific data and assign variables
$string = $item2['data'];
$number = preg_match("/(Comic|Hardcover|Paperback)[^A-Za-z]+/", $string, $fields);
switch ($fields[1])
{
case ('Comic'):
$cat = array(51, 52);
break;
case ('Hardcover'):
$cat = array(85, 52);
break;
case ('Paperback'):
$cat = array(95, 52);
break;
default: "";
}
$number = preg_match("/((January)|(February)|(March)|(April)|(May)|(June)|(July)|(August)|(September)|(October)|(November)|(December))[^A-Za-z0-9,]+[A-Za-z0-9,\s]+/", $string, $fields);
$date = $fields[0];
$number = preg_match("/((UPC)|(ISBN))[^0-9-]+([0-9-]+)/", $string, $fields);
$upc = $fields[4];
$number = preg_match("/((Price))[^0-9.]+([0-9.\s]+)/", $string, $fields);
$price = $fields[3];
$full_desc = $item2['full_desc'];
$maintitle = $v['title'];
$excerpt = $v['excerpt'];
$comic_post = array();
$comic_post['post_title'] = wp_strip_all_tags($maintitle);
$comic_post['post_content'] = wp_strip_all_tags($full_desc);
$comic_post['post_status'] = 'publish';
$comic_post['post_author'] = 1;
$comic_post['post_type'] = 'wpsc-product';
$comic_post['post_category'] = $cat;
$comic_post['comment_status'] = 'closed';
$comic_post['ping_status'] = 'closed';
$comic_post['post_excerpt'] = wp_strip_all_tags($excerpt);
// create comic book
$post_id = wp_insert_post( $comic_post );
// category insertion does not work fixed this by calling wp_set_post_terms
wp_set_post_terms($post_id, $cat, 'wpsc_product_category' );
$wpsc_custom = update_post_meta;
$wpsc_custom($post_id, '_wpsc_price', $price);
$wpsc_custom($post_id, '_wpsc_sku', $upc);
//Gain access to WP Ecommerce meta data and assign new values to weight ***IN PROGRESS***
$product_data['meta'] = array();
$product_data['meta'] = maybe_unserialize(get_post_meta( $post_id, '' ));
//***TESTING***//
echo '<br /> the data <br />';
print_r($product_data['meta']);
//Set featured image for product
$filename = ('comics/' .$title .$date_stamp. '-medium.jpg');
update_post_meta( $post_ID, 'image_thumbnail', $imgloc );
set_featured_image($post_id, $filename);
}
}
else { echo 'Could not scrape site!'; }
?>

With help from a WP E-commerce contributor here's the missing puzzle piece to update weight.
if(!isset($product_data['meta']) || !is_array($product_data['meta'])) {
$product_data['meta'] = array();
}
if(!isset($product_data['meta']['_wpsc_product_metadata'])) {
$product_data['meta']['_wpsc_product_metadata'] =
maybe_unserialize(get_post_meta($post_id, '_wpsc_product_metadata', true));
}
if(!is_array($product_data['meta']['_wpsc_product_metadata'])) {
$product_data['meta']['_wpsc_product_metadata'] = array();
}
$product_data['meta']['_wpsc_product_metadata']['weight_unit'] = 'ounce';
$product_data['meta']['_wpsc_product_metadata']['weight'] = 0.19;
update_post_meta($post_id, '_wpsc_product_metadata', $product_data['meta']['_wpsc_product_metadata']);

for someone that has not programmed for so long and has only recently looked into PHP you do seem to be doing quite well.
Regarding the array. _wpsc_product_metadata appears to be JSON. You should look towards the PHP manual particularly the section related to JSON as linked below.
http://php.net/manual/en/book.json.php
If you use json_decode you will be able to retrieve an object that has the attributes that you require as properties for the object.

Related

php array returning duplicate values

I am trying to loop through each key but i am facing a problem of same value repeating inside for each loop
Please be noted we should keep on same code structure multiple foreach it's requirement i already posted this question here but didn't get solution instead of solution entire new code as answer imposed on me and nobody is actually taking care of it
Here is example of my current code and result (click here)
here is my code so far
<?php
$data2 = array(
'category_name' => '33287*100*prescription*1,32457*1250*lab*1'
);
$result = array('0' => (object)$data2);
foreach ($result as $key => $category) {
$category_name = explode(',', $category->category_name);
}
$newresults=[];
foreach ($category_name as $key) {
$category->category_name = $key;
$newresults[]=$category;
}
$result=$newresults;
$newresults=[];
$category->items_count = 0;
foreach ($result as $key => $value) {
list($sale_key, $sale_value) = explode('*', $value->category_name);
// $category->items_count += count($sale_value);
$newresults[]=$category;
}
$result=$newresults;
i am getting the wrong results like this
Array
(
[0] => stdClass Object
(
[category_name] => 33287*100*prescription*1
)
[1] => stdClass Object
(
[category_name] => 33287*100*prescription*1
)
)
As noted, because you are reusing variable names, and also using them when their scope might not be correct or accepted, you are causing some confusion.
The code below brings the bottom loop inside of the top loop, because that's where the context really lives. Creating a temporary loop only adds to the potential confusion. If that doesn't work with the additional logic, more changes will be needed. I also changed a bunch of the variable names to hopefully make things more obvious. See the comments in the code for more details.
$reporting_data = array(
'category_name' => '33287*100*prescription*1,32457*1250*lab*1,32459*1500*lab*1,32460*400*lab*1,32461*600*lab*1,32468*950*lab*1,32470*950*lab*1,33291*2500*lab*1,33292*2500*lab*1,47516*2000*lab*1,49209*0*lab*1,56835*2400*lab*1,56836*2400*lab*1',
'patient' => '28370',
'date' => 1643030497,
'ref' => '371',
);
// Create array of objects
$reporting_data_as_objects[] = (object)$reporting_data;
$results = [];
foreach ($reporting_data_as_objects as &$obj) {
// Setup base data that is shared across all items
$obj->reception_data_sum = 0;
$obj->references_data_sum = 0;
$obj->actual_price = 0;
$category_names = explode(',', $obj->category_name);
// Loop over the comma-delimited parts of category_name
foreach ($category_names as $category_name) {
// Clone our template object
$tmp = clone $obj;
// The second item of the asterisk-delimted field is the price
// We used $_ to indicate that we aren't interested in the first item.
list($_, $sale_value) = explode('*', $category_name);
// Set object-specific fields on our clone
$tmp->category_name = $category_name;
$tmp->actual_price = (int)$sale_value;
// Add the clone to the array
$results[] = $tmp;
}
}
// Always unset by-ref variables of a foreach
unset($obj);
print_r($results);
Demo here: https://3v4l.org/95KAQ

Exclude the first result from an Array

I am currently messing around with iTunes Api and have ran into a problem with the returning process of albums track list returning the first result as the actual album data instead of the tracklist.
$loop['artist_name'] = $counted[$x]->artistName;
$loop['album_id'] = $counted[$x]->collectionId;
$loop['album_name'] = $counted[$x]->collectionName;
$loop['track_number'] = $counted[$x]->trackCount;
$loop['artwork_url'] = $counted[$x]->artworkUrl100;
$loop['copyright'] = $counted[$x]->copyright;
$loop['genre'] = $counted[$x]->primaryGenreName;
$loop['release_date'] = $counted[$x]->releaseDate;
$data_b = file_get_contents('https://itunes.apple.com/lookup?id='.$loop['album_id'].'&entity=song');
$response_ab = json_decode($data_b);
print '<pre>';
print_r($response_ab);
print '</pre>';
The above portion for print_r returns the following data.
[results] => Array
(
[0] => stdClass Object
(
[wrapperType] => collection
)
[1] => stdClass Object
(
[wrapperType] => track
)
Then continues onward down the track list, how can I remove the first [0] option from my loop? It appears this only returns the album name anyway when I am trying to get the tracklist.
I didn't test the below code however it should work.
$data_b = file_get_contents('https://itunes.apple.com/lookup?id='.$loop['album_id'].'&entity=song');
$response_ab = json_decode($data_b);
$count = $response_ab->results;
$arr = count($count);
for($a = 1; $a < $arr; $a++) {
// do some cool stuff here
}

New array from multidimensional array - url parsing

I have the following URL: myexample.com/?city=Miami
and a large array (23k)
$e = $_GET["city"];
$myArray = array
(
array ("Miami","Florida"),
array ("Key West","Florida"),
array ("NOLA", "Luisiana"),
array ("Baton Rouge","Luisiana")
);
I'm looking for a solution to dynamically create a new array of cities that matches the state of the city in the URL, and echo all the cities from that state.
In other words:
if myexample.com/?city=NOLA, I would like to echo "Baton Rouge" and "NOLA" (from Luisiana)
if myexample.com/?city=Miami, echo "Key West" and "Miami" (from Florida)
etc.
There are quite a few similar questions answered already (here, here, but looping is not one of strengths (beginner).
Thank you.
EDIT1:
$resArray = array();
foreach($myArray as $arr) {
if(in_array($e, $arr))
$resArray[] = $arr;
}
print_r($resArray);
Result: Array ( [0] => Array ( [0] => Miami [1] => Florida ) )
First of all I would restructure your myArray in something like the following:
$stateAndCities = [
"Florida" => ["Miami","Key West"],
"Luisiana" => ["NOLA", "Baton Rouge"]
];
after that you can better handle the input and give an easier output
$city = $_GET["city"];
$resultCities = [];
$resultState = "";
// Loop over all states with their cities
foreach($stateAndCities as $state => $cities) {
if(in_array($city, $cities)){ // if the given $city is in the $cities?
$resultCities = $cities;
$resultState = $state;
break;
}
}
if(!empty($resultState) && !empty($resultCities)){ // ensure that the city was found in any state
echo $resultState;
print_r($resultCities);
}
(the code is not tested!)
Manual:
http://php.net/in_array
http://php.net/empty

Add/Change Array to/in existing PHP $_SESSION

I got following array in my PHP $_SESSION
[CART] => SHOPPINGCART OBJECT
(
[CONTENTS] => ARRAY
(
[121] => ARRAY
(
[QTY] => 1
)
I know how to change some simple $_SESSION variable, but what if there is an array in array and then there is the value I want to change? Or what if i wanted to add a new Array to [CONTENTS]? Sadly i couldn't find a solution on here.
Your $_SESSION array actually contains an OBJECT which contains and ARRAY which contains an ARRAY
So using normal notation to access QTY for example you would do
echo $_SESSION['CART']->CONTENTS[121]['QTY'];
Or changing the QTY
$_SESSION['CART']->CONTENTS[121]['QTY'] = 10;
Adding a new array to CONTENTS would be
$_SESSION['CART']->CONTENTS[] = array('QTY' => 2);
Then viewing all the CONTENTS array you could do
foreach ( $_SESSION['CART']->CONTENTS as $id => $content ) {
echo "$id\n"
foreach ( $content as $qty ) {
echo " $qty\n";
}
}
One could use a combination of serialize()/unserialize().
To store it in a session:
$cart= new SHOPPINGCART();
$_SESSION['cart'] = serialize($cart);
To actually change values from it:
$cart = unserialize($_SESSION['cart']);
// do anything with cart and store it afterwards with the code above
$cart["quantity"] += 1; // increment it by one
$_SESSION['cart'] = serialize($cart);
$temp = $_SESSION['CART'];
$temp->CONTENTS['121']['QTY'] = 5;
$_SESSION['CART'] = $temp;
Check if this works; then we can think of a way for specifying "121".

Arrays inside array to hold filenames

This is for the front page of a website, which is supposed to display the newest/latest post at the very top, as you scroll down and goto the next pages, the posts get older.
There is a folder the contains lots of ini files with only numbers in the names. What i'm trying to do is load all the posts names (and only names - not their contents) into an array then sort those out to other arrays. I thought maybe using a multidimensional array would be a good idea. For example (if im understanding this right), $usePage[1][2] would have the number of the second post on page one. Is even the best way to do this?
Here is the relevant bit of code:
$ppp = 4;
$totalposts = 0;
$posts = array();
foreach (scandir($postsLoc) as $file) {
if (is_file($postsLoc . "/" . $file)) {
$totalposts++;
array_push($posts, $file);
}
}
natsort($posts);
array_values($posts);
$posts = array_reverse($posts);
print_r($posts);
$currPage = -;
$usePage = array(array());
$done = 0;
for ($i = $totalposts; $i != 0; $i--){
if ($done >= $ppp){
//Next page
$currPage++;
$done = 0;
$usePage[$currPage] = array();
}
$done++;
array_push($usePage[$currPage][$done], $i);
}
print_r($usePage);
So far, I've managed to confuse myself.
Thanks for any help in advance!
the below code results in a multi dimenstional $postsInPage array, the first dimension being the page ref, the second being the posts for that page. You should then be able to use this array pull out the relevant posts dependant on your pageId:
Array
(
[1] => Array
(
[0] => .
[1] => ..
[2] => email_20131212_2c7a6.html
[3] => email_20131212_98831.html
)
[2] => Array
(
[0] => errFile_20140110_940ad.txt
[1] => errFile_20140110_2021a.txt
[2] => errFile_20140110_2591c.txt
[3] => errFile_20140110_43280.txt
etc, etc. The code (haven't included the is_file check)
// load all the posts into an array:
$allPosts = array();
foreach (scandir("temp") as $file) {
$allPosts[] = $file;
}
//sort the array (am making an assumption that $file structure will natsort sensibly
natsort($allPosts);
$allPosts = array_values($allPosts);
//split into posts per page.
$ppp = 4;
$pageId = 1;
$totalposts = 1;
$postsInPage = array();
foreach ($allPosts as $post) {
$postsInPage[$pageId][] = $post;
if (($totalposts % $ppp) == 0) { //i.e. 4 per page
$pageId++;
}
$totalposts++;
}

Categories