Get daily orders count in Woocommerce - php

I want to get daily order count of daily whenever an order is posted. I wrote the below code to give a notification on slack whenever there is an order. As a result of displaying $result it showing the current order amount rather than the total order count of the day.
function wp_slack_woocommerce_order_status_completed2( $events ) {
$events['woocommerce_order_status_processing'] = array(
// Action in WooCommerce to hook in to get the message.
'action' => 'woocommerce_order_status_processing',
// Description appears in integration setting.
'description' => __( 'Whenever we receive an order', 'slack-woocommerce' ),
// Message to deliver to channel. Returns false will prevent
// notification delivery.
'message' => function( $order_id ) {
$order = wc_get_order( $order_id );
$date = is_callable( array( $order, 'get_date_completed' ) )
? $order->get_date_completed()
: $order->completed_date;
$url = add_query_arg(
array(
'post' => $order_id,
'action' => 'edit',
),
admin_url( 'post.php' )
);
$user_id = is_callable( array( $order, 'get_user_id' ) )
? $order->get_user_id()
: $order->user_id;
if ( $user_id ) {
$user_info = get_userdata( $user_id );
}
if ( ! empty( $user_info ) ) {
if ( $user_info->first_name || $user_info->last_name ) {
$username = esc_html( ucfirst( $user_info->first_name ) . ' ' . ucfirst( $user_info->last_name ) );
} else {
$username = esc_html( ucfirst( $user_info->display_name ) );
}
} else {
$billing_first_name = is_callable( array( $order, 'get_billing_first_name' ) )
? $order->get_billing_first_name()
: $order->billing_first_name;
$billing_last_name = is_callable( array( $order, 'get_billing_last_name' ) )
? $order->get_billing_last_name()
: $order->billing_last_name;
if ( $billing_first_name || $billing_last_name ) {
$username = trim( $billing_first_name . ' ' . $billing_last_name );
} else {
$username = __( 'Guest', 'slack-woocommerce' );
}
}
global $wpdb;
$date_from = '2018-02-27';
$date_to = '2018-02-28';
$post_status = implode("','", array('wc-processing', 'wc-completed') );
$result = $wpdb->get_results( "SELECT count(*) as total FROM $wpdb->posts
WHERE post_type = 'shop_order'
AND post_status IN ('{$post_status}')
AND post_date BETWEEN '{$date_from} 00:00:00' AND '{$date_to} 23:59:59'
");
// Remove HTML tags generated by WooCommerce.
add_filter( 'woocommerce_get_formatted_order_total', 'wp_strip_all_tags', 10, 1 );
$total = html_entity_decode( $order->get_formatted_order_total() );
remove_filter( 'woocommerce_get_formatted_order_total', 'wp_strip_all_tags', 10 );
//$data2=WC_API_Reports::get_sales_report( );
// Returns the message to be delivered to Slack.
return apply_filters( 'slack_woocommerce_order_status_completed_message',
sprintf(
__( 'Reveived new order with amount *%1$s*. Made by *%2$s* on *%3$s*. <%4$s|See detail> %s', 'slack-woocommerce' ),
$total,
$username,
$date,
$url,
$resullt
),
$order
);
},
);
return $events;
}
add_filter( 'slack_get_events', 'wp_slack_woocommerce_order_status_completed2' );

To get the daily order count you can use this custom function that will return the order count for the current day or the order count for a specific defined date:
function get_daily_orders_count( $date = 'now' ){
if( $date == 'now' ){
$date = date("Y-m-d");
$date_string = "> '$date'";
} else {
$date = date("Y-m-d", strtotime( $date ));
$date2 = date("Y-m-d", strtotime( $date ) + 86400 );
$date_string = "BETWEEN '$date' AND '$date2'";
}
global $wpdb;
$result = $wpdb->get_var( "
SELECT DISTINCT count(p.ID) FROM {$wpdb->prefix}posts as p
WHERE p.post_type = 'shop_order' AND p.post_date $date_string
AND p.post_status IN ('wc-on-hold','wc-processing','wc-completed')
" );
return $result;
}
Code goes in function.php file of your active child theme (or theme). Tested and works.
USAGE:
1) To get the orders count for the current date:
$orders_count = get_daily_orders_count();
2) To get the orders count for a specific date (with a format like 2018-02-28):
// Get orders count for february 25th 2018 (for example)
$orders_count = get_daily_orders_count('2018-02-25');

Related

Send a custom reminder email for WooCommerce On-Hold orders after two days

My goal is to send an email to the customer containing custom text if the order status is on-hold and if the order creation time is 48 hours or more old.
order is 48 hours old or more
send email to customer
ask customer to pay
include a link to the order (to my account payment page)
I'm trying to use the code from an answer to one of my previous questions about Automatically cancel order after X days if no payment in WooCommerce.
I have lightly changes the code:
add_action( 'restrict_manage_posts', 'on_hold_payment_reminder' );
function on_hold_payment_reminder() {
global $pagenow, $post_type;
if( 'shop_order' === $post_type && 'edit.php' === $pagenow
&& get_option( 'unpaid_orders_daily_process' ) < time() ) :
$days_delay = 5;
$one_day = 24 * 60 * 60;
$today = strtotime( date('Y-m-d') );
$unpaid_orders = (array) wc_get_orders( array(
'limit' => -1,
'status' => 'on-hold',
'date_created' => '<' . ( $today - ($days_delay * $one_day) ),
) );
if ( sizeof($unpaid_orders) > 0 ) {
$reminder_text = __("Payment reminder email sent to customer $today.", "woocommerce");
foreach ( $unpaid_orders as $order ) {
// HERE I want the email to be sent instead <=== <=== <=== <=== <===
}
}
update_option( 'unpaid_orders_daily_process', $today + $one_day );
endif;
}
This is the email part that I want to sync with the above (read the code comments):
add_action ('woocommerce_email_order_details', 'on_hold_payment_reminder', 5, 4);
function on_hold_payment_reminder( $order, $sent_to_admin, $plain_text, $email ){
if ( 'customer_on_hold_order' == $email->id ){
$order_id = $order->get_id();
echo "<h2>Do not forget about your order..</h2>
<p>CUSTOM MESSAGE HERE</p>";
}
}
So how can I send an email notification reminder for "on-hold" orders with a custom text?
The following code will be triggered once daily and will send an email reminder with a custom message on unpaid orders (for "on-hold" order status):
add_action( 'restrict_manage_posts', 'on_hold_payment_reminder' );
function on_hold_payment_reminder() {
global $pagenow, $post_type;
if( 'shop_order' === $post_type && 'edit.php' === $pagenow
&& get_option( 'unpaid_orders_reminder_daily_process' ) < time() ) :
$days_delay = 2; // 48 hours
$one_day = 24 * 60 * 60;
$today = strtotime( date('Y-m-d') );
$unpaid_orders = (array) wc_get_orders( array(
'limit' => -1,
'status' => 'on-hold',
'date_created' => '<' . ( $today - ($days_delay * $one_day) ),
) );
if ( sizeof($unpaid_orders) > 0 ) {
$reminder_text = __("Payment reminder email sent to customer $today.", "woocommerce");
foreach ( $unpaid_orders as $order ) {
$order->update_meta_data( '_send_on_hold', true );
$order->update_status( 'reminder', $reminder_text );
$wc_emails = WC()->mailer()->get_emails(); // Get all WC_emails objects instances
$wc_emails['WC_Email_Customer_On_Hold_Order']->trigger( $order->get_id() ); // Send email
}
}
update_option( 'unpaid_orders_reminder_daily_process', $today + $one_day );
endif;
}
add_action ( 'woocommerce_email_order_details', 'on_hold_payment_reminder_notification', 5, 4 );
function on_hold_payment_reminder_notification( $order, $sent_to_admin, $plain_text, $email ){
if ( 'customer_on_hold_order' == $email->id && $order->get_meta('_send_on_hold') ){
$order_id = $order->get_id();
$order_link = wc_get_page_permalink('myaccount').'view-order/'.$order_id.'/';
$order_number = $order->get_order_number();
echo '<h2>'.__("Do not forget about your order.").'</h2>
<p>'.sprintf( __("CUSTOM MESSAGE HERE… %s"),
'<a href="'.$order_link.'">'.__("Your My account order #").$order_number.'<a>'
) .'</p>';
$order->delete_meta_data('_send_on_hold');
$order->save();
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.

Woocommerce auto cancel on-hold after X days

Since I will be using offline payments (bank billets - standard in Brazil). What I am trying to achieve is to auto-cancel "on-hold" orders after 9 days, which is when the billet expires. I found a few references of code: one from woocommerce github and another from stackoverflow. What the code does (kinda messy in my opinion) is mirror the "pending" cancelation to "on hild". On github they are saying that it's important to use date_modified arguments to pull orders from the last hour. I have tested this out but it's not working. Do not know what the problem is.
<?php
function wc_foo_cancel_unpaid_onhold_orders() {
global $wpdb;
$held_duration = get_option('woocommerce_hold_stock_minutes');
if ( $held_duration < 1 || 'yes' !== get_option( 'woocommerce_manage_stock')) {
return;
}
$unpaid_orders = wc_foo_cancel_unpaid_onhold_orders( strtotime( '-' . absint( $held_duration) . ' MINUTES'. current_time( 'timestamp')));
if ( $unpaid_orders) {
foreach ( $unpaid_orders as $unpaid_orders ){
$order = wc_get_order( $unpaid_order);
if ( apply_filters( 'woocommerce_cancel_unpaid_order', 'checkout' == $order->get_created_via(), $order ) ) {
$order ->update_status( 'cancelled', _( 'Unpaid order cancelled - time limite reached.', 'woocommerce'));
}
}
}
}
add_action( 'woocommerce_cancel_unpaid_orders', 'wc_foo_cancel_unpaid_onhold_orders');
function wc_foo_get_unpaid_onhold_orders( $date ){
global $wpdb;
$args = array(
'date_modified' => '>' . ( time() - HOUR_IN_SECONDS ),
'status' => 'on-hold',);
$orders = wc_get_orders( $args );
$unpaid_orders = $wpdb->get_col( $wpdb->prepare( "
SELECT posts.id
FROM {$wpdb->posts} AS posts
WHERE posts.posts_type IN ('" . implode( "','", wc_get_order_types()). "')
AND posts.post_status = 'wc-on-hold'
AND posts.date_modified < %s
", date( 'Y-m-d H:i:s', absint( $date)) ) );
}
?>
So I had a little bit of help form #danaharrison at Wordpress.org to achieve this. So the code only applies to 'on-hold' orders.
// To change the amount of days just change '-7 days' to your liking.
function get_unpaid_submitted() {
global $wpdb;
$unpaid_submitted = $wpdb->get_col( $wpdb->prepare( "
SELECT posts.ID
FROM {$wpdb->posts} AS posts
WHERE posts.post_status = 'wc-on-hold'
AND posts.post_date < %s
", date( 'Y-m-d H:i:s', strtotime('-7 days') ) ) );
return $unpaid_submitted;
}
// This excludes check payment type.
function wc_cancel_unpaid_submitted() {
$unpaid_submit = get_unpaid_submitted();
if ( $unpaid_submit ) {
foreach ( $unpaid_submit as $unpaid_order ) {
$order = wc_get_order( $unpaid_order );
$cancel_order = True;
foreach ( $order->get_items() as $item_key => $item_values) {
$manage_stock = get_post_meta( $item_values['variation_id'], '_manage_stock', true );
if ( $manage_stock == "no" ) {
$payment_method = $order->get_payment_method();
if ( $payment_method == "cheque" ) {
$cancel_order = False;
}
}
}
if ( $cancel_order == True ) {
$order -> update_status( 'cancelled', __( 'Pagamento não identificado e cancelado.', 'woocommerce') );
}
}
}
}
add_action( 'woocommerce_cancel_unpaid_submitted', 'wc_cancel_unpaid_submitted' );
/* End of code. */

XML with multiple roots

Hi i've been trying to generate the following XML with PHP.
I've managed to generate it all except for the location section as it seems to treat it as another root and error out. Does anyone know the correct way to produce this?
<?xml version="1.0" encoding="UTF-8"?>
<classifieds xmlns="http://www.bdjjobs.com/ClassifiedJobFromRecruiterFeed">
<job>
<reference_id>20161114-72</reference_id>
<recruiter>Smiles R Us</recruiter>
<job_title>Denture Specialist</job_title>
<short_description><![CDATA[An exciting position in a dynamic dental practice]]></short_description>
<description><![CDATA[<p>Full description of post</p>]]></description>
<location>
<city>city</city>
<state>county</state>
<country>country</country>
</location>
<salary_description><![CDATA[Full Package]]></salary_description>
<organisations>Independent Dental Practice</organisations>
<job_type>Specialist Appointments</job_type>
<salary_band>£100,000 or more</salary_band>
<contract_type>Associate Permanent</contract_type>
<hours>Full time</hours>
<practice_type>Mixed (NHS/Private)</practice_type>
<start_date>2016-09-01</start_date>
<expiry_date>2016-10-30</expiry_date>
<application_email>apply_here#email.com</application_email>
</job>
</classifieds>
Any assistance would be greatly appreciated, thanks :)
Here is the code:
// Start Job Element
$job_element = $xml_document->createElement("job");
// Job ID
$rootreferencenumber = $xml_document->createElement("reference_id");
$rootreferencenumber->appendChild($xml_document->createCDATASection( get_the_ID() ));
$job_element->appendChild($rootreferencenumber);
// Recruiter
$recruiter = $xml_document->createElement("recruiter");
$recruiter->appendChild($xml_document->createCDATASection( "MBR Dental Recruitment" ));
$job_element->appendChild($recruiter);
// Job title
$title = $xml_document->createElement("title");
$title->appendChild($xml_document->createCDATASection( get_the_title() ) );
$job_element->appendChild($title);
// Job Description
$description = $xml_document->createElement("description");
$description->appendChild($xml_document->createCDATASection( ( strip_tags( str_replace( "</p>", "\n\n", get_the_content() ) ) ) ) );
$job_element->appendChild($description);
// City
$city = $xml_document->createElement("city");
$get_city = explode( ',', get_post_meta( get_the_ID(), 'geolocation_city', true ) );
$city->appendChild($xml_document->createCDATASection( $get_city[0] ) );
$job_element->appendChild($city);
// Region from Taxonomy
$region = $xml_document->createElement("region");
$categories = wp_get_post_terms( get_the_ID(), 'job_listing_region', array( "fields" => "names" ) );
if ( $categories && ! is_wp_error( $categories ) ) {
$region->appendChild( $xml_document->createCDATASection( implode( ',', $categories ) ) );
} else {
$region->appendChild( $xml_document->createCDATASection( '' ) );
}
$job_element->appendChild($region);
// Create Company Name
$company_name = $xml_document->createElement("organisations");
$company_name->appendChild($xml_document->createCDATASection('xx'));
$job_element->appendChild($company_name);
// Create Phone Number
$phone_number = $xml_document->createElement("phone_number");
$phone_number->appendChild($xml_document->createCDATASection('0000'));
$job_element->appendChild($phone_number);
// Job direct URL
$url = $xml_document->createElement("application_url");
$url->appendChild($xml_document->createCDATASection(get_permalink( get_the_ID() )));
$job_element->appendChild($url);
// Category
$phone_number = $xml_document->createElement("job_type");
$phone_number->appendChild($xml_document->createCDATASection('Job'));
$job_element->appendChild($phone_number);
// Subcategory
$region = $xml_document->createElement("subcategory");
$categories = wp_get_post_terms( get_the_ID(), 'job_listing_category', array( "fields" => "names" ) );
if ( $categories && ! is_wp_error( $categories ) ) {
$region->appendChild( $xml_document->createCDATASection( implode( ',', $categories ) ) );
} else {
$region->appendChild( $xml_document->createCDATASection( '' ) );
}
$job_element->appendChild($region);
// Job date based on todays date
$date = $xml_document->createElement("start_date");
$date->appendChild($xml_document->createCDATASection(date(Ymd) ));
$job_element->appendChild($date);
// Job date expire from original post date
$expiry_date = $xml_document->createElement("expiry_date");
$wpDate = (date(Ymd) );
$wpDate = new DateTime($wpDate);
$wpDate->add(new DateInterval('P14D')); // P14D means a period of 14 days
$wpDate = $wpDate->format('Ymd');
$expiry_date->appendChild($xml_document->createCDATASection( $wpDate ));
$job_element->appendChild($expiry_date);
// Create Application Email Address
$app_email = $xml_document->createElement("application_email");
$app_email->appendChild($xml_document->createCDATASection('xx#xx.com'));
$job_element->appendChild($app_email);
// End Job Element
$root->appendChild($job_element);
Ok so i was approaching this completely wrong..
I needed to append the child elements (City + Region) to the new $location element. Not to the original $job_element
here is the correct code:
// Start Job Element
$job_element = $xml_document->createElement("job");
// Job ID
$rootreferencenumber = $xml_document->createElement("reference_id");
$rootreferencenumber->appendChild($xml_document->createCDATASection( get_the_ID() ));
$job_element->appendChild($rootreferencenumber);
// Recruiter
$recruiter = $xml_document->createElement("recruiter");
$recruiter->appendChild($xml_document->createCDATASection( "xx" ));
$job_element->appendChild($recruiter);
// Job title
$title = $xml_document->createElement("title");
$title->appendChild($xml_document->createCDATASection( get_the_title() ) );
$job_element->appendChild($title);
// Job Description
$description = $xml_document->createElement("description");
$description->appendChild($xml_document->createCDATASection( ( strip_tags( str_replace( "</p>", "\n\n", get_the_content() ) ) ) ) );
$job_element->appendChild($description);
//Create Location Element
$location = $xml_document->createElement("location");
$job_element->appendChild($location);
// City
$city = $xml_document->createElement("city");
$get_city = explode( ',', get_post_meta( get_the_ID(), 'geolocation_city', true ) );
$city->appendChild($xml_document->createCDATASection( $get_city[0] ) );
$location->appendChild($city);
// Region from Taxonomy
$region = $xml_document->createElement("region");
$categories = wp_get_post_terms( get_the_ID(), 'job_listing_region', array( "fields" => "names" ) );
if ( $categories && ! is_wp_error( $categories ) ) {
$region->appendChild( $xml_document->createCDATASection( implode( ',', $categories ) ) );
} else {
$region->appendChild( $xml_document->createCDATASection( '' ) );
}
$location->appendChild($region);
// Country Code
$country = $xml_document->createElement("country");
$country->appendChild($xml_document->createCDATASection('UK'));
$location->appendChild($country);
// Create Company Name
$company_name = $xml_document->createElement("organisations");
$company_name->appendChild($xml_document->createCDATASection('xx'));
$job_element->appendChild($company_name);
// Create Phone Number
$phone_number = $xml_document->createElement("phone_number");
$phone_number->appendChild($xml_document->createCDATASection('xx'));
$job_element->appendChild($phone_number);
// Job direct URL
$url = $xml_document->createElement("application_url");
$url->appendChild($xml_document->createCDATASection(get_permalink( get_the_ID() )));
$job_element->appendChild($url);
// Category
$job_type = $xml_document->createElement("job_type");
$job_type->appendChild($xml_document->createCDATASection('Job'));
$job_element->appendChild($job_type);
// Subcategory
$region = $xml_document->createElement("subcategory");
$categories = wp_get_post_terms( get_the_ID(), 'job_listing_category', array( "fields" => "names" ) );
if ( $categories && ! is_wp_error( $categories ) ) {
$region->appendChild( $xml_document->createCDATASection( implode( ',', $categories ) ) );
} else {
$region->appendChild( $xml_document->createCDATASection( '' ) );
}
$job_element->appendChild($region);
// Job date based on todays date
$date = $xml_document->createElement("start_date");
$date->appendChild($xml_document->createCDATASection(date(Ymd) ));
$job_element->appendChild($date);
// Job date expire from original post date
$expiry_date = $xml_document->createElement("expiry_date");
$wpDate = (date(Ymd) );
$wpDate = new DateTime($wpDate);
$wpDate->add(new DateInterval('P14D')); // P14D means a period of 14 days
$wpDate = $wpDate->format('Ymd');
$expiry_date->appendChild($xml_document->createCDATASection( $wpDate ));
$job_element->appendChild($expiry_date);
// Create Application Email Address
$app_email = $xml_document->createElement("application_email");
$app_email->appendChild($xml_document->createCDATASection('x#xx.net'));
$job_element->appendChild($app_email);
// End Job Element
$root->appendChild($job_element);

Woocommerce sort columns by Event Time

I'm working with Wordpress, Woocommerce & Eventon plugin in order to create a selling tickets for events site. Users can order tickets for different dates.
I'm trying to implement a sortable column wich shows for every ticket sold the date for the event (stored in woocommerce_order_itemmeta table as meta_value of meta_key 'Event-Time'). So first of all I created and populated that column like this:
add_filter( 'manage_edit-shop_order_columns', 'wooc_set_custom_column_order_columns');
//create custom woocommerce columns
function wooc_set_custom_column_order_columns($columns) {#
$nieuwearray = array();
foreach($columns as $key => $title) {
if ($key=='billing_address') { // in front of the Billing column
$nieuwearray['order_product'] = __( 'Products', 'woocommerce' );
$nieuwearray['Event-Time'] = __( 'Reservation Date', 'woocommerce' );
}
$nieuwearray[$key] = $title;
}
return $nieuwearray ;
}
//populate custom woocommerce columns
add_action( 'manage_shop_order_posts_custom_column' , 'custom_shop_order_column', 10, 2 );
function custom_shop_order_column( $column ) {
global $post, $woocommerce, $the_order;
switch ( $column ) {
case 'order_product' :
$terms = $the_order->get_items();
if ( is_array( $terms ) ) {
foreach($terms as $term)
{
echo $term['item_meta']['_qty'][0] .' x ' . $term['name'] .'<br />';
}
} else {
_e( 'Unable get the product', 'woocommerce' );
}
break;
case 'Event-Time' :
$terms = $the_order->get_items();
if ( is_array( $terms ) ) {
foreach($terms as $term) {
if(array_key_exists( 'Event-Time', $term ) ){
$date_event = substr($term['item_meta']['Event-Time'][0], 0, 10);
echo $date_event . '<br />';
} else {
echo '<b>' . __('No existe fecha reserva?', 'woocommerce') . '</b>';
}
}
} else {
_e( 'Unable get the product', 'woocommerce' );
}
break;
}
}
In order to make Event-Time column sortable, I added this code:
add_filter( "manage_edit-shop_order_sortable_columns", 'sort_columns_woocommerce' );
function sort_columns_woocommerce( $columns ) {
$custom = array(
//'order_producten' => 'MY_COLUMN_1_POST_META_ID',
'Event-Time' => 'Event-Time'
);
return wp_parse_args( $custom, $columns );
}
but nothing happened, so after a few hours looking it up on Google, I found similar solution that I tried to adapt to my case:
function order_by_event_time_join($query) {
global $wpdb;
if ( is_admin() && (isset($_GET['post_type']) && $_GET['post_type'] === 'shop_order') && (isset($_GET['orderby']) && $_GET['orderby'] === 'Event-Time') ) {
$first_item_in_order = "SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = $wpdb->posts.ID AND order_item_type = 'line_item' LIMIT 0, 1";
$query .= "LEFT JOIN {$wpdb->prefix}woocommerce_order_items AS items ON $wpdb->posts.ID = items.order_id AND items.order_item_id = ($first_item_in_order) ";
$query .= "LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS itemmeta ON items.order_item_id = itemmeta.order_item_id AND (itemmeta.meta_key = 'Event-Time') ";
}
return $query;
}
add_filter('posts_join', 'order_by_event_time_join');
function order_by_event_time_where($where) {
global $wpdb;
if( is_admin() && $_GET['post_type'] === 'shop_order' && (isset($_GET['orderby']) && $_GET['orderby'] === 'Event-Time') ) {
if(strpos($where, 'shop_webhook')) {
return " AND $wpdb->posts.post_type = 'shop_order' AND itemmeta.meta_key = 'Event-Time'";
}
}
return $where;
}
add_filter('posts_where', 'order_by_event_time_where');
But no luck... What I understand the problem is I'm not able to sort columns by the meta_value 'Event-Time' in the ticket-orders section of woocommerce...
I can show Event-Time data but impossible to sort/filter it.

Modify code to change timestamp timezone in sitemap

Below is the code from a plugin I use for sitemaps.
I would like to know if there's a way to "enforce" a different timezone on all date variable and functions in it.
If not, how do I modify the code to change the timestamp to reflect a different timezone? Say for example, to America/New_York timezone.
Please look for date to quickly get to the appropriate code blocks. Code on Pastebin.
<?php
/**
* #package XML_Sitemaps
*/
class WPSEO_Sitemaps {
.....
/**
* Build the root sitemap -- example.com/sitemap_index.xml -- which lists sub-sitemaps
* for other content types.
*
* #todo lastmod for sitemaps?
*/
function build_root_map() {
global $wpdb;
$options = get_wpseo_options();
$this->sitemap = '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
$base = $GLOBALS['wp_rewrite']->using_index_permalinks() ? 'index.php/' : '';
// reference post type specific sitemaps
foreach ( get_post_types( array( 'public' => true ) ) as $post_type ) {
if ( $post_type == 'attachment' )
continue;
if ( isset( $options['post_types-' . $post_type . '-not_in_sitemap'] ) && $options['post_types-' . $post_type . '-not_in_sitemap'] )
continue;
$count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM $wpdb->posts WHERE post_type = %s AND post_status = 'publish' LIMIT 1", $post_type ) );
// don't include post types with no posts
if ( !$count )
continue;
$n = ( $count > 1000 ) ? (int) ceil( $count / 1000 ) : 1;
for ( $i = 0; $i < $n; $i++ ) {
$count = ( $n > 1 ) ? $i + 1 : '';
if ( empty( $count ) || $count == $n ) {
$date = $this->get_last_modified( $post_type );
} else {
$date = $wpdb->get_var( $wpdb->prepare( "SELECT post_modified_gmt FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = %s ORDER BY post_modified_gmt ASC LIMIT 1 OFFSET %d", $post_type, $i * 1000 + 999 ) );
$date = date( 'c', strtotime( $date ) );
}
$this->sitemap .= '<sitemap>' . "\n";
$this->sitemap .= '<loc>' . home_url( $base . $post_type . '-sitemap' . $count . '.xml' ) . '</loc>' . "\n";
$this->sitemap .= '<lastmod>' . htmlspecialchars( $date ) . '</lastmod>' . "\n";
$this->sitemap .= '</sitemap>' . "\n";
}
}
// reference taxonomy specific sitemaps
foreach ( get_taxonomies( array( 'public' => true ) ) as $tax ) {
if ( in_array( $tax, array( 'link_category', 'nav_menu', 'post_format' ) ) )
continue;
if ( isset( $options['taxonomies-' . $tax . '-not_in_sitemap'] ) && $options['taxonomies-' . $tax . '-not_in_sitemap'] )
continue;
// don't include taxonomies with no terms
if ( !$wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE taxonomy = %s AND count != 0 LIMIT 1", $tax ) ) )
continue;
// Retrieve the post_types that are registered to this taxonomy and then retrieve last modified date for all of those combined.
$taxobj = get_taxonomy( $tax );
$date = $this->get_last_modified( $taxobj->object_type );
$this->sitemap .= '<sitemap>' . "\n";
$this->sitemap .= '<loc>' . home_url( $base . $tax . '-sitemap.xml' ) . '</loc>' . "\n";
$this->sitemap .= '<lastmod>' . htmlspecialchars( $date ) . '</lastmod>' . "\n";
$this->sitemap .= '</sitemap>' . "\n";
}
// allow other plugins to add their sitemaps to the index
$this->sitemap .= apply_filters( 'wpseo_sitemap_index', '' );
$this->sitemap .= '</sitemapindex>';
}
/**
* Build a sub-sitemap for a specific post type -- example.com/post_type-sitemap.xml
*
* #param string $post_type Registered post type's slug
*/
function build_post_type_map( $post_type ) {
$options = get_wpseo_options();
............
// We grab post_date, post_name, post_author and post_status too so we can throw these objects into get_permalink, which saves a get_post call for each permalink.
while ( $total > $offset ) {
$join_filter = apply_filters( 'wpseo_posts_join', '', $post_type );
$where_filter = apply_filters( 'wpseo_posts_where', '', $post_type );
// Optimized query per this thread: http://wordpress.org/support/topic/plugin-wordpress-seo-by-yoast-performance-suggestion
// Also see http://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/
$posts = $wpdb->get_results( "SELECT l.ID, post_content, post_name, post_author, post_parent, post_modified_gmt, post_date, post_date_gmt
FROM (
SELECT ID FROM $wpdb->posts {$join_filter}
WHERE post_status = 'publish'
AND post_password = ''
AND post_type = '$post_type'
{$where_filter}
ORDER BY post_modified ASC
LIMIT $steps OFFSET $offset ) o
JOIN $wpdb->posts l
ON l.ID = o.ID
ORDER BY l.ID" );
/* $posts = $wpdb->get_results("SELECT ID, post_content, post_name, post_author, post_parent, post_modified_gmt, post_date, post_date_gmt
FROM $wpdb->posts {$join_filter}
WHERE post_status = 'publish'
AND post_password = ''
AND post_type = '$post_type'
{$where_filter}
ORDER BY post_modified ASC
LIMIT $steps OFFSET $offset"); */
$offset = $offset + $steps;
foreach ( $posts as $p ) {
$p->post_type = $post_type;
$p->post_status = 'publish';
$p->filter = 'sample';
if ( wpseo_get_value( 'meta-robots-noindex', $p->ID ) && wpseo_get_value( 'sitemap-include', $p->ID ) != 'always' )
continue;
if ( wpseo_get_value( 'sitemap-include', $p->ID ) == 'never' )
continue;
if ( wpseo_get_value( 'redirect', $p->ID ) && strlen( wpseo_get_value( 'redirect', $p->ID ) ) > 0 )
continue;
$url = array();
$url['mod'] = ( isset( $p->post_modified_gmt ) && $p->post_modified_gmt != '0000-00-00 00:00:00' ) ? $p->post_modified_gmt : $p->post_date_gmt;
$url['chf'] = 'weekly';
$url['loc'] = get_permalink( $p );
.............
}
/**
* Build a sub-sitemap for a specific taxonomy -- example.com/tax-sitemap.xml
*
* #param string $taxonomy Registered taxonomy's slug
*/
function build_tax_map( $taxonomy ) {
$options = get_wpseo_options();
..........
// Grab last modified date
$sql = "SELECT MAX(p.post_date) AS lastmod
FROM $wpdb->posts AS p
INNER JOIN $wpdb->term_relationships AS term_rel
ON term_rel.object_id = p.ID
INNER JOIN $wpdb->term_taxonomy AS term_tax
ON term_tax.term_taxonomy_id = term_rel.term_taxonomy_id
AND term_tax.taxonomy = '$c->taxonomy'
AND term_tax.term_id = $c->term_id
WHERE p.post_status = 'publish'
AND p.post_password = ''";
$url['mod'] = $wpdb->get_var( $sql );
$url['chf'] = 'weekly';
$output .= $this->sitemap_url( $url );
}
}
/**
* Build the <url> tag for a given URL.
*
* #param array $url Array of parts that make up this entry
* #return string
*/
function sitemap_url( $url ) {
if ( isset( $url['mod'] ) )
$date = mysql2date( "Y-m-d\TH:i:s+00:00", $url['mod'] );
else
$date = date( 'c' );
$output = "\t<url>\n";
$output .= "\t\t<loc>" . $url['loc'] . "</loc>\n";
$output .= "\t\t<lastmod>" . $date . "</lastmod>\n";
$output .= "\t\t<changefreq>" . $url['chf'] . "</changefreq>\n";
$output .= "\t\t<priority>" . str_replace( ',', '.', $url['pri'] ) . "</priority>\n";
if ( isset( $url['images'] ) && count( $url['images'] ) > 0 ) {
foreach ( $url['images'] as $img ) {
$output .= "\t\t<image:image>\n";
$output .= "\t\t\t<image:loc>" . esc_html( $img['src'] ) . "</image:loc>\n";
if ( isset( $img['title'] ) )
$output .= "\t\t\t<image:title>" . _wp_specialchars( html_entity_decode( $img['title'], ENT_QUOTES, get_bloginfo('charset') ) ) . "</image:title>\n";
if ( isset( $img['alt'] ) )
$output .= "\t\t\t<image:caption>" . _wp_specialchars( html_entity_decode( $img['alt'], ENT_QUOTES, get_bloginfo('charset') ) ) . "</image:caption>\n";
$output .= "\t\t</image:image>\n";
}
}
$output .= "\t</url>\n";
return $output;
}
/**
* Get the modification date for the last modified post in the post type:
*
* #param array $post_types Post types to get the last modification date for
* #return string
*/
function get_last_modified( $post_types ) {
global $wpdb;
if ( !is_array( $post_types ) )
$post_types = array( $post_types );
$result = 0;
foreach ( $post_types as $post_type ) {
$key = 'lastpostmodified:gmt:' . $post_type;
$date = wp_cache_get( $key, 'timeinfo' );
if ( !$date ) {
$date = $wpdb->get_var( $wpdb->prepare( "SELECT post_modified_gmt FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = %s ORDER BY post_modified_gmt DESC LIMIT 1", $post_type ) );
if ( $date )
wp_cache_set( $key, $date, 'timeinfo' );
}
if ( strtotime( $date ) > $result )
$result = strtotime( $date );
}
// Transform to W3C Date format.
$result = date( 'c', $result );
return $result;
}
}
global $wpseo_sitemaps;
$wpseo_sitemaps = new WPSEO_Sitemaps();
I believe you're looking for the date_default_timezone_set() function, which will force all date functions, including date(), to use the specified time zone.
date_default_timezone_set( 'America/New_York');
For your specific case to only have changes apply to the plugin, you should save the current timezone with date_default_timezone_get(), then set your own timezone, and revert it when you're done. So, you could do something like this:
class WPSEO_Sitemaps {
private $old_timezone = '';
private $new_timezone = 'America/New_York';
function setTimezone() {
$this->old_timezone = date_default_timezone_get();
date_default_timezone_set( $this->new_timezone);
}
function revertTimezone() {
date_default_timezone_set( $this->old_timezone);
}
function foo() {
$this->setTimezone();
date();
$tihs->revertTimezone();
}
}

Categories