Wordpress search through meta_value thats an array - php

If i use an array for a meta value can i see if a value is in the array when querying it? I have a website that has events that has dates attached to it as a meta value and i need to see if an event is on a certain date through a search.
$dates[] = 05/02/2016
$dates[] = 06/02/2016
$dates[] = 06/02/2016
update_post_meta($event, 'show_dates', $dates);
if i add this to an event how could i check if the 'show_dates' contains a date searched for? below is what i have tried already
$wp_query->set('post_status', array('publish', 'future'));
$wp_query->set("meta_key", "show_dates");
$wp_query->set("orderby", "meta_value");
$wp_query->set("order", "ASC");
$startDate = parseDatePicker($_GET['StartDate'], new \DateTime());
if (!is_null($startDate)) {
$wp_query->set("meta_query", array(
array(
'key' => "show_dates",
'value' => $startDate->format("d/m/Y"),
'compare' => 'IN'
)
));
}

Ok so it turns out the answer to this was easier than i expected. As Wordpress serializes the data in the array you can use LIKE instead of IN which will check the serialized array to see if it contains that date.
$wp_query->set('post_status', array('publish', 'future'));
$wp_query->set("meta_key", "show_dates");
$wp_query->set("orderby", "meta_value");
$wp_query->set("order", "ASC");
$startDate = parseDatePicker($_GET['StartDate'], new \DateTime());
if (!is_null($startDate)) {
$wp_query->set("meta_query", array(
array(
'key' => "show_dates",
'value' => $startDate->format("d/m/Y"),
'compare' => 'LIKE'
)
));
}
my next problem was how to work with a range I managed to figure this out and have posted below incase nayone else has a similar problem
if (!is_null($startDate) && !is_null($endDate) && ($startDate->format('d/m/Y') != $endDate->format('d/m/Y'))) {
$wp_query->set("relation", "OR");
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($startDate, $interval, $endDate);
$dates[] = $startDate->format('d/m/Y');
foreach($period as $day){
$dates[] = array(
'key' => "next_showing_date",
'value' => $day->format('d/m/Y'),
'compare' => 'LIKE',
);
}
$wp_query->set("meta_query", $dates);
}

Related

Remove dates array between start date and end date in php

I want to find an optimized way to remove dates between start date and end date in php, below how i handle it but seems timeout when there is too many days :
/**
* Get list of dates from start date and end date
* #param {string} start
* #param {string} end
* #param {string} format
* #return array
*/
function _getDatesFromRange($start, $end, $format = 'd/m/Y') {
// Declare an empty array
$array = array();
// Variable that store the date interval
// of period 1 day
$interval = new DateInterval('P1D');
$realEnd = DateTime::createFromFormat('Y-m-d', $end);
$realEnd->add($interval);
$period = new DatePeriod(DateTime::createFromFormat('Y-m-d', $start), $interval, $realEnd);
// Use loop to store date into array
foreach($period as $date) {
$array[] = $date->format($format);
}
// Return the array elements
return $array;
}
/**
* Flat an array
* #param {array} array
* #return array
*/
function _flatten($array) {
$return = array();
array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; });
return $return;
}
// List of dates
$bookings = array(
array(
'bookable' => 'no',
'from' => '2020-08-01',
'to' => '2020-08-05'
),
array(
'bookable' => 'no',
'from' => '2020-08-15',
'to' => '2020-08-18'
),
array(
'bookable' => 'yes',
'from' => '2020-08-01',
'to' => '2020-08-31'
)
);
So to list all dates and get bookable list, i do like this :
foreach($bookings as $booking){
if($booking['bookable'] === 'yes'){
// Get an array of list of dates between start and end
$bookable[] = _getDatesFromRange($booking['from'], $booking['to']);
} else {
$not_bookable[] = _getDatesFromRange($booking['from'], $booking['to']);
}
}
if(is_array($bookable) && is_array($not_bookable)) {
$output = array_diff(_flatten($bookable), _flatten($not_bookable));
print_r($output);
}
You can test all from this url bookable dates demo, i have 2000 products and some products have a large intervals between start and end date like below, and in this case i get timeout execution, so how i can optimise above code ?
$bookings = array(
array(
'bookable' => 'no',
'from' => '2020-08-01',
'to' => '2020-08-05'
),
array(
'bookable' => 'no',
'from' => '2020-08-15',
'to' => '2020-08-18'
),
array(
'bookable' => 'yes',
'from' => '2050-08-01',
'to' => '2050-08-31'
)
);
Thanks for you helps

Google Calendar can´t get ColorId

Anyone know how to get the colorId from google calendar events? I search a lot on web for that and I didn´t find anything that works. I need help.
My code works good but regarding the colorId always receive NULL.
I know we have the $cal->colors->get() method but it's not quite what I want. I want the colors of each the events.
Here is my code:
$client = new Google_Client();
$client->setApplicationName("Ware");
$client->setDeveloperKey('CalendarKey');
$cal = new Google_Service_Calendar($client);
$params = array(
'singleEvents' => true,
'orderBy' => 'startTime'
);
$events = $cal->events->listEvents($calendarId, $params);
$calTimeZone = $events->timeZone;
$events = $cal->events->instances($calendarId, "eventId");
date_default_timezone_set($calTimeZone);
$jsonEvents = json_encode($events->getItems());
$outerArray = array();
$innerArray = array();
foreach ($events->getItems() as $event) {
$date = $event->start->date;
if (!isset($date)) {
$date = $event->start->dateTime;
}
$endDate = $event->end->dateTime;
if (!isset($endDate)) {
$endDate = $event->end->date;
}
$array = array(
"title" => $event->summary,
"description" => $event->description,
"id" => $event->id,
"location" => $event->location,
"start" => $date,
"end" => $endDate,
"colorId" => $event->colorId
);
array_push($outerArray, $array);
}
echo json_encode($outerArray);
The "colorId" => $event->colorId is always NULL.
Public calendar is ON and I have the rights "Make changes and manage sharing".
How can fix that help?
Thanks

Lavachart display count each months

Hello i need serious help cause i have tried all way and not find an answer... so i really want to display chart that count many data each month, ex january 2 data, febuary 3 data etc... pls look at this brother
public function lihatkeluhan(){
$halaman="tindaklayanan";
$keluhan_list=DB::table('keluhans')
->select(DB::raw('id,tanggal,produk,username,area,masalah,status'))->get();
$keluhan_group = keluhan::select(DB::raw('id,tanggal,produk,username,area,masalah,status'))
->get()->groupBy(function($date) {
return Carbon::parse($date->tanggal)->format('m'); // grouping by months
});
foreach ($keluhan_group as $group) {
$count[] = count($group);
}
$bulan = array("Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agu","Sep","Okt","Nov","Des");
$count = Count($keluhan_list);
$population = Lava::DataTable();
$population->addDateColumn("Month")
->addNumberColumn('Keluhan');
foreach($keluhan_group as $group){
$population->addRow(["jan",$count]);
}
Lava::LineChart('Population', $population, [
'title' => 'Tahun : 2017',
'titleTextStyle' => [
'color' => '#212F3C',
'fontSize' => 14
]
]);
$keluhan_group used to group by month
$count result is number of data each month
But idk how to display on chart...
Btw $population->addDateColumn("Month") is not work, it not display month but year T_T
Replace your code from $keluhan_group to $population with below code and check.
here you need to pass array of month and count of that month
$keluhan_group = keluhan::select(DB::raw("COUNT(*) as count , MONTHNAME(created_at) as month"))
->orderBy("created_at")
->groupBy(DB::raw("month(created_at)"))
->get()->toArray();
$chart_array = array();
foreach($keluhan_group as $data){
$n_data = [];
array_push($n_data,$data['month'],$data['count']);
array_push($chart_array,$n_data);
}
$population = Lava::DataTable();
$population->addDateColumn("Month")
->addNumberColumn('Keluhan')
->addRow($chart_array);
hope this will Help.
see i have implemented chart using my 'User' tabel,
i was not having lavachart in my project so i have update it using http://itsolutionstuff.com/post/laravel-5-geo-chart-example-and-demo-using-lavacharts-packageexample.html
here is my controller code:
$users = Users::select(DB::raw("COUNT(*) as count , MONTHNAME(created_at) as month"))
->orderBy("created_at")
->groupBy(DB::raw("month(created_at)"))
->get()->toArray();
$chart_array = array();
foreach($users as $data){
$n_data = [];
array_push($n_data,$data['month'],$data['count']);
array_push($chart_array,$n_data);
}
$lava = new Lavacharts;
$popularity = $lava->DataTable();
$popularity->addStringColumn('Country')
->addNumberColumn('Popularity')
->addRows($chart_array);
$lava->LineChart('demochart', $popularity, [
'title' => 'Demo population count',
'animation' => [
'startup' => true,
'easing' => 'inAndOut'
],
'colors' => ['blue', '#F4C1D8']
]);
return view('welcome', ['lava' => $lava]);
and in my .blade file:
<div id="temps_div"></div>
<?= $lava->render('LineChart', 'demochart' , 'temps_div') ?>
Hope this will Help.
$companies=Company::all();
$start = (new DateTime('2017-01-01'))->modify('first day of this month');
$end = (new DateTime('2022-01-01'))->modify('first day of next month');
$interval = DateInterval::createFromDateString('12 month');
$period = new DatePeriod($start, $interval, $end);
$lava = new Lavacharts; // See note below for Laravel
$finances = \Lava::DataTable();
$finances->addDateColumn('Year');
foreach($companies as $company)
{
$finances ->addNumberColumn($company->company_name." ".$company->company_location." total sales amount");
}
foreach ($period as $dt) {
$yeardate=$dt->format("Y-m-d");
$insertrow = array( $yeardate );
foreach($companies as $company)
{
$cmp= $company->company_name;
$loc= $company->company_location;
$companiesinfo[]=$cmp." ".$loc;
$databasename=$company->database_name;
\Config::set('database.connections.tenant.host', 'localhost');
\Config::set('database.connections.tenant.username','root');
\Config::set('database.connections.tenant.password', '');
\Config::set('database.connections.tenant.database', $databasename);
\Config::set('database.default', 'tenant');
DB::reconnect('tenant');
$calculatesalesofcompany=B2CFINAL::
select(DB::raw('sum(GrandTotal) as total'))
->where(DB::raw('YEAR(SaleDate)'), '=', $yeardate)
->first();
if($calculatesalesofcompany->total==null)
{
$calculatesalesofcompany->total=0;
}
array_push( $insertrow, $calculatesalesofcompany->total );
}
$finances ->addRow($insertrow);
}
\Lava::ComboChart('Finances2', $finances2, [
'title' => 'Company Performance',
'titleTextStyle' => [
'color' => 'rgb(123, 65, 89)',
'fontSize' => 16
],
'legend' => [
'position' => 'in'
],
'seriesType' => 'bars',
]);

php code to send email using find function in forloop

I have startdate and end date in my table like below.
startdate = 2016-01-01
Enddate = 2016-06-20
Now i want to send email automatically before 1 month from end date.
everything is working fine...email is also sending..
But my problem is i want to send email to multiple users if there are 2 rows match in table with my conditions then email is gone to both the users.
But my code only send email to only single users..not all users.
I want email is gone to all users one by one.
public function certificateExpired()
{
$this->autoRender = False;
$this->loadModel('Certificate');
$data = $this->Certificate->find("all", array(
'recursive' => -1, // should be used with joins
'fields' => array('User.*', 'Certificate.*'),
'joins' => array(
array(
'table' => 'users',
'alias' => 'User',
'type' => 'LEFT',
'conditions' => array('User.id = Certificate.user_id')
)
),
'conditions' => array('Certificate.is_expirable' => 1,'Certificate.status' => 1)
));
foreach ($data as $row) {
$currentdate = date("Y-m-d");
$date = $row['Certificate']['end_date'];
$newdate = strtotime($date .' -1 months');
$enddate = date('Y-m-d', $newdate);
if ($currentdate >= $enddate) {
//For sending email
$data['email'] = $row['User']['email'];
$data['name'] = $row['User']['name'];
$data['document_name'] = $row['Certificate']['name'];
$data['templateid'] = 19;
$send_mail = $this->EmailFunctions->certificateExpiredTemplate($data);
if ($send_mail) {
$this->redirect(array('controller' => 'Dashboards', 'action' => 'shipperDashboard'));
}
}
}
}
foreach ($data as $row) {
$currentdate = date("Y-m-d");
$date = $row['Certificate']['end_date'];
$newdate = strtotime($date .' -1 months');
$enddate = date('Y-m-d', $newdate);
if ($currentdate >= $enddate) {
//For sending email
$data['email'] = $row['User']['email'];
$data['name'] = $row['User']['name'];
$data['document_name'] = $row['Certificate']['name'];
$data['templateid'] = 19;
$send_mail = $this->EmailFunctions->certificateExpiredTemplate($data);
}
}
$this->redirect(array('controller' => 'Dashboards', 'action' => 'shipperDashboard'));
Change the foreach loop as above.

Logo change with date script

I just wondered if anybody can point me in the right direction: I'm looking to make a script whereby the logo on my site changes depending on the date; so for instance a haloween style one soon.
I started off by having 2 arrays, 1 of start dates and 1 of end dates(not sure even if this is the best way!):
<?php
$start_dates = array('01/01' => 'New Years',
'14/02' => 'Valentine Day',
'16/02/2010' => 'Pancake Day',
'17/03' => 'St Patricks Day',
'01/04' => 'April Fools',
'02/04/2010' => 'Easter',
'23/04' => 'St Georges Day',
'11/06/2010' => 'World Cup',
'31/10' => 'Halloween',
'05/11' => 'Guy Fawkes',
'11/11' => 'Armistice Day',
'16/10' => 'Today',
'15/12' => 'Christmas');
$end_dates = array( '08/01' => 'New Years',
'15/02' => 'Valentine Day',
'17/02/2010' => 'Pancake Day',
'18/03' => 'St Patricks Day',
'02/04' => 'April Fools',
'06/04/2010' => 'Easter',
'24/04' => 'St Georges Day',
'12/07/2010' => 'World Cup',
'01/11' => 'Halloween',
'06/11' => 'Guy Fawkes',
'12/11' => 'Armistice Day',
'17/10' => 'Today',
'01/01' => 'Christmas');
?>
Easy so far...the problemis that I need a way of working out if todays date falls between the start date and end date, then changing the image file name.
Its a long shot but I hope someone would be kind enough to help.
Thanks,
B.
like this
$events = array(
'New Year' => '01/01 01/08',
'Pancake Day' => '16/02/2010 17/02/2010',
//etc
);
echo find_event($events, '16/02');
where find_event() is
function mdy2time($date) {
$e = explode('/', $date);
if(count($e) < 3)
$e[] = '2010';
return strtotime("$e[1]-$e[0]-$e[2]");
}
function find_event($events, $date = null) {
$date = is_null($date) ? time() : mdy2time($date);
foreach($events as $name => $range) {
list($start, $end) = explode(' ', $range);
if($date >= mdy2time($start) && $date <= mdy2time($end))
return $name;
}
return null;
}
you should use an array more like this:
$dates = array();
$dates[] = array(
'name' => 'New Years'
'start' = '01/14',
'end' => '01/20',
'style' => 'haloween',
);
$dates[] = array(
//...
);
then you can get the style as follows:
$style='default';
// date as number e.g. 130 (january 30th)
$currDate = date('md',time()) * 1;
foreach ($dates AS $k => $v) {
$tmp = explode("/",$v['start'];
$start = ($tmp[1].$tmp[0])*1;
$tmp = explode("/",$v['end'];
$stop = ($tmp[1].$tmp[0])*1;
if ($start <= $currDate && $currDate < $stop) {
$style=$v['style'];
break;
}
}
echo 'style: '.$style;
Didn't check the code yet, so feel free to correct me if iam wrong.

Categories