Using arrays with the Calendar class in CodeIgniter - php

I'm trying to create a rather complex array for my calendar application. It's supposed to contain dates, with the name of the day, the 'type' and the events, if any. I got as far as creating this:
[dates] {
[22] {
[day] => [Friday]
[type] => [weekday]
}
[23] {
[day] => [Saturday]
[type] => [Weekend]
}
[24] {
[day] => [Sunday]
[type] => [Weekend]
}
}
Now I would like to add another key called 'events'. I want to add the events for each day to the array.. So I could get something like:
[24] {
[day] => [Sunday]
[type] => [Weekend]
[events] {
[1] {
[title] => [test event]
[description] => [my event]
[date] => [24-04-2011]
}
[2] {
[title] => [test event 2]
[description] => [my second event]
[date] => [24-04-2011]
}
}
Not sure if this makes sense.
I created the first example using this code:
for($i = 1; $i <= $data['days_in_curr_month']; $i++)
{
$day_info = $this->get_day_info($i, $data['current_month'], $data['current_year']);
$dates[$i]['name'] = $day_info['day_name'];
$dates[$i]['type'] = $day_info['day_type'];
}
return $dates;
I then wanted to grab the event info by doing:
$event_info = $this->get_event_info($i, $data['current_month'], $data['current_year']);
in the same for loop.
My get_event_info method looks like this:
public function get_event_info($day, $month, $year)
{
$date = $year . "-" . $month . "-" . $day;
$this->db->where('date', $date);
$this->db->where('user_id', '1');
$query = $this->db->get('tblEvents');
$event_info = array();
foreach($query->result() as $row)
{
$event_info['events'][$row->id]['title'] = $row->title;
$event_info['events'][$row->id]['description'] = $row->description;
}
return $event_info;
}
It outputs arrays like this:
Array ( [events] => Array ( [1] => Array ( [title] => Project 2 [description] => Test: Project 2 ) [2] => Array ( [title] => Illustrator [description] => Test: Illustrator 2 ) ) )
Now, I return the $event_info from get_events_info to the create_dates_list method, but I'm not sure how I would go about adding my event arrays to the $dates array.
The get_event_info gets the events for each date (1 - end of month-). I then want to add those to my $dates array in the format listed above in my second example.
I'm confused cause these are rather complex arrays. Thanks in advance.

I think all you need to do is (for example):
$append_events = get_event_info($day, $month, $year);
$array['dates']['1']['event'] = $append_events['events'];
Then you can access your elements:
$array['dates']['1']['event'][$id]['title']
$array['dates']['1']['event'][$id]['description']

Related

Filter multidimensional array and push in new one

I am trying to build a class schedule that takes a .csv with data for the whole semester. I have this multidimensional array, which contains the date, class, instructor, room, and notes for every day of the semester:
Array (
Array (
[0] => 1
[1] => 2019-04-02
[2] => Study Skills
[3] => 371
[4] => Mr Teacher
[5] => 0
[6] =>
)
Array ( ... )
...)
I managed to display the schedule for the whole semester in one table. However, ideally, I would filter out the data for each month and then push in into a new multidimensional array for the whole semester.
I was able to filter out individual months by comparing it a to hardcoded string but I obviously don't want to do that for the whole semester:
$may = "05";
$classMay = [];
foreach ($days as $day){
if (strrpos($day[1], $may, -5)){
array_push($classMay, $day);
}
};
Is there a more efficient solution to this?
Any insight is much appreciated!
Just get the month name from the date of each one and append the day data onto an array indexed by the month:
foreach($days as $day) {
$month = date('F', strtotime($day[1]));
$result[$month][] = $day;
}
Now you should have an array that looks similar to this:
Array
(
[January] => Array
(
[0] => Array
(
[0] => 1
[1] => 2019-01-01
//etc
)
[1] => Array
(
[0] => 3
[1] => 2019-01-02
//etc
)
)
[February] => Array
(
[0] => Array
(
[0] => 10
[1] => 2019-02-01
//etc
)
[1] => Array
(
[0] => 30
[1] => 2019-02-02
//etc
)
)
)
For fun you could loop 12 months and filter on the month:
foreach(range(1, 12) as $m) {
$month = date('F', strtotime($m));
$result[$month] = array_filter($days, function($v) use($month) {
return $month == date('F', strtotime($v[1]));
});
}

How can i filter a multidimensional array into another one in PHP?

probably this question is duplicate because I don't know how to describe the problem to find an answer.
I've got an array with 3 parameters: date, events and tags.
A date contains a unix timestamp,
An events is an arrya that contain events' id,
Tags is an array that contain events' tags (comma-separated string if the number is not alone).
This is the array:
Array
(
[date] => 1554328800
[events] => Array
(
[0] => 130
[1] => 131
[2] => 163
)
[tags] => Array
(
[0] => 4
[1] => "1,3,4"
[2] => "1,3"
)
)
The relationship between events and tags is in the key, so the event 130 that has position 0 has tag 4.
As you can see there are some tags repeated (events 130 and 131 or 131 and 163).
How could I get an array with only repeated events like this:
Array
(
[0] => Array
(
[date] => 1554328800
[events] => Array
(
[0] => 130
[1] => 131
)
[tags] => 4
)
[1] => Array
(
[date] => 1554328800
[events] => Array
(
[0] => 131
[1] => 163
)
[tags] => Array
(
[0] => 1
[1] => 3
)
)
)
Here is how I would do it:
List the events per individual tag
This will give several sets of events, which can be used in the next step
List the tags per set of events that occurred in previous step
Produce the result from step 2
Here is the code, also runnable at 3v4l.org:
// Sample input
$data = [
"date" => 1554328800,
"events" => [130, 131, 163],
"tags" => [4, "1,3,4", "1,3"]
];
// 1. List the events per individual tag
foreach($data["tags"] as $i => $val) {
$vals = explode(",", $val);
foreach($vals as $val) {
$eventsByTag[$val][] = $data["events"][$i];
}
}
// 2. List the tags per set of events
foreach($eventsByTag as $tag => $events) {
sort($events, SORT_NUMERIC);
$tagsByEvents[implode(",", $events)][] = $tag;
}
// 3. produce the result
foreach($tagsByEvents as $events => $tags) {
$events = explode(",", $events);
if (count($tags) == 1) $tags = $tags[0];
$result[] = [
"date" => $data["date"],
"events" => $events,
"tags" => $tags
];
}
print_r($result);
$date = array();
$date['date'] = 1554328800;
$date['events'] = array(130, 131, 163);
$date['tags'] = array(4, "1,3,4", "1,3");
$events_by_tag = array(); //gather events grouped by tag
foreach ($date['events'] as $pos => $event) { //parse all events
if (is_string($date['tags'][$pos])) { //if tag is a string <=> if there are more than one tag for the current event
$tags = explode(',', $date['tags'][$pos]); //explode string to loop over the tags
foreach ($tags as $tag) {
if (is_array($events_by_tag[$tag])) { //if tag has already been found and then an array exists to store it
array_push($events_by_tag[$tag], $event);
} else {
$events_by_tag[$tag] = array($event); //else create an array for the next times this tag will be found and store it inside
}
}
} else { //if there's a single tag which is a integer
if (is_array($events_by_tag[$tag])) { //if tag has already been found and then an array exists to store it
array_push($events_by_tag[$date['tags'][$pos]], $event);
} else {
$events_by_tag[$date['tags'][$pos]] = array($event); //else create an array for the next times this tag will be found and store it inside
}
}
}
$result_array = array(); //final array reorganized + date
foreach ($events_by_tag as $tag => $events) {
$tmp_array['date'] = $date['date'];
$tmp_array['events'] = $events;
$tmp_array['tags'] = $tag;
array_push($result_array, $tmp_array);
}
This is NOT exactly what you expected because it will not merge events sharing tags. I think this part needs another post to be developed, but otherwise I can modify my answer to give you the way to go if necessary.
pl check this
$sarr=['date'=>1554328800,
'events'=>
[
130,
131,
163
],
'tags'=>
[
4,
"1,3,4",
"1,3"
]
];
$tagarr=[];
$events=$sarr['events'];
$index=0;
foreach( $sarr['tags'] as $tag)
{
$t=explode(",",$tag);
$cnt=count($t);
for($idx=0;$idx<$cnt;$idx++)
$tagarr[$t[$idx]][]=$events[$index];
$index++;
}
$cnt=count($tagarr);
$myarr=[];
foreach($tagarr as $key=>$value)
{
$myarr[]=['date'=>$sarr['date'],'events'=>$value,'tags'=>$key];
}
ec ho "<pre>";
print_r($myarr);
echo "</pre>";
output is
Array
(
[0] => Array
(
[date] => 1554328800
[events] => Array
(
[0] => 130
[1] => 131
)
[tags] => 4
)
[1] => Array
(
[date] => 1554328800
[events] => Array
(
[0] => 131
[1] => 163
)
[tags] => 1
)
[2] => Array
(
[date] => 1554328800
[events] => Array
(
[0] => 131
[1] => 163
)
[tags] => 3
)
)

Create an Array for each date and populate each array according to matching dates

currently I am creating a travel application.
I have connected API's together with google maps, where the user can "Add a place / hotel to their itinerary which is then stored on a database.
I want to be able to create an array with every place/hotel/flight on a specific date so that I can output a calendar for the user to show them what they are doing each day.
So far I have;
$eachDay = array(); $i = 0; $j = 0;
foreach ($array as $entriesRow) {
$i++;
$eachDay[$i]['date'] = $entriesRow;
if ($result2->num_rows > 0) {
while ($row2 = $result2->fetch_assoc()) {
if ($eachDay[$i]['date'] == $row2['dateGoing']) {
$j++;
$eachDay[$i]['title'][$j] = $row2['title'];
}
}
}
and the return I get is
Array ( [date] => 2017-03-21 [title] => Array ( [1] => Sydney Harbour Bridge [2] => World Tower ) ) Array ( [date] => 2017-03-22 ) Array ( [date] => 2017-03-23 ) Array ( [date] => 2017-03-24 ) Array ( [date] => 2017-03-25 ) Array ( [date] => 2017-03-26 ) Array ( [date] => 2017-03-27 ) Array ( [date] => 2017-03-28 ) Array ( [date] => 2017-03-29 ) Array ( [date] => 2017-03-30 )
This is fine for the first day but it doesn't seem to loop through the other days like the 2017-03-22, it just displays the date. I have data for each of the other days.
I'm defiently missing something, like another loop or something else, but i'm just not sure!
Thank you in advance, sorry if it is not explained very well.
Got it,
foreach ($array as $entriesRow) {
$i++;
$eachDay[$i]['date'] = $entriesRow;
$j = 0;
foreach ($places as $v) {
if($eachDay[$i]['date'] == $v['dateGoing']){
$eachDay[$i]['title'][$j] = $v['title'];
$j++;
}
}

Adding Elements To An StdClass Array - PHP / Codeigniter

I have an array that is an stdClass. The output of that array is as follows :
Array
(
[0] => stdClass Object
(
[vendor_id] => 1
[user_id] => 1
[date_created] => 2013-06-12 16:48:38
[date_edited] =>
[status] => active
[user_firstname] => Stuart
[user_surname] => Blackett
)
)
What I would like to do is add two variables to this stdClass. They are "total_bookings" and "total_venues";
I currently am looping through the results and then getting a count to create the total. I would like to add those two vars to the end of that stdClass array.
My PHP is as follows :
$vendors = $this->po_model->get_all_vendors();
$this->template->set('total_vendors', count($vendors));
$count = 0;
foreach($vendors as $vendor)
{
$count++;
$total_venues = $this->po_model->get_count_venues($vendor->user_id);
$total_bookings = $this->po_model->get_count_bookings($vendor->user_id);
$vendors[$count]['total_venues'] = $total_venues;
$vendors[$count]['total_bookings'] = $total_bookings;
}
However, When I var_dump that my Array looks like this :
Array
(
[0] => stdClass Object
(
[vendor_id] => 1
[user_id] => 1
[date_created] => 2013-06-12 16:48:38
[date_edited] =>
[status] => active
[user_firstname] => Stuart
[user_surname] => Blackett
)
[1] => Array
(
[total_venues] => 6
[total_bookings] => 14
)
)
So my question is, How do I add total_venues and total_bookings to that stdClass()?
Thanks
$myArray[$indexOfObject]->total_venues = 6;
$myArray[$indexOfObject]->total_bookings= 14;
Your example:
foreach($vendors as $key => $vendor)
{
$total_venues = $this->po_model->get_count_venues($vendor->user_id);
$total_bookings = $this->po_model->get_count_bookings($vendor->user_id);
$vendors[$key]->total_venues = $total_venues;
$vendors[$key]->total_bookings = $total_bookings;
}
its an object, you should use object notations, not array notations. also change your move your count++ below these two instructions
$vendors[$count]->total_venues = $total_venues;
$vendors[$count]->total_bookings = $total_bookings;
$count++;

Combination of arrays

I have tried to get the below code to work for a good couple of hours, but just don't succeed.
I have this date array:
Array ( [0] => Array ( [0] => 2007 )
[1] => Array ( [0] => 2008 )
[2] => Array ( [0] => 2009 )
...
)
and this plusMinus one:
Array ( [0] => Array ( [plus] => 2 [date] => 2007 )
[1] => Array ( [minus] => 1 [date] => 2008 )
[2] => Array ( [minus] => 1 [date] => )
[3] => Array ( [plus] => 1 [date] => 2010 [minus] => 1 )
)
I have been trying to combine them into this:
Array ( [0] => Array ( [date] => 2007 [plus]=> 2)
[1] => Array ( [date] => 2008 [minus]=> 1)
[2] => Array ( [date] => 2009 [plusMinus]=> 0)
[3] => Array ( [date] => 2010 [plus] => 1 [minus]=>1 )
...
)
So basically I want to check if a value of the date array exists in the plusMinus array. If true the date and values from the plusMinus array shall replace the entry in the date array.
If false, the original date array entry is complemented by a [plusMinus] => 0 key-value pair.
The way I have tried to do it is this:
foreach ($filler as $key1 => $value1)
{
foreach ($plusMinus as $key2 => $value2)
{
if ($value1['0'] !== $value2['date'])
{
$value1['plusMinus'] = '0';
$result2[$key1][] = $value1;
}
elseif ($value1['0'] == $value2['date'])
{
if (array_key_exists('plus',$value2))
{
$value1['plus'] = $value2['plus'];
$result2[$key1][]=$value1;
}
elseif(array_key_exists('minus',$value2))
{
$value1['minus'] = $value2['minus'];
$result2[$key1][]=$value1;
}
elseif(array_key_exists('minus',$value2) &&
array_key_exists('plus',$value2))
{
}
}
}
}
$valuesComplete = array();
foreach ($result2 as $value) {
$result2 = $value['0'];
array_push($valuesIncomplete, $result2);
}
return $valuesComplete;
Instead of the desired outcome described above I get this:
Array ( [0] => Array
( [0] => 2007 [plus] => 2 )
[1] => Array ( [0] => 2008 [plusMinus => 0 )
[2] => Array ( [0] => 2009 [plusMinus] => 0 )
[3] => Array ( [0] => 2010 [plusMinus] => 0 )
[4] => Array ( [0] => 2011 [plusMinus] => 0 )
[5] => Array ( [0] => 2012 [plusMinus] => 0 )
[6] => Array ( [0] => 2013 [plusMinus] => 0 )
)
What am I missing? Thanks for any help!
Unfortunately, because of the input data format, I can't see any way to do this that doesn't involve an O(n + m + p) operation. But no matter, you gotta do what you gotta do.
Firstly I would start by filtering the useless elements from the PlusMinus array. Since it's already fairly close to the desired output format, it makes sense to use this as the base of the result.
$temp = array();
foreach ($plusMinus as $item) {
if (!empty($item['date'])) {
$temp[$item['date']] = $item;
}
}
Notice that I used the date as the index of the temporary array we're using to build the result. This is to allow you to easily ensure that the result array is in the correct order, and to quickly check whether an item needs to be added from the Filler array.
Next, we need to add any missing elements from the Filler array:
foreach ($filler as $item) {
if (!isset($temp[$item[0]])) {
$temp[$item[0]] = array(
'date' => $item[0],
'plusMinus' => 0
);
}
}
Now all the data is in the array in the correct format, we just need to sort it:
ksort($temp);
...and get convert it back to an indexed array:
return array_values($temp);
No need for the performance killing nested loops or complex flow control.
See it working
As I understood you need to add years that not in second array but in first?
In that case you can do:
foreach ($filler as $key1 => $value1)
{
$ok = false;
foreach ($plusMinus as $key2 => $value2)
{
if($value2['date']==$value1[0])
{
$ok = true;
break;
}
}
if(!$ok)
{
$plusMinus[$value1[0]]=array('date'=>$value1[0], 'plusMinus'=>0);
}
}
<?php
$a1 = array(array( 2007 ),
array( 2008 )
);
$a2 = array(array('plus'=>1, 'date'=>2007),
array('minus'=>1,'date'=>2008),
array('plus'=>1, 'minus'=>1, 'date'=>2008)
);
$r = array();
foreach($a1 as $k1=>$d1) {
$year = $d1[0];
foreach( $a2 as $k2=>$d2 ) {
if( $d2['date'] == $year ) {
$r[$year]['date'] = $year;
if(isset($d2['plus'])) {
$r[$year]['plus'] = $d2['plus'];
}
if(isset($d2['minus'])) {
$r[$year]['minus'] = $d2['minus'];
}
}
}
}
print_r($r);
and result
Array
(
[2007] => Array
(
[date] => 2007
[plus] => 1
)
[2008] => Array
(
[date] => 2008
[minus] => 1
[plus] => 1
)
)
$ar1 = array( array(2007), array(2008), array(2009), array(2010) );
$ar2 = array(
array("date"=>2007, "plus"=>2),
array("date"=>2008, "minus"=>1),
array("date"=>"", "minus"=>1),
array("date"=>2010, "plus"=>1, "minus"=>1)
);
foreach($ar2 as $key=>$val){
if(isset($ar1[$key][0]))
$val["date"] = $ar1[$key][0];
$ar2[$key] = $val;
}
I am not sure if I understand you correctly but this works fine...
It will work only if you are sure that your both arrays "date" equals one to other..
This is what I came up with:
To not create the product of both arrays (foreach inside foreach), I first index the $plusMinus array with the date. That will allow to test quickly if a year exists or not:
$years = array_combine(array_column($plusMinus, 'date'), $plusMinus);
This uses the array_column() function of PHP 5.5, if you don't have it you can easily create it your own.
After doing that it is exactly how you wrote it in your own words:
foreach($date as &$entry)
{
list($year) = $entry;
$entry = array('date' => $year);
// check if a value of the date array exists in the plusMinus array.
if (isset($years[$year])) {
// If true the date and values from the plusMinus array shall replace the entry in the date array
$entry += $years[$year];
} else {
// If false, the original date array entry is complemented by a [plusMinus] => 0 key-value pair.
$entry += array('plusMinus' => 0);
}
}
unset($entry);
See it i action.
This will work just fine.
I did not at all understand your question, but if i got it this is the way:
First make your $datearray more understandable like this:
$dateArray = array(2007,2008,2009,2010);
$plusMinus = array(
array( 'plus' => 2 ,'date' => 2007),
array( 'minus' => 1 ,'date' => 2008),
array ( 'minus' => 1 , 'date' => '' ),
array ( 'plus' => 1 , 'date' => 2010 , 'minus' => 1 )
);
You can make it multidimensional later;
After that:
foreach($dateArray as $k=>$v)
{
if(in_array($v,$plusMinus[$k]))
{
$filler[$k] = $plusMinus[$k];
}
else{
if(empty($plusMinus[$k]['date']))
{
$filler[$k]['date']= $v;
$filler[$k]['plusMinus'] = 0;
}
}
}
This is simple and clean, understandable way with very little code if your arrays will always have the structure you described, meaning the plusMinus values for 2007 are in the cell [0] and the 2007 in the dateArrays is also in the cell [0] like you have shown. I hope i could help.

Categories