Creating directories based on array values - php

I get a response from an API call that looks like the following
Array
(
[_id] => aasdasdasdasdasd
[created] => 2017-01-16T14:11:54.616Z
[options] => Array
(
[title] => 1
[data] => Array
(
[0] => Array
(
[labelName] => Date
[labelValues] => Array
(
[0] => March 2016
)
)
[1] => Array
(
[labelName] => Title
[labelValues] => Array
(
[0] => Food
)
)
[2] => Array
(
[labelName] => Product
[labelValues] => Array
(
[0] => Rice
)
)
)
)
)
I then process the response by doing the following
$results = array();
foreach ($output['options']['data'] as $data) {
if (isset($data['labelValues'][0])) {
$results[$data['labelName']] = $data['labelValues'][0];
}
}
This leaves me with something along the lines of this
Array
(
[Date] => March 2016
[Title] => Food
[Product] => Rice
)
Putting it into an array was not my intention, it was mainly done to help me better understand the looping required to process the original data.
My main intention is to create directories from these values. The main directory will be the Date, within this should be the Title and within this should be Product. So for the above, the directory structure should be something like 2016 > Food > Rice.
In order to achieve this, I have come up with the following
foreach ($output['options']['data'] as $data) {
if (isset($data['labelValues'][0])) {
if($data['labelName'] == 'Date') {
if (preg_match('/\b\d{4}\b/', $data['labelValues'][0], $matches)) {
$results[$data['labelName']] = $matches[0];
if (!file_exists($matches[0])) {
mkdir($matches[0], 0777, true);
}
}
}
}
}
The above works well and creates the date folder for me. Where I am struggling is how I now create the Title folder within the Date folder, and then the Product within the Title.
How would I go about achieving this?
Many thanks

I like your created array:
$array = array
(
[Date] => March 2016
[Title] => Food
[Product] => Rice
)
Simply implode the path:
mkdir(implode('/', $array), 0777, true);
This will create all of the directories, March 2016/Food/Rice

Related

Printing out an array bit of a different way

I've been struggling quite a bit with this. I have a folder with a list of files and a basic naming order - abc-def-xyz.php
I'm trying to create an index page to list all of the files automatically in groups. So:
abc-def-xyz.php
abc-def-xzz.php
abb-def-xyz.php
Would show in the php index page as:
abc
def
xyz
xzz
abb
def
xyz
I can get to the point of exploding the file names and removing the extension, then i'm just lost. Any advice would be much appreciated. Thank you!
Array
(
[0] => Array (this is applyOnline-alert-warning.php)
(
[0] => applyOnline
[1] => alert
[2] => warning
)
[1] => Array
(
[0] => applyOnline
[1] => collectionOrDelivery
)
)
Using the methodology from this answer How to write getter/setter to access multi-level array by key names?:
$array = array();
foreach($files as $file) {
$temp = &$array;
foreach(explode('-', $file) as $key) {
$temp =& $temp[pathinfo($key, PATHINFO_FILENAME)];
}
$temp = $file;
}
Yields an array where the key names can be used:
Array
(
[abc] => Array
(
[def] => Array
(
[xyz] => abc-def-xyz.php
[xzz] => abc-def-xzz.php
)
)
[abb] => Array
(
[def] => Array
(
[xyz] => abb-def-xyz.php
)
)
)

PHP Nested foreach with Key

I have been trying to work this out for two days now and am hitting a brick wall. I have a skyscanner array that has flight itineraries where I have the flight
Leg - being Itineraries -> OutboundLegId -
and also the legs which shows the flight number - being
Legs -> FlightNumbers -> FlightNumber.
What I am trying to achieve is to display the Itinerary and then join the Flight Number on to that. But no matter what I try I cannot get this to work. I have read all about Keys on here and tried loads of examples but am coming up with nothing. Can someone point me in the right direction please?
Example arrays below
[Itineraries] => Array
(
[0] => Array
(
[OutboundLegId] => 13542-1610140610-29-0-13445-1610141240
[InboundLegId] => 13445-1610211340-29-0-13542-1610211640
[PricingOptions] => Array
(
[0] => Array
(
[Agents] => Array
(
[0] => 2174187
)
[QuoteAgeInMinutes] => 31
[Price] => 200.98
[DeeplinkUrl] => http://partners.api.skyscanner.net/apiservices/deeplink/v2?_cje=5JlLCgyPUKY0hT8T0Ybh6dL0Xf0htAiHTFX7RU79eeI3XvrsxvEqP1QUJAoHiHRd&url=http%3a%2f%2fwww.apideeplink.com%2ftransport_deeplink%2f4.0%2fUK%2fen-gb%2fGBP%2fcook%2f2%2f13542.13445.2016-10-14%2c13445.13542.2016-10-21%2fair%2fairli%2fflights%3fitinerary%3dflight%7c-32294%7c1152%7c13542%7c2016-10-14T06%3a10%7c13445%7c2016-10-14T12%3a40%2cflight%7c-32294%7c1153%7c13445%7c2016-10-21T13%3a40%7c13542%7c2016-10-21T16%3a40%26carriers%3d-32294%26passengers%3d1%2c0%2c0%26channel%3ddataapi%26cabin_class%3deconomy%26facilitated%3dfalse%26ticket_price%3d200.98%26is_npt%3dfalse%26is_multipart%3dfalse%26client_id%3dskyscanner_b2b%26request_id%3d3bc96bda-fd7c-403a-b841-2ccc3c26071d%26commercial_filters%3dfalse%26q_datetime_utc%3d2016-09-29T08%3a18%3a27
)
[Legs] => Array
(
[0] => Array
(
[Id] => 13542-1610140610-29-0-13445-1610141240
[SegmentIds] => Array
(
[0] => 1
)
[OriginStation] => 13542
[DestinationStation] => 13445
[Departure] => 2016-10-14T06:10:00
[Arrival] => 2016-10-14T12:40:00
[Duration] => 270
[JourneyMode] => Flight
[Stops] => Array
(
)
[Carriers] => Array
(
[0] => 105
)
[OperatingCarriers] => Array
(
[0] => 105
)
[Directionality] => Outbound
[FlightNumbers] => Array
(
[0] => Array
(
[FlightNumber] => 1152
[CarrierId] => 105
)
)
)
Assuming this is one big array and its called $data you can nest a couple of foreach loops.
I use foreach loops as I assume there are cases where this data structure get more complex than the one you show
foreach ( $data['Itineraries'] as $itin ) {
foreach ( $data['Legs'] as $legs) {
if ($legs['Id'] == $itin['OutboundLegId']) {
// we matched the itinerary with a leg
echo $legs['OutboundLegId'] . ' ' . $legs['FlightNumbers'][0]['FlightNumber'];
}
}
}
Use it as draft. Can't perform function without feedback.
Put proper arrays instead of {YOUR-ARRAY-WITH-LEGS} and {YOUR-ARRAY-WITH-ITINERARIES}
$sortedLegs = array_column('Id', {YOUR-ARRAY-WITH-LEGS});
$joinedArray = array_map(function($itinerary) use($sortedLegs){
if(array_key_exists($itinerary['OutboundLegId'],$sortedLegs)) {
$itinerary['legs'] = $sortedLegs[$itinerary['OutboundLegId']];
}
return $itinerary;
},{YOUR-ARRAY-WITH-ITINERARIES});

PHP - while creating array (mysql_fetch_array) program creating array in array

I want to create array:
$branza_query = mysql_query ('SELECT craft FROM base') or die...
$craft = array();
while ($cra = mysql_fetch_array($craft_query))
{
$craft[] = $cra;
}
No big deal but when i want to print_r it, i have restult like:
Array ( [0] => Array ( [0] => steel [craft] => steel )
[1] => Array ( [0] => farm [craft] => farm )
[2] => Array ( [0] => some [craft] => some )
[3] => Array ( [0] => it [craft] => it ) // etc.
)
I just wanted to add next value to existing array with result like:
Array ( [0] = steel
[1] = farm
[2] = some
[3] = it /etc.
)
or
Array ( [0] = craft => steel
[1] = craft => farm
[2] = craft => some
[3] = craft => it /etc.
)
or something similar because next thing what i want to do is something like:
foreach($craft as $value)
{
echo '<option value ="'.$value.'"> '.$value.'</option>';
}
The Problem is you create an array take $cra as its first element every time you call $craft[]=$cra, and then add it to $craft. That is why you have a three layer array as result.
But actually, $cra is already an array. So what you need to do is just array_push($craft, $cra);. Or use array_push($craft, $cra[0]); this will give what you want.
Please refer to the page http://php.net/manual/en/function.mysql-fetch-array.php

Iterate through multidimensional PHP array and output values

I'm having a real headache trying to iterate through an array and output elements. Using the array structure below I want to be able to output each instance of partname.
The following loop outputs the first instance of partname. I can't seem to adapt it to loop through all instances within the array. I'm sure I'm missing something basic.
foreach($ItemsArray['assignments'] as $item) {
$partname = $item['grades'][0]['partname'];
}
Array
(
[assignments] => Array
(
[0] => Array
(
[assigntmentid] => 5101
[grades] => Array
(
[0] => Array
(
[id] => 5101
[name] => Advanced AutoCad
[partid] => 6601
[partname] => Draft
[userid] => 82069
[grade] => 53
[courseid] => 6265
[fullname] => Computer Aided Design
)
)
)
[1] => Array
(
[assigntmentid] => 5101
[grades] => Array
(
[0] => Array
(
[id] => 5101
[name] => Advanced AutoCad
[partid] => 6602
[partname] => Final
[userid] => 82069
[grade] => 35
[courseid] => 6265
[fullname] => Computer Aided Design
)
)
)
)
)
Instead of just coding by slapping the keyboard. Write down what your function needs to do. In english (or whatever language you prefer). This would be something like:
Foreach assignment, loop over all grades and store the partname of
that grade into an array.
And then code it:
function getPartnames($assignments) {
$partNames = array();
foreach ($assignments as $assignment) {
foreach($assignment['grades'] as $grade) {
$partNames[] = $grade['partname'];
}
}
return $partNames;
}
So what did I do? I simply translated english to code.
Some few more tips: Use variables names that make sense. $item; $ItemArray; ... don't make sense. They tell me nothing
use an extra foreach in your loop:
foreach($ItemsArray['assignments'] as $item) {
foreach($item['grades'] as $grade) {
echo $grade['partname'];
}
}

CakePHP Model Query Return Data Formating

I'm looking for a way to make it so cake returns all database data in the same format/structure... Currently it returns two different types of format depending on the relationship.
If a model 'B' is associated with the current model 'A' being queried it will then place model associations for 'B' underneath it as you can see in [User] below. I want it so that all queries use that structure.
example:
$this->find('all', ....
returns:
Array
(
[0] => Array
(
[UserGroup] => Array
(
[id] => 53
[user_id] => 100003332014851
[media_id] =>
[name] => john
[description] => qwasdfad
)
[User] => Array
(
[id] => 100003332014851
[session_id] => ssm2qbrotmm13ho1ipm8ii2492
[username] =>
[password] => -1
[Planner] => Array
(
)
[Purchase] => Array
(
)
[Listing] => Array
(
)
)
)
I want this to look like:
Array
(
[0] => Array
(
[UserGroup] => Array
(
[id] => 53
[user_id] => 100003332014851
[media_id] =>
[name] => john
[description] => qwasdfad
[User] => Array
(
[id] => 100003332014851
[session_id] => ssm2qbrotmm13ho1ipm8ii2492
[username] =>
[password] => -1
[Planner] => Array
(
)
[Purchase] => Array
(
)
[Listing] => Array
(
)
)
)
)
)
In CakePHP, the find() method return data like your first format. But If you want to format like second one then you have to process it by hand (try to avoid this if possible)
$data = $this->find('all');
$assocs = Set::extract('/User', $data); // extracting all `User` array
foreach($assocs as $key => $assoc) {
unset($data[$key]['User']); // removing the associate `User` from `$data`
$data[$key]['UserGroup']['User'] = $assoc['User']; // adding associate under `UserGroup`
}
ended up doing this... it changes the output to what we need. The top level item does not have a header which is fine I just adjusted our scripts for that... maybe this will help somebody else if they need a custom idea
also no guarantee this covers all possible results but so far it works with all the queries we have.
class AppModel extends Model {
function afterFind($results, $primary) {
//if this is a primary, structure like a secondary so entire site is same format
if ($primary) {
$class = get_class($this);
//simple fix for primary
foreach ($results as $key => $result) {
$result = $this->formatData($result, $class);
$results[$key] = $result;
}
}
return $results;
}
function formatData($result, $class) {
$array = array();
if (isset($result[$class])) {
$array = $result[$class];
unset($result[$class]);
}
$array += $result;
return $array;
}
You can also use contain in this case along with find as UserGroup.User for your desired result

Categories