I'm having some problems to schedule a custom cron job in a wordpress plugin.
I have this code inside my class and is supposed to send multiple emails to different adresses and each email will have a different subject and message.
class GreetingTicketScheduler {
public function __construct()
{
register_activation_hook(__FILE__, [$this, 'schedule_orders_forward']);
add_action('forward_orders', [$this, 'send_confirmed_orders']);
}
public function schedule_orders_forward()
{
// Schedules the event if it's NOT already scheduled.
if(!wp_next_scheduled('forward_orders')){
wp_schedule_event( time(), '5min', 'send_confirmed_orders', [], true);
}
}
public function send_confirmed_orders()
{
global $wpdb;
$table = $wpdb->prefix . 'order_codes';
//
$sql = $wpdb->prepare("SELECT * FROM $table");
//
$results = $wpdb->get_results($sql, ARRAY_A);
//
if( !empty($results) ){
//
$pdv_subject = "Morning greetings of " . date('d-m-Y', time());
//
$pdv_message_a .= "Salut!\n";
$pdv_email_a = 'mail.example#example.org';
$pdv_headers_a[] = 'Cc: mail.example#example.org';
//
$pdv_message_b .= "Ciao!\n";
$pdv_email_b = 'mail.example#example.org';
$pdv_headers_b[] = 'Cc: mail.example#example.org';
//
$pdv_message_p .= "Hi!\n";
$pdv_email_p = 'mail.example#example.org';
$pdv_headers_p[] = 'Cc: mail.example#example.org';
//
foreach( $results as $key => $val ){
if(date('d-m-Y', $val['confirmed_at']) === date('d-m-Y', time()) && $val['order_cpco'] === '6605'){
$pdv_message_a .= $val['order_file'] . "\n";
}
//
if(date('d-m-Y', $val['confirmed_at']) === date('d-m-Y', time()) && $val['order_cpco'] === '6200'){
$pdv_message_b .= $val['order_file'] . "\n";
}
//
if(date('d-m-Y', $val['confirmed_at']) === date('d-m-Y', time()) && $val['order_cpco'] === '6600' ){
$pdv_message_p .= $val['order_file'] . "\n";
}
}
//
//wp_mail( $to:string|array, $subject:string, $message:string, $headers:string|array, $attachments:string|array )
//
wp_mail($pdv_email_a, $pdv_subject, $pdv_message_a, $pdv_headers_a);
//
wp_mail($pdv_email_b, $pdv_subject, $pdv_message_b, $pdv_headers_b);
//
wp_mail($pdv_email_p, $pdv_subject, $pdv_message_p, $pdv_headaers_p);
}
}
}
In my staging envoirment I have the plugin activated but I've noticed that the emails will be not send, probably I've missed something in the code.
What I need to modify to correctly schedule the cron job every five minutes or every hour?
You need to use an action hook to schedule the cron job, and then call the function.
class GreetingTicketScheduler {
public function __construct()
{
add_action('wp', [$this, 'schedule_orders_forward']);
add_action('forward_orders', [$this, 'send_confirmed_orders']);
}
public function schedule_orders_forward()
{
if (!wp_next_scheduled('forward_orders')) {
wp_schedule_event(time(), 'hourly', 'forward_orders');
}
}
public function send_confirmed_orders()
{
// ... code to send emails ...
}
}
Related
So I am trying to manually update the Subscription Dates and show a notice on the for the subsrriptions here. The goal is to make all the subscriptions trigger on the 1st of every month let's say.
So in the wp_posts meta we have post_date and post_date_gmt
class ChiChi_SubscriptionMetaBoxes
{
/**
* To load Schedule meta box
* */
public static function redateSchedule()
{
add_meta_box('chichi-redate-schedule', _x('Redate Schedule', 'meta box title'), 'ChiChi_SubscriptionMetaBoxes::output', 'shop_subscription', 'side', 'default');
}
/**
* To display Redate Schedule
*
* #param object $post
* */
public static function output($post)
{
global $theorder;
if (wcs_is_subscription($theorder) && !$theorder->has_status(wcs_get_subscription_ended_statuses())) {
include(get_theme_file_path('/lib/woocommerce/templates/html-redate-schedule.php'));
}
}
public static function save($order_id)
{
global $wpdb;
if (!isset($_POST['redate_schedule_date_nonce']) || !isset($_POST['redate_schedule'])) {
return $order_id;
}
$nonce = $_REQUEST['redate_schedule_date_nonce'];
if (!is_numeric($_POST['redate_schedule'])) {
return $order_id;
}
$newDay = (int)$_POST['redate_schedule'];
//Verify that the nonce is valid.
if (!wp_verify_nonce($nonce) || wp_is_post_revision($order_id)) {
return $order_id;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return $order_id;
}
// Check the user's permissions.
if ('page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $order_id)) {
return $order_id;
}
} else {
if (!current_user_can('edit_post', $order_id)) {
return $order_id;
}
}
// Update the meta field in the database.
$subscription = wcs_get_subscription($order_id);
$pending_status = 'pending';
if (class_exists('ActionScheduler_Store')) {
$pending_status = ActionScheduler_Store::STATUS_PENDING;
}
$amSchedule = '_action_manager_schedule';
try {
$redatedShedule = [];
$schedules = as_get_scheduled_actions([
'hook' => 'woocommerce_subscription_upfront_renewal',
'args' => [
'subscription_id' => $subscription->get_id()
],
'status' => $pending_status,
'per_page' => 100
]);
if (!empty($schedules)) {
foreach ($schedules as $key => $schedule) {
$scheduledPost = get_post($key);
if (!empty($scheduledPost)) {
$originalDateTs = strtotime($scheduledPost->post_date);
$originalGmtDateTs = strtotime($scheduledPost->post_date_gmt);
$newDate = date("Y-m-" . $newDay . " H:i:s", $originalDateTs);
$gmtDate = get_gmt_from_date($newDate);
// Update Post
wp_update_post([
'ID' => $key,
'post_date' => $newDate,
'post_date_gmt' => $gmtDate
]);
// Update meta time stamps
$sql = "UPDATE " . $wpdb->postmeta . " SET meta_value = REPLACE(meta_value, '" . $_schedule_start . "', '" . strtotime($gmtDate) . "') WHERE `post_id` = '" . esc_sql($key) . "' AND `meta_key` = '" . $wpdb->escape($amSchedule) . "'";
$wpdb->get_results($sql);
$redatedShedule[] = $gmtDate;
}
}
if (count($redatedShedule) > 0) {
// Update End Date
$dates['end'] = date('Y-m-d H:i:s', strtotime(end($redatedShedule) . '+1 month'));
$subscription->update_dates($dates);
$order = new WC_Order($order_id);
$order->add_order_note("Subscription has been manually re-dated to: <br/>" . implode('<br>', $redatedShedule));
}
}
return $order_id;
// wp_cache_delete($post_id, 'posts');
} catch (Exception $e) {
wcs_add_admin_notice($e->getMessage(), 'error');
}
}
}
add_action('add_meta_boxes', 'ChiChi_SubscriptionMetaBoxes::redateSchedule', 26);
add_action('woocommerce_before_save_order_items', 'ChiChi_SubscriptionMetaBoxes::save', 10, 1);
let me know please if someone spots any issue. The code itself is commented so you know what the specific sections of code are doing.
thanks
I have an issue where I need to data from a RETS server and populate it on the database, I was able to get all but two tables to properly automate this data in, but I'm having issues with the last (and biggest) two. After looking at it, the issue is timeout with the server, it cannot finish in time for the database to populate.
I am working off of a godaddy server and already have the maximum time I can set for the program to run, the only thing I can do now is figure out a way to speed up my code so it finishes in time, and would like some help figuring that out.
The code (posted below) was modified to fit my needs from here: https://github.com/coreyrowell/retshelper/blob/master/rets_helper.php
While it works well and I was able to get it working, I haven't been able to figure out the best way to speed it up. Any help would be sincerely appreciated.
<?php
/*
.---------------------------------------------------------------------------.
| Software: RETSHELPER - PHP Class to interface RETS with Database |
| Version: 1.0 |
| Contact: corey#coreyrowell.com |
| Info: None |
| Support: corey#coreyrowell.com |
| ------------------------------------------------------------------------- |
| Author: Corey Rowell - corey#coreyrowell.com |
| Copyright (c) 2013, Corey Rowell. All Rights Reserved. |
| ------------------------------------------------------------------------- |
| License: This content is released under the |
| (http://opensource.org/licenses/MIT) MIT License. | |
'---------------------------------------------------------------------------'
*/
/*
.---------------------------------------------------------------------------.
| This software requires the use of the PHPRETS library |
| http://troda.com/projects/phrets/ |
'---------------------------------------------------------------------------'
*/
define("BASE_PATH",dirname(__FILE__)."/");
ini_set('mysql.connect_timeout',0);
ini_set('default_socket_timeout',0);
class RETSHELPER
{
// Defaults
private $rets, $auth, $config, $database, $mysqli, $data, $log, $scriptstart, $scriptend,
$previous_start_time, $current_start_time, $updates_log, $active_ListingRids = array();
public function __construct()
{
// Require PHRETS library
require_once("phrets.php");
// Start rets connection
$this->rets = new phRETS;
$this->scriptstart = date("m-d-y_h-i-s", time());
// RETS Server Info
$this->auth['url'] = 'redacted';//MLS_URL;//MLS_URL;
$this->auth['username'] = 'redacted'; //MLS_USERNAME;
$this->auth['password'] = 'redacted'; //MLS_PASS;
$this->auth['retsversion'] = ''; //USER Agent Version
$this->auth['useragent'] = ''; //USER Agent
// RETS Options
$this->config['property_classes'] = array("A");//,"B","C","D","E","F");
$this->config['KeyField'] = "LIST_1";
$this->config['offset_support'] = TRUE; // Enable if RETS server supports 'offset'
$this->config['useragent_support'] = FALSE;
$this->config['images_path'] = BASE_PATH."listing_photos/";
$this->config['logs_path'] = BASE_PATH."logs/";
$this->config['start_times_path'] = BASE_PATH."logs/";
$this->config['previous_start_time'] = $this->get_previous_start_time();
$this->config['create_tables'] = FALSE; // Create tables for classes (terminates program)
// Log to screen?
$this->config['to_screen'] = TRUE;
// Database Config
$this->database['host'] = 'redacted'; //DB_SERVER;
$this->database['username'] = 'redacted'; //DB_USER;
$this->database['password'] = 'redacted'; //DB_PASS;
$this->database['database'] = 'redacted'; //DB_NAME;
$this->config_init();
// Load the run function
$this->run();
}
private function config_init()
{
// Set offset support based on config
if($this->config['offset_support'])
{
$this->rets->SetParam("offset_support", true);
} else {
$this->rets->SetParam("offset_support", false);
}
if($this->config['useragent_support'])
{
$this->rets->AddHeader("RETS-Version", $this->auth['retsversion']);
$this->rets->AddHeader("User-Agent", $this->auth['useragent']);
}
}
public function run()
{
// Start Logging
$this->logging_start();
// RETS Connection
$this->connect();
// Connect to Database
$this->database_connect();
if($this->config['create_tables'])
{
$this->log_data("Creating database tables, program will exit after finishing.");
foreach ($this->config['property_classes'] as $class)
{
$this->log_data("Creating table for: " . $class);
$this->create_table_for_property_class($class);
}
$this->log_data("Exiting program.");
return;
}
// Get Properties (and images)
$this->get_properties_by_class();
// Close RETS Connection
$this->disconnect();
// Delete inactive listings
$this->database_delete_records();
// Insert new listings
$this->database_insert_records();
// Disconnect from Database
$this->database_disconnect();
// End Logging
$this->logging_end();
// Time for next scheduled update
$this->set_previous_start_time();
}
private function connect()
{
$this->log_data("Connecting to RETS...");
// Connect to RETS
$connect = $this->rets->Connect($this->auth['url'], $this->auth['username'], $this->auth['password']);
if($connect)
{
$this->log_data("Successfully connected to RETS.");
return TRUE;
} else {
$error = $this->rets->Error();
if($error['text'])
{
$error = $error['text'];
} else {
$error = "No error message returned from RETS. Check RETS debug file.";
}
$this->log_error("Failed to connect to RETS.\n".$error);
die();
}
}
private function get_properties_by_class()
{
$this->log_data("Getting Classes...");
foreach ($this->config['property_classes'] as $class)
{
$this->log_data("Getting Class: ".$class);
// Set
$fields_order = array();
$mod_timestamp_field = $this->get_timestamp_field($class);
$previous_start_time = $this->config['previous_start_time'];
$search_config = array('Format' => 'COMPACT-DECODED', 'QueryType' => 'DMQL2', 'Limit'=> 1000, 'Offset' => 1, 'Count' => 1);
/*--------------------------------------------------------------------------------.
| |
| If you're having problems, they probably lie here in the $query and/or $search. |
| |
'--------------------------------------------------------------------------------*/
// Query
$query = "({$mod_timestamp_field}=2016-09-16T00:00:00-2016-09-16T01:00:00)";//{$previous_start_time}+)";
// Run Search
$search = $this->rets->SearchQuery("Property", $class, $query, $search_config);
// Get all active listings
$query_all = "({$mod_timestamp_field}=1980-01-01T00:00:00+)";
$search_all = $this->rets->SearchQuery("Property", $class, $query_all, array('Format'=>'COMPACT', 'Select'=>$this->config['KeyField']));
$tmpArray = array();
while($active_rid = $this->rets->FetchRow($search_all)) {
array_push($tmpArray, $active_rid[$this->config['KeyField']]);
}
$this->active_ListingRids['property_'.strtolower($class)] = $tmpArray;
$data = array();
if ($this->rets->NumRows($search) > 0)
{
// Get columns
$fields_order = $this->rets->SearchGetFields($search);
$this->data['headers'] = $fields_order;
// Process results
while ($record = $this->rets->FetchRow($search))
{
$this_record = array();
// Loop it
foreach ($fields_order as $fo)
{
$this_record[$fo] = $record[$fo];
}
$ListingRid = $record[$this->config['KeyField']];
$data[] = $this_record;
}
}
// Set data
$this->data['classes'][$class] = $data;
$this->log_data("Finished Getting Class: ".$class . "\nTotal found: " .$this->rets->TotalRecordsFound());
// Free RETS Result
$this->rets->FreeResult($search);
}
}
private function get_timestamp_field($class)
{
$class = strtolower($class);
switch($class)
{
case 'a':
$field = "LIST_87";
break;
}
return $field;
}
private function disconnect()
{
$this->log_data("Disconnected from RETS.");
$this->rets->Disconnect();
}
private function database_connect()
{
$this->log_data("Connecting to database...");
$host = $this->database['host'];
$username = $this->database['username'];
$password = $this->database['password'];
$database = $this->database['database'];
// Create connection
$this->mysqli = new mysqli($host, $username, $password, $database);
// Throw error if connection fails
if ($this->mysqli->connect_error) {
$this->log_error("Database Connection Error". $this->mysqli->connect_error);
die('Connect Error (' . $this->mysqli->connect_errno . ') '
. $this->mysqli->connect_error);
}
}
private function database_delete_records()
{
$this->log_data("Updating database...");
// Loop through each table and update
foreach($this->config['property_classes'] as $class)
{
// Get Tables
$table = "rets_property_".strtolower($class);
$activeListings = $this->active_ListingRids['property_'.strtolower($class)];
$sql = "DELETE FROM {$table} WHERE {$this->config['KeyField']} NOT IN (".implode(',', $activeListings).");";
$this->mysqli->query($sql);
if($this->mysqli->affected_rows > 0)
{
$this->log_data("Deleted {$this->mysqli->affected_rows} Listings.");
// return TRUE;
} else if($this->mysqli->affected_rows == 0) {
$this->log_data("Deleted {$this->mysqli->affected_rows} Listings.");
} else {
$this->log_data("Deleting database records failed \n\n" . mysqli_error($this->mysqli));
// return FALSE;
}
}
}
private function database_insert_records()
{
$this->log_data("Inserting records...");
foreach($this->config['property_classes'] as $class)
{
// Get Tables
$table = "rets_property_".strtolower($class);
// Get data
$data_row = $this->data['classes'][$class];
// Defaults
$total_rows = 0;
$total_affected_rows = 0;
// Loop through data
foreach($data_row as $drow)
{
// Clean data
// replace empty with NULL
// and wrap data in quotes
$columns = array();
$values = array();
foreach($drow as $key => $val)
{
if($val === '')
{
$val = '""';
} else {
$val = mysqli_real_escape_string($this->mysqli ,$val);
$val = "'$val'";
}
$columns[] = $key;
$values[] = $val;
}
// Implode data rows with commas
$values = implode(', ', $values);
$columns = implode(', ', $columns);
// Build SQL
$sql = "REPLACE INTO {$table} ({$columns}) VALUES ({$values})";
// Do query
$this->mysqli->query($sql);
if($this->mysqli->affected_rows > 0)
{
$total_affected_rows++;
} else {
$this->log_error("Failed to insert the following record: ".$sql . "\n\n" . mysqli_error($this->mysqli));
}
$total_rows++;
}
$this->log_data("Done inserting data. ".$class."\nTotal Records: ".$total_rows." .\nTotal Inserted: ".$total_affected_rows);
}
}
private function database_disconnect()
{
$this->log_data("Database disconnected...");
// Close connection
$this->mysqli->close();
}
private function create_table_for_property_class($class)
{
// gets resource information. need this for the KeyField
$rets_resource_info = $this->rets->GetMetadataInfo();
$resource = "Property";
// pull field format information for this class
$rets_metadata = $this->rets->GetMetadata($resource, $class);
$table_name = "rets_".strtolower($resource)."_".strtolower($class);
// i.e. rets_property_resi
$sql = $this->create_table_sql_from_metadata($table_name, $rets_metadata, $rets_resource_info[$resource]['KeyField']);
$this->mysqli->query($sql);
}
private function create_table_sql_from_metadata($table_name, $rets_metadata, $key_field, $field_prefix = "")
{
$sql_query = "CREATE TABLE {$table_name} (\n";
foreach ($rets_metadata as $field) {
$field['SystemName'] = "`{$field_prefix}{$field['SystemName']}`";
$cleaned_comment = addslashes($field['LongName']);
$sql_make = "{$field['SystemName']} ";
if ($field['Interpretation'] == "LookupMulti") {
$sql_make .= "TEXT";
}
elseif ($field['Interpretation'] == "Lookup") {
$sql_make .= "VARCHAR(50)";
}
elseif ($field['DataType'] == "Int" || $field['DataType'] == "Small" || $field['DataType'] == "Tiny") {
$sql_make .= "INT({$field['MaximumLength']})";
}
elseif ($field['DataType'] == "Long") {
$sql_make .= "BIGINT({$field['MaximumLength']})";
}
elseif ($field['DataType'] == "DateTime") {
$sql_make .= "DATETIME default '0000-00-00 00:00:00' not null";
}
elseif ($field['DataType'] == "Character" && $field['MaximumLength'] <= 255) {
$sql_make .= "VARCHAR({$field['MaximumLength']})";
}
elseif ($field['DataType'] == "Character" && $field['MaximumLength'] > 255) {
$sql_make .= "TEXT";
}
elseif ($field['DataType'] == "Decimal") {
$pre_point = ($field['MaximumLength'] - $field['Precision']);
$post_point = !empty($field['Precision']) ? $field['Precision'] : 0;
$sql_make .= "DECIMAL({$field['MaximumLength']},{$post_point})";
}
elseif ($field['DataType'] == "Boolean") {
$sql_make .= "CHAR(1)";
}
elseif ($field['DataType'] == "Date") {
$sql_make .= "DATE default '0000-00-00' not null";
}
elseif ($field['DataType'] == "Time") {
$sql_make .= "TIME default '00:00:00' not null";
}
else {
$sql_make .= "VARCHAR(255)";
}
$sql_make .= " COMMENT '{$cleaned_comment}'";
$sql_make .= ",\n";
$sql_query .= $sql_make;
}
$sql_query .= "`Photos` TEXT COMMENT 'Photos Array', ";
$sql_query .= "PRIMARY KEY(`{$field_prefix}{$key_field}`) )";
return $sql_query;
}
private function get_previous_start_time()
{
$filename = "previous_start_time_A.txt";
// See if file exists
if(file_exists($this->config['start_times_path'].$filename))
{
$time=time();
$this->updates_log = fopen($this->config['start_times_path'].$filename, "r+");
$this->previous_start_time = fgets($this->updates_log);
$this->current_start_time = date("Y-m-d", $time) . 'T' . date("H:i:s", $time);
} else {
// Create file
$this->updates_log = fopen($this->config['start_times_path'].$filename, "w+");
fwrite($this->updates_log, "1980-01-01T00:00:00\n");
$this->get_previous_start_time();
}
// fgets reads up to & includes the first newline, strip it
return str_replace("\n", '', $this->previous_start_time);
}
private function set_previous_start_time()
{
$file = $this->config['start_times_path'] . "previous_start_time_A.txt";
$file_data = $this->current_start_time."\n";
$file_data .= file_get_contents($file);
file_put_contents($file, $file_data);
}
private function logging_start()
{
$filename = "Log".date("m-d-y_h-i-s", time()).".txt";
// See if file exists
if(file_exists($this->config['logs_path'].$filename))
{
$this->log = fopen($this->config['logs_path'].$filename, "a");
} else {
// Create file
$this->log = fopen($this->config['logs_path'].$filename, "w+");
}
}
private function log_data($data)
{
$write_data = "\nInfo Message: [".date("m/d/y - h:i:s", time())."]\n------------------------------------------------\n";
$write_data .= $data."\n";
$write_data .= "\n------------------------------------------------\n";
fwrite($this->log, $write_data);
if($this->config['to_screen'])
{
echo str_replace(array("\n"), array('<br />'), $write_data);
}
}
private function log_error($error)
{
$write_data = "\nError Message: [".date("m/d/y - h:i:s", time())."]\n------------------------------------------------\n";
$write_data .= $error."\n";
$write_data .= "\n------------------------------------------------\n";
fwrite($this->log, $write_data);
if($this->config['to_screen'])
{
echo str_replace(array("\n"), array('<br />'), $write_data);
}
}
private function logging_end()
{
$this->scriptend = date("m-d-y_h-i-s", time());
$this->log_data("Closing log file.\n
Start Time: {$this->scriptstart}\n
End Time: {$this->scriptend}");
fclose($this->log);
}
}
// Load the class
$retshelper = new RETSHELPER;
Sorry for the wall of code; I would shorten it down but I'm at a loss with what is still needed and what isn't. Once again, any help would or a point into the right direction would be appreciated.
Here is the snippet of code in question:
function hoursearned_func($user) {
$key = 'Service Hours Earned';
if(isset($user[$key])) {
$result = $user[$key];
}
return "Service Hours Earned: ".$result." Hours";
}
add_shortcode('hoursearned', 'hoursearned_func');
This small function simply returns the value of an array given the key, but when calling the shortcode, [hoursearned], it only displays:
Service Hours Earned: Hours
rather than:
Service Hours Earned: 200 Hours
Where 200 is a string that is returned by the function hoursearned_func given $user.
For some reason Wordpress is not passing the returned variables from the functions to the shortcodes. How can I get Wordpress to show the result from the function?
Here is the full code if that helps... (note that all of this is being loaded as a plugin)
//Dump CSV file (SalesForce Report) to php array to be parsed..
add_action('dump_csv_array', 'dump_csv_array', 10);
function dump_csv_array(){
$data = array();
$header = NULL;
if (($file = fopen('http://blah.com/info.csv', 'r')) !==FALSE) { //The link to the CSV is insignificant
while (($row = fgetcsv($file, 1000, ",")) !==FALSE) {
if(!$header)
$header = $row;
else
$data[] = array_combine($header, $row);
}
fclose($file);
}
return $data;
}
$multiarray = (array) dump_csv_array();
global $current_user;
get_currentuserinfo();
$user_email = $current_user->user_email;
//Parses the multidimensional array of Dumped CSV info. Looks up the current user's email and returns a single array of the current user's SalesForce information.
function parse_array($multiarray, $user_email){
$array = (array) $multiarray;
$email = $user_email;
if(is_user_logged_in() === true ) {
foreach($array as $subarray) {
if(isset($subarray['Email']) && $subarray['Email'] == $email) {
$data = $subarray;
}
}
}
else {
return NULL;
}
return $data;
}
$user = parse_array($multiarray, $user_email);
//Defines Shortcodes and their Functions
function hoursearned_func($user) {
$key = 'Service Hours Earned';
if(isset($user[$key])) {
$result = $user[$key];
}
return "Service Hours Earned: ".$result." Hours";
}
function hoursawarded_func($user) {
$key = 'Service Hours Awarded';
if(isset($user[$key])) {
$result = $user[$key];
}
return "Service Hours Awarded: ".$result." Hours";
}
function rank_func($user) {
$key = 'Rank';
if(isset($user[$key])) {
$result = $user[$key];
}
return "Rank: ".$result;
}
function memstatus_func($user) {
$key = 'Membership Status';
if(isset($user[$key])) {
$result = $user[$key];
}
return "Status: ".$result;
}
function register($atts) {
add_shortcode( 'hoursearned', 'hoursearned_func');
add_shortcode( 'hoursawarded', 'servicehours_func');
add_shortcode( 'rank', 'rank_func');
add_shortcode( 'memstatus', 'memstatus_func');
}
add_action('init', 'register');
var_dump(hoursearned_func($user));
Try to create a shortcode with attributes, (or) retrieve the $user data inside the shortcode's function and set them as default values.
function example_func($atts) {
$user = get_user_array(); //Retrieve the data
$atts = shortcode_atts($user, $atts);
return 'example: ' . $atts['foo'] . ' ' . $atts['bar'];
}
add_shortcode('example', 'example_func');
Have a look at the Shortcode API it basically explains everything.
As of November 17, 2014 Google announced they shutdown the google calendar API v1,v2.
See this link:
http://googleappsupdates.blogspot.com/2014/06/calendar-gdata-api-google-calendar.html
A couple years ago we built a php web form to input data into the calendar with ZEND framework.
With the current code now not working and getting this error.
Error: Expected response code 200, got 403
Forbidden
Error 403
This is very frustrating because we need this application working on the website, its basically the whole point of even visiting the site in the first place.
The php form was pretty simple. Basically a visitor would enter their zip code, then choose a day and time that is displayed from the "availability calendar" on their gmail calendar account. There was also two more custom calendar that was for booked online, and internal booking purposes. Once someone completed the steps including input forms with their contact information and hitting submit the "availability calendar" would be updated on their site as booked and the google calendar itself.
It would also send en email notifying you booked.
I am not personally familiar with ZEND and Google Cal APIv3. I have a level of understanding with php/css/etc but not deep enough to go through the entire upgrade process.
I was hoping maybe it was something pretty easy and someone here on StackOverflow that has a strong knowledge with this material can help me with.
It seems I have read their forums and many, many, many people are frustrated with the shutdown of v1,v2.
Would I need to upgrade the ZEND framework? Currently it is 1.11.3, or can I leave that alone.
I have read that the point of v3 is to make writing the code easier, so maybe this isn't to difficult of a task... Here is the code on the first step.
<?php
function setEnvironment() {
session_start();
date_default_timezone_set('America/New_York');
}
setEnvironment();
function setup() {
set_include_path("/var/www/vhosts/mydomainexample.com/httpdocs/");
require_once("Zend/Loader.php");
Zend_Loader::loadClass("Zend_Gdata");
Zend_Loader::loadClass("Zend_Gdata_ClientLogin");
Zend_Loader::loadClass("Zend_Gdata_Calendar");
}
//////////////////////////////////////////////////
// //
// CONNECT TO GOOGLE CALENDAR //
// //
//////////////////////////////////////////////////
function connect() {
global $service;
$user = "mygmailexample#gmail.com";
$pass = "mypasswordexample";
$serviceName = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $serviceName);
$service = new Zend_Gdata_Calendar($client);
}
//////////////////////////////////////////////////
// //
// CREATE EVENT AND ADD TO CALENDAR //
// //
//////////////////////////////////////////////////
function bookAppointment() {
global $service;
$title = "ONLINE BOOKING: " . $_SESSION["fullName"] . " , " . $_SESSION["townCity"];
$content .= "Name: " . $_SESSION["fullName"] . "\n\n";
$content .= "Requested Time: " . date("l M jS g:i A",$_SESSION["s"]) . " - " . date("g:i A",$_SESSION["e"]) . "\n\n";
$content .= "Home Phone: " . $_SESSION["homePhone"] . "\n\n";
$content .= "Email: " . $_SESSION["emailAddress"] . "\n\n";
$content .= "Address: \n\n" . $_SESSION["streetAddress"] . "\n";
$content .= "" . $_SESSION["townCity"] . " ";
$content .= "" . $_SESSION["zipCode"] . "\n\n";
$content .= "" . $_SESSION["jobDescription"] . "\n\n";
$event = $service->newEventEntry();
$event->title = $service->newTitle($title);
$event->content = $service->newContent($content);
$when = $service->newWhen();
$when->startTime = date(DateTime::RFC3339,$_SESSION["s"]);
$when->endTime = date(DateTime::RFC3339,$_SESSION["e"]);
$event->when = array($when);
$newEvent = $service->insertEvent($event,"http://www.google.com/calendar/feeds/o8d31pro7mbgbi2g93acsluhn8#group.calendar.google.com/private/full");
$eventUri = $newEvent->id->text;
$to = "example#example.com";
$subject = $title;
$message = $content;
$headers = 'From: ' . $_SESSION["emailAddress"] . "\r\n" .
'Reply-To: ' . $_SESSION["emailAddress"] . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
$to = $_SESSION["emailAddress"];
$subject = "BOOKED:";
$message = "Thank you for booking an appointment with example! We look forward to seeing you and may contact you one more time to confirm before we travel to your location.\n\n" . $content;
$headers = "From: example <example#example.com>\r\n" .
"Reply-To: Lalaland Tan <example#example.com>\r\n" .
"X-Mailer: PHP/" . phpversion();
mail($to, $subject, $message, $headers);
}
//////////////////////////////////////////////////
// //
// GET SCHEDULE AND AVAILABILITY FROM GOOGLE //
// //
//////////////////////////////////////////////////
function getSchedule() {
global $service, $timeSlotsByDay;
$query = $service->newEventQuery();
$query->setVisibility("private");
$query->setProjection("full");
$query->setOrderby("starttime");
$query->setSortOrder('ascending');
$query->setStartMin(date(DateTime::RFC3339));
$query->setStartMax(date(DateTime::RFC3339,(time()+2678400)));
$query->setSingleEvents("true");
$query->setMaxResults(999);
$query->setUser("exampleurl#group.calendar.google.com");
try {
$internalBookings = $service->getCalendarEventFeed($query);
} catch (Zend_Gdata_App_Exception $e) {
echo "Error: " . $e->getMessage();
}
$query->setUser("exampleurl#group.calendar.google.com");
try {
$onlineBookings = $service->getCalendarEventFeed($query);
} catch (Zend_Gdata_App_Exception $e) {
echo "Error: " . $e->getMessage();
}
$query->setUser("exampleurl#group.calendar.google.com");
try {
$availableSlots = $service->getCalendarEventFeed($query);
} catch (Zend_Gdata_App_Exception $e) {
echo "Error: " . $e->getMessage();
}
$timeSlotsByDay = array();
foreach ($availableSlots as $timeSlot) {
$slotStart = strtotime($timeSlot->when[0]->starttime);
$slotEnd = strtotime($timeSlot->when[0]->endtime);
$available = true;
foreach ($internalBookings as $event) {
if ( $available ) {
$bookingStart = strtotime($event->when[0]->starttime);
$bookingEnd = strtotime($event->when[0]->endtime);
if ( ( $bookingStart >= $slotStart ) && ( $bookingStart < $slotEnd ) ) {
$available = false;
}
if ( ( $bookingEnd > $slotStart ) && ( $bookingEnd <= $slotEnd ) ) {
$available = false;
}
if ( ( $bookingStart <= $slotStart ) && ( $bookingEnd >= $slotEnd ) ) {
$available = false;
}
}
}
foreach ($onlineBookings as $event) {
if ( $available ) {
$bookingStart = strtotime($event->when[0]->starttime);
$bookingEnd = strtotime($event->when[0]->endtime);
if ( ( $bookingStart >= $slotStart ) && ( $bookingStart < $slotEnd ) ) {
$available = false;
}
if ( ( $bookingEnd > $slotStart ) && ( $bookingEnd <= $slotEnd ) ) {
$available = false;
}
}
}
$timeSlotsByDay[date("Ymd",strtotime($timeSlot->when[0]->starttime))][] = array("start"=>$slotStart,"end"=>$slotEnd,"available"=>$available);
}
}
//////////////////////////////////////////////////
// //
// STORE FORM DATA IN SESSION //
// //
//////////////////////////////////////////////////
function sessTimeSlot() {
$_SESSION["s"] = $_GET["s"];
$_SESSION["e"] = $_GET["e"];
}
function sessJobDetails() {
$_SESSION["fullName"] = $_POST["fullName"];
$_SESSION["homePhone"] = $_POST["homePhone"];
$_SESSION["emailAddress"] = $_POST["emailAddress"];
$_SESSION["streetAddress"] = $_POST["streetAddress"];
$_SESSION["townCity"] = $_POST["townCity"];
$_SESSION["zipCode"] = $_POST["zipCode"];
$_SESSION["jobDescription"] = $_POST["jobDescription"];
}
?>
you can't use Zend anymore to list, add, delete event. You have to use google api v3.
Here is an example of class you can use to manage events:
Authentification Zend Gdata (403 forbidden)
i using a wordpress plugin, i notice that returns a error on
$alias = (string)end(array_keys($settings));
above line .the error is
PHP Strict Standards: Only variables should be passed by reference in on wordpress function
i added that function below. anyone know how to solve that error please, becoz admin dashboard of the plugin not loading because of this error.
/*
* GET modules lists
*/
function load_modules ()
{
$folder_path = $this->cfg['paths']['plugin_dir_path'] . 'modules/';
$cfgFileName = 'config.php';
// static usage, modules menu order
$menu_order = array();
foreach(glob($folder_path . '*/' . $cfgFileName) as $module_config ){
$module_folder = str_replace($cfgFileName, '', $module_config);
// Turn on output buffering
ob_start();
if( is_file( $module_config ) ) {
require_once( $module_config );
}
$settings = ob_get_clean(); //copy current buffer contents into $message variable and delete current output buffer
if(trim($settings) != "") {
$settings = json_decode($settings, true);
$alias = (string) end(array_keys($settings));
// create the module folder URI
// fix for windows server
$module_folder = str_replace( DIRECTORY_SEPARATOR, '/', $module_folder );
$__tmpUrlSplit = explode("/", $module_folder);
$__tmpUrl = '';
$nrChunk = count($__tmpUrlSplit);
if($nrChunk > 0) {
foreach ($__tmpUrlSplit as $key => $value){
if( $key > ( $nrChunk - 4) && trim($value) != ""){
$__tmpUrl .= $value . "/";
}
}
}
// get the module status. Check if it's activate or not
$status = false;
// default activate all core modules
if(in_array( $alias, $this->cfg['core-modules'] )) {
$status = true;
}else{
// activate the modules from DB status
$db_alias = $this->alias . '_module_' . $alias;
if(get_option($db_alias) == 'true'){
$status = true;
}
}
// push to modules array
$this->cfg['modules'][$alias] = array_merge(array(
'folder_path' => $module_folder,
'folder_uri' => $this->cfg['paths']['plugin_dir_url'] . $__tmpUrl,
'db_alias' => $this->alias . '_' . $alias,
'status' => $status
), $settings );
// add to menu order arrayhttp://cc.aa-team.com/wp-plugins/smart-seo-v2/wp-admin/admin-ajax.php?action=pspLoadSection§ion=Social_Stats
if(!isset($this->cfg['menu_order'][(int)$settings[$alias]['menu']['order']])){
$this->cfg['menu_order'][(int)$settings[$alias]['menu']['order']] = $alias;
}else{
// add the menu to next free key
$this->cfg['menu_order'][] = $alias;
}
// add module to activate modules array
if($status == true){
$this->cfg['activate_modules'][$alias] = true;
}
// load the init of current loop module
if( $status == true && isset( $settings[$alias]['module_init'] ) ){
if( is_file($module_folder . $settings[$alias]['module_init']) ){
//if( is_admin() ) {
$current_module = array($alias => $this->cfg['modules'][$alias]);
require_once( $module_folder . $settings[$alias]['module_init'] );
//}
}
}
}
}
// order menu_order ascendent
ksort($this->cfg['menu_order']);
}
End rereceives value by reference, but result of function is not variable.
You could rewrite your code.
$array_keys = array_keys($settings);
$alias = (string)end($array_keys);
unset($array_keys);