Programatically extending an array with sub arrays - php

I have a working array as follows
"content" => array
(
array //sub array for image 1
(
'url' => $uploadspath.$media_url0,//main image
"type" =>$type0,//media type
"caption"=>$caption0
),
array //sub array for image 2
(
'url' => $uploadspath.$media_url1,//main image
"type" =>$type1,//media type
"caption"=>$caption1
),
array //sub array for image 3
(
'url' => $uploadspath.$media_url2,//main image
"type" =>$type2,//media type
"caption"=>$caption2
),
....Programatically add new sub arrays here subject to the existence of $media_url(4,5,6 etc)..
);
I am getting the $media_url and other data from database. I would like too programatically extend the array by adding additional sub arrays and associated URL/type/caption elements IF there is a value for $media_url4; $media_url5; $media_url6; $media_url7; etc. etc. (Max 10 images)
My problem is how to code the extension of my array with additional sub-arrays based purely on the existence of additional media_urls. Simplistically I would like to be able to do something along the following lines but I don't know how to implement it within a nested array structure...
if ($media_url4) {code to add sub array/element for image 4}
if ($media_url5) {code to add sub array/elementsfor image 5}
etc...
Thank you for any assistance.

//Below we have a function or pdo function that return the new values from database that you want to put in the CONTENT MASTER ARRAY, NOW we put the values in a variable $rows
$rows = functionThatReturnNewValuesToPutInContentArray();
//The foreach looping the variable rows, getting each row in database and putting this in a variable $row
foreach($rows as $row){
//If the $row object data from database contains media_url value add new subarray to masterContentArray
if($row->media_url != ''){
$newSubArray = [
//$row->media_url, is considering that you have a column in your db named by media_url, and that contains url string
'url'=>$row->uploadsPath . $row->media_url,
'type'=>$row->type,
'caption'=>$row->caption,
];
array_push($masterContentArray['content'], $newSubArray);
}
}
return json_encode($content);

Related

Store array response as object inside array for options

I would like to been appending objects to instagram value instead of overwriting them if there is a new object that isn't repeated.
So I have this piece of code:
if (is_array($api_return)) {
$api_return += ['last_updated' => time()];
$this->instagram->set_user_id($api_return['user_id']);
$this->instagram->set_username($api_return['username']);
$this->instagram->set_access_token($api_return['access_token']);
$this->instagram->set_access_token_expiration($api_return['access_token_expiration']);
$this->instagram->set_last_updated($api_return['last_updated']);
// Show our authenticated message.
$page_content .= $this->get_admin_notice_content('green',
'auth-finished', $this->instagram->get_username());
update_option('instagram', $api_return);
}
What this does, is it takes $api_return which is a array and groups it into an object and saves it inside the database as this:
We have option_name which is instagram and then the value is:
a:5:{s:8:"username";s:16:"saint";s:7:"user_id";i:17841404774727369;s:12:"access_token";s:141:"IGQVJVR1N*****";s:23:"access_token_expiration";i:1650688769;s:12:"last_updated";i:1645536110;}
What I'm attempting to do:
Now I want to be able to save multiple object where the instagram key doesn't get overwritten but each new api_return gets stored as a new object if it's not the same in an array.
Here is an example:
authenticated_users = [
{s:8:"username";s:16:"saint";s:7:"user_id";i:17841404774727369;s:12:"access_token";s:141:"IGQVJVR1N*****";s:23:"access_token_expiration";i:1650688769;s:12:"last_updated";i:1645536110;}
{s:8:"username";s:16:"test3";s:7:"user_id";i:17841404774727369;s:12:"access_token";s:141:"IGQVJVR1N*****";s:23:"access_token_expiration";i:1650688769;s:12:"last_updated";i:1645536110;}
];
What is the best approach on storing the option value as an array with multiple objects?
You have to first load the option an then manually merge the values:
$current = get_option("instagram", []);
$newData = [
$api_return,
];
// Merge array $current and $newData into single array so
// $api_return is appended to $current and the option is updated.
update_option("instagram", array_merge($current, $newData));

Fill one array using two loop

I have an object where there are all my articles.
I'm currently looping my object to fill an array where I create an associative table for each article.
In my object I also have a Categories object and I would like to add the label of each category at the end of each associative array previously completed, but
I don't know how to do that.. In the Categories object there may be multiple labels.
My code :
$articles = $this->entityManager->getRepository('SGBundle:Article')->findBy([], ['id'=>'desc']);
$arrayCollection = [];
foreach($articles as $article) {
$arrayCollection[] = [
'id' => $article->getId(),
'date_publication' => $article->getDatePublication(),
...
];
foreach($article->getCategories() as $categorie) {
$arrayCollection[] = ['categorie' => $categorie->getLibelle()];
}
}
On my screenshot, for each article there is an array with 36 values ​​and an array with 1 value and I would like this table to be in the table where there are 36 values. It's possible ?
First gather categories, then add'em to article item:
foreach($articles as $article) {
$categories = [];
foreach($article->getCategories() as $categorie) {
$categories[] = $categorie->getLibelle();
}
$arrayCollection[] = [
'id' => $article->getId(),
'date_publication' => $article->getDatePublication(),
...
//
'categorie' => $categories,
];
}
If the article.categories field is marked as lazy, then it won't be hydrated by default and the $article->getCategories() will perform a new query on each loop round.
Instead of a simple findBy, you might want a custom DQL query in this case to optimize this and get the exact array you want in one single request.
Also note that your current query is fetching all articles of your database. While this is probably your purpose, keep in mind that this could get pretty heavy with the data growing. In most cases, this kind of query should be paginated.

Add mutiple values to one column

We are working on a website based on SilverStripe and this site is connected with a SugarCRM database.
We have created a Form with a CheckboxSet with multiple values and store it a variable called $data['Interessen']
$set_entry_parameters = array(
"session" => $session_id,
"module_name" => "Contacts",
"name_value_list" => array(
array(
"name" => "interessen_c",
"value" => $data['Interessen']['fotografie']
),
array(
"name" => "interessen_c",
"value" => $data['Interessen']['dance']
)
)
);
Now the last array with "interessen_c" overwrites the previous values. We want to add more than one value at one time.
How is this possible?
If the contents of $data['Interessen'] can only have values from a fixed list of possibilities, I'd recommend making the field interessen_c into type multienum ("Multi-Selection Dropdown" field).
For that field create a list of all available items in Sugar (e.g. in Studio or creating the app_list_strings entry manually via code).
Sugar will then support multiple values in this field and display them nicely.
If your program writes the data by communicating with the Sugar REST API you can then just pass the $data['Interessen'] array as the value for interessen_c and Sugar will know what to do with it.
If your program writes the data directly to the interessen_c field in the database, then the field contents must adhere to the following format:
^value1^,^value2^,^value3^
So with ^ around each value and all items being separated by ,
Here an example of how to convert the array values to such a string in PHP:
$interessen = array();
foreach ($data['Interessen'] as $value) {
// add value surrounded by ^ to array
$interessen[] = "^$value^";
}
// transform values in array to string with items being separated by ,
$interessen = implode(',', $interessen);
Side-Note:
From within Sugar one can use encodeMultienumValue($arr) and unencodeMultienum($string) to convert from array to db-string format and back.
Both functions are defined in include/utils.php

XML Attributes to arrays (PHP)

I have an XML which includes many thousands of nodes with information about them in attributes.
Each node is like :
<Class Option1="fiahfs;if" Option2="fiowfr0r0" ClassID="1">
<Class Option1="ro;ewaj;frwajro" Option2="afj;wh;fha" Option3="34014upkla" ClassID="2">
....
I need to parse that info into PHP arrays with array names being attribute names and the number of element in array equal to ClassID Attribute.
The problem is that some nodes have attributes that other nodes I dont have. I previously used ->attributes() for one selected element as
$a => $b,
$$a=array();
then
${$a}[(integer)$products['ClassID']]=$b
Where $products is simplexml element got from parsing XML with xpath. That basically gave me what i needed - i had a few arrays and i could address my requests like $Option1[1] , $Option2[1], Option1[2]...etc.
But the problem is that if I create that structure using only attribute list of one selected element -there`ll be elements that that one element do not have,but other have, and after a create arrays and then parse XML -there'll not be some arrays. Like if i create arrays from [0] of that example, that will give me $Option1, $Option2, but no $Option3.
When I rebuilt my code to :
foreach ($XML->xpath('/idspace/Class') as $products){
foreach($products->attributes() as $a => $b){
if(!isset($$a) $$a=array();
${$a}[(integer)$products['ClassID']]=$b;
}}
And after that I tried to foreach($ClassID) - I`ve got only one element in that array.
How can I parse every XML attribute to array while using attribute "ClassID" as element number in array?
I'm quite confused with your arrays. For me it sounds strange to have an extra array for each attribute. Why not make one array that contains each element and have the attributes as children. So that in the end you get an array like this:
$products = array(
[1] => array(
[Option1] => "fiahfs;if",
[Option2] => "fiowfr0r0",
),
[2] => array(
[Option1] => "ro;ewaj;frwajro",
[Option2] => "afj;wh;fha",
[Option3] => "34014upkla",
),
In this way you can easily access all the attributes for a given ChildId:
$products[$childId]['Option1'] - or better check if the Attribute-Name exists.
You can use simplexml->attributes()
$products = array(); // products will have the result!
foreach ($xml->products as $productXml) { // don't know your xml structure here,
// but you need to iterate over every product in the xml
$singleProduct = array();
$classId = 0;
foreach($productXml->attributes() as $a => $b) {
if ($a == 'ClassID') {
$classId = $b;
} else {
$singleProduct[$a] = $b;
}
}
$products[$classId] = $singleProduct;
}

PHP: Session 2-Dimensional Array - Track Viewed Products

I'm trying to create an array to display the last 5 products a customer has viewed.
The array is a 2 dimensional array like below...
$RView= array(
array( ID => "1001", RefCode => "Ref_01", Name => "Name_01" ),
...
array( ID => "1005", RefCode => "Ref_05", Name => "Name_05" )
);
The array values are retrieved from the products recordset and is designed to function as follows when a customer visits a product page.
Page will check if a Session Array exists
If yes, an array variable is created from existing Session
If no, a new array is created.
Array will add the new product details.
Array will count if there are more than 5 existing products in the array.
If yes, it will remove the oldest.
If no, moves to next step.
A Session is created/updated from the revised Array.
My current effort is attached below...
Many thanks for any help.
<?php
session_start()
// Get or Create Array
IF (isset($_SESSION['sessRView'])) {
$RView = ($_SESSION['sessRView']); }
ELSE {
$RView = array(array());
}
// Append currently viewed Product to Array
array(array_unshift($RView, $row_rsPrd['PrdID'], $row_rsPrd['RefCode'], $row_rsPrd['Name']));
// Check if more than 5 products exist in Array, if so delete.
IF (sizeof($RView) > 5) {
array(array_pop($RView)); }
// Update Session for next page
$_SESSION['sessRView'] = $RView;
// Display Array
for ($row = 0; $row < 5; $row++)
{
echo "<ul>";
echo "<li><a href='?PrdID=".$RView[$row]["PrdID"]."'>".$RView[$row]["RefCode"]."</a> : ".$RView[$row]["Name"]."</li>";
echo "</ul>";
}
?>
It's more or less right - just 2 lines need to be changed.
There's no need for the extra array() around array_unshift and array_pop.
When you use array_unshift you're pushing an array of items (not the id/codes individually) - I think you mean array_unshift($RView, array($prodid,$name,...))
What if $RView doesn't have 5 elements? In that case you're accessing undefined array indices (which may or may not show an error). Change it to a foreach loop: e.g.
foreach ($Rview as $prod) echo $prod['Name']...
It should work after you make these changes. You might want to clean up the coding style a bit, though :)
EDIT: Oh, I see, when you're referencing the array in the for loop it doesn't know that the array has "ProdID" and "Name" indices. When you make an array you have to define the indexes using the => operator.
Add indexes to the array when you array_unshift:
array_unshift($RView, array("ProdID" => $row_rsProd["ProdID"], "Name"...))
If row_rsProd isn't too big, you can just tack the entire row_rsprod onto $RView.
so change array_unshift(...) to just $RView[] = $row_rsProd
This way the indexes are preserved.
Alternatively you can change the indicies in the for loop to match. Right now the array you unshift onto $RView is 0-based - $RView[0][0] is the product ID for the first product, etc.
So you can change the stuff in the foreach loop to
echo "<li>..." $prod[0] $prod[1] $prod[2]
Hope that helps!

Categories