Woocommerce hook not triggering emails for custom statuses - wordpress

I've registered custom order statuses in a plugin I'm working on, but I can't get emails to fire when moving in or out of one of these statuses. (including to/from a core status, ie. the processing/completed emails don't fire when moving from a custom status).
I've registered every possible combination of actions I can think of (excluding on-hold and pending, based on our use case)
Can anyone tell me what I'm missing please?
Initial class:
<?php
/**
* #author BAKKBONE Australia
* #package Bkf_WC_Email
* #license GNU General Public License (GPL) 3.0
**/
if ( ! defined( 'ABSPATH' ) ) {
return;
}
/**
* Class Bkf_WC_Email
*/
class Bkf_WC_Email {
/**
* Bkf_WC_Email constructor.
*/
public function __construct() {
add_action( 'woocommerce_email_classes', array( $this, 'bkf_register_email' ), 90, 1 );
define( 'CUSTOM_WC_EMAIL_PATH', plugin_dir_path( __FILE__ ) );
add_filter('woocommerce_email_actions', array($this, 'bkf_woocommerce_email_actions'), 10, 1);
}
/**
* #param array $emails
*
* #return array
*/
public function bkf_register_email( $emails ) {
$emails['WC_Email_Customer_Scheduled_Order'] = include __DIR__ . 'emails/class-wc-customer-scheduled-order.php';
$emails['WC_Email_Customer_Prepared_Order'] = include __DIR__ . 'emails/class-wc-customer-made-order.php';
$emails['WC_Email_Customer_Out_for_Delivery_Order'] = include __DIR__ . 'emails/class-wc-customer-out-order.php';
return $emails;
}
public function bkf_woocommerce_email_actions($actions)
{
$actions[] = 'woocommerce_order_status_scheduled';
$actions[] = 'woocommerce_order_status_made';
$actions[] = 'woocommerce_order_status_out';
$actions[] = 'woocommerce_order_status_relay';
$actions[] = 'woocommerce_order_status_processing';
$actions[] = 'woocommerce_order_status_completed';
$actions[] = 'woocommerce_order_status_scheduled_to_made';
$actions[] = 'woocommerce_order_status_scheduled_to_out';
$actions[] = 'woocommerce_order_status_scheduled_to_relay';
$actions[] = 'woocommerce_order_status_scheduled_to_processing';
$actions[] = 'woocommerce_order_status_scheduled_to_completed';
$actions[] = 'woocommerce_order_status_made_to_scheduled';
$actions[] = 'woocommerce_order_status_made_to_out';
$actions[] = 'woocommerce_order_status_made_to_relay';
$actions[] = 'woocommerce_order_status_made_to_processing';
$actions[] = 'woocommerce_order_status_made_to_completed';
$actions[] = 'woocommerce_order_status_out_to_scheduled';
$actions[] = 'woocommerce_order_status_out_to_made';
$actions[] = 'woocommerce_order_status_out_to_relay';
$actions[] = 'woocommerce_order_status_out_to_processing';
$actions[] = 'woocommerce_order_status_out_to_completed';
$actions[] = 'woocommerce_order_status_relay_to_scheduled';
$actions[] = 'woocommerce_order_status_relay_to_made';
$actions[] = 'woocommerce_order_status_relay_to_out';
$actions[] = 'woocommerce_order_status_relay_to_processing';
$actions[] = 'woocommerce_order_status_relay_to_completed';
$actions[] = 'woocommerce_order_status_processing_to_scheduled';
$actions[] = 'woocommerce_order_status_processing_to_made';
$actions[] = 'woocommerce_order_status_processing_to_out';
$actions[] = 'woocommerce_order_status_processing_to_relay';
$actions[] = 'woocommerce_order_status_processing_to_completed';
$actions[] = 'woocommerce_order_status_completed_to_scheduled';
$actions[] = 'woocommerce_order_status_completed_to_made';
$actions[] = 'woocommerce_order_status_completed_to_out';
$actions[] = 'woocommerce_order_status_completed_to_relay';
$actions[] = 'woocommerce_order_status_completed_to_processing';
$bkfoptions = get_option("bkf_options_setting");
if($bkfoptions["bkf_petals"] == "1") {
$actions[] = 'woocommerce_order_status_new';
$actions[] = 'woocommerce_order_status_accept';
$actions[] = 'woocommerce_order_status_reject';
$actions[] = 'woocommerce_order_status_scheduled_to_new';
$actions[] = 'woocommerce_order_status_scheduled_to_accept';
$actions[] = 'woocommerce_order_status_scheduled_to_reject';
$actions[] = 'woocommerce_order_status_made_to_new';
$actions[] = 'woocommerce_order_status_made_to_accept';
$actions[] = 'woocommerce_order_status_made_to_reject';
$actions[] = 'woocommerce_order_status_out_to_new';
$actions[] = 'woocommerce_order_status_out_to_accept';
$actions[] = 'woocommerce_order_status_out_to_reject';
$actions[] = 'woocommerce_order_status_relay_to_new';
$actions[] = 'woocommerce_order_status_relay_to_accept';
$actions[] = 'woocommerce_order_status_relay_to_reject';
$actions[] = 'woocommerce_order_status_processing_to_new';
$actions[] = 'woocommerce_order_status_processing_to_accept';
$actions[] = 'woocommerce_order_status_processing_to_reject';
$actions[] = 'woocommerce_order_status_completed_to_new';
$actions[] = 'woocommerce_order_status_completed_to_accept';
$actions[] = 'woocommerce_order_status_completed_to_reject';
$actions[] = 'woocommerce_order_status_new_to_scheduled';
$actions[] = 'woocommerce_order_status_new_to_made';
$actions[] = 'woocommerce_order_status_new_to_out';
$actions[] = 'woocommerce_order_status_new_to_relay';
$actions[] = 'woocommerce_order_status_new_to_processing';
$actions[] = 'woocommerce_order_status_new_to_completed';
$actions[] = 'woocommerce_order_status_new_to_accept';
$actions[] = 'woocommerce_order_status_new_to_reject';
$actions[] = 'woocommerce_order_status_accept_to_scheduled';
$actions[] = 'woocommerce_order_status_accept_to_made';
$actions[] = 'woocommerce_order_status_accept_to_out';
$actions[] = 'woocommerce_order_status_accept_to_relay';
$actions[] = 'woocommerce_order_status_accept_to_processing';
$actions[] = 'woocommerce_order_status_accept_to_completed';
$actions[] = 'woocommerce_order_status_accept_to_new';
$actions[] = 'woocommerce_order_status_accept_to_reject';
$actions[] = 'woocommerce_order_status_reject_to_scheduled';
$actions[] = 'woocommerce_order_status_reject_to_made';
$actions[] = 'woocommerce_order_status_reject_to_out';
$actions[] = 'woocommerce_order_status_reject_to_relay';
$actions[] = 'woocommerce_order_status_reject_to_processing';
$actions[] = 'woocommerce_order_status_reject_to_completed';
$actions[] = 'woocommerce_order_status_reject_to_new';
$actions[] = 'woocommerce_order_status_reject_to_accept';
}
return $actions;
}
}
new Bkf_WC_Email();
Specific email's class:
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( ! class_exists( 'WC_Email' ) ) {
return;
}
/**
* Class WC_Email_Customer_Out_for_Delivery_Order
*/
class WC_Email_Customer_Out_for_Delivery_Order extends WC_Email {
/**
* Create an instance of the class.
*
* #access public
* #return void
*/
function __construct() {
$this->id = 'customer_out_order';
$this->title = __( 'Order Out for Delivery', 'woocommerce' );
$this->description = __( 'An email sent to the customer when an order is out for delivery.', 'woocommerce' );
$this->customer_email = true;
$this->heading = __( 'Order Out for Delivery', 'woocommerce' );
$this->subject = sprintf( _x( '[%s] Order Out for Delivery', 'default email subject for out for delivery emails', 'woocommerce' ), '{blogname}' );
$this->template_html = 'emails/customer-out-order.php';
$this->template_plain = 'emails/plain/customer-out-order.php';
$this->template_base = CUSTOM_WC_EMAIL_PATH . 'templates/';
add_action( 'woocommerce_order_status_out', array( $this, 'trigger' ) );
parent::__construct();
}
/**
* Trigger Function that will send this email to the customer.
*
* #access public
* #return void
*/
function trigger( $order_id ) {
$this->object = wc_get_order( $order_id );
if ( version_compare( '3.0.0', WC()->version, '>' ) ) {
$order_email = $this->object->billing_email;
} else {
$order_email = $this->object->get_billing_email();
}
$this->recipient = $order_email;
if ( ! $this->is_enabled() || ! $this->get_recipient() ) {
return;
}
$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
}
/**
* Get content html.
*
* #access public
* #return string
*/
public function get_content_html() {
return wc_get_template_html( $this->template_html, array(
'order' => $this->object,
'email_heading' => $this->get_heading(),
'additional_content' => $this->get_additional_content(),
'sent_to_admin' => false,
'plain_text' => false,
'email' => $this
), '', $this->template_base );
}
/**
* Get content plain.
*
* #return string
*/
public function get_content_plain() {
return wc_get_template_html( $this->template_plain, array(
'order' => $this->object,
'email_heading' => $this->get_heading(),
'additional_content' => $this->get_additional_content(),
'sent_to_admin' => false,
'plain_text' => true,
'email' => $this
), '', $this->template_base );
}
}
return new WC_Email_Customer_Out_for_Delivery_Order();
I welcome any ideas :)

I think you are missing the triggers. Try to hook into woocommerce_order_status_changed action and fire your e-mails as you wish based on $from and $to statuses.
Here's a preview with 3 examples:
function custom_woocommerce_order_status_changed( $order_id, $from, $to, $order ) {
// Get all WC mailer emails
$wc_emails = WC()->mailer()->get_emails();
// Example A: Handle (from) 'my-custom-status' triggers
if( $from == 'my-custom-status' ) {
// Trigger 'completed' e-mail if changing to 'completed'
if( $to == 'completed' ) {
$wc_emails['WC_Email_Customer_Completed_Order']->trigger( $order_id );
}
}
// Example B: Handle (from) 'processing' triggers
if( $from == 'processing' ) {
// Trigger 'my-custom-status' e-mail if changing to 'my-custom-status'
if( $to == 'my-custom-status' ) {
$wc_emails['WC_Email_Customer_My_Custom_Status_Order']->trigger( $order_id );
}
}
// Example C: Handle (to) 'my-custom-status' triggers
// This will fire the email for every order changed to this status (whatever the $from status is)
if( $to == 'my-custom-status' ) {
$wc_emails['WC_Email_Customer_My_Custom_Status_Order']->trigger( $order_id );
}
}
add_action( 'woocommerce_order_status_changed', 'custom_woocommerce_order_status_changed', 20, 4 );
Note: Try to write these conditions as simply and straightforward as you can. Remember that if your order change scenario will be a duplicate, the e-mail will be also triggered (sent) multiple times.

Related

How to do email validation by blocking some email domain names in wordpress?

I need to validate an email field in gravity form. We have some known list of email domains and need to validate whether that domains present or not and If that domains present means we need to show the error message.
What is the best way to implement that? Any plugin suggestions?
This is possible with the GW_Email_Domain_Validator snippet here:
https://gravitywiz.com/banlimit-email-domains-for-gravity-form-email-fields/
Full snippet as of July 18, 2020 included here. Use the link above to get the latest version.
<?php
/**
* Gravity Wiz // Gravity Forms // Email Domain Validator
*
* This snippets allows you to exclude a list of invalid domains or include a list of valid domains for your Gravity Form Email fields.
*
* #version 1.4
* #author David Smith <david#gravitywiz.com>
* #license GPL-2.0+
* #link http://gravitywiz.com/banlimit-email-domains-for-gravity-form-email-fields/
*/
class GW_Email_Domain_Validator {
private $_args;
function __construct($args) {
$this->_args = wp_parse_args( $args, array(
'form_id' => false,
'field_id' => false,
'domains' => false,
'validation_message' => __( 'Sorry, <strong>%s</strong> email accounts are not eligible for this form.' ),
'mode' => 'ban' // also accepts "limit"
) );
// convert field ID to an array for consistency, it can be passed as an array or a single ID
if($this->_args['field_id'] && !is_array($this->_args['field_id']))
$this->_args['field_id'] = array($this->_args['field_id']);
$form_filter = $this->_args['form_id'] ? "_{$this->_args['form_id']}" : '';
add_filter("gform_validation{$form_filter}", array($this, 'validate'));
}
function validate($validation_result) {
$form = $validation_result['form'];
foreach($form['fields'] as &$field) {
// if this is not an email field, skip
if(RGFormsModel::get_input_type($field) != 'email')
continue;
// if field ID was passed and current field is not in that array, skip
if($this->_args['field_id'] && !in_array($field['id'], $this->_args['field_id']))
continue;
$page_number = GFFormDisplay::get_source_page( $form['id'] );
if( $page_number > 0 && $field->pageNumber != $page_number ) {
continue;
}
if( GFFormsModel::is_field_hidden( $form, $field, array() ) ) {
continue;
}
$domain = $this->get_email_domain($field);
// if domain is valid OR if the email field is empty, skip
if($this->is_domain_valid($domain) || empty($domain))
continue;
$validation_result['is_valid'] = false;
$field['failed_validation'] = true;
$field['validation_message'] = sprintf($this->_args['validation_message'], $domain);
}
$validation_result['form'] = $form;
return $validation_result;
}
function get_email_domain( $field ) {
$email = explode( '#', rgpost( "input_{$field['id']}" ) );
return trim( rgar( $email, 1 ) );
}
function is_domain_valid( $domain ) {
$mode = $this->_args['mode'];
$domain = strtolower( $domain );
foreach( $this->_args['domains'] as $_domain ) {
$_domain = strtolower( $_domain );
$full_match = $domain == $_domain;
$suffix_match = strpos( $_domain, '.' ) === 0 && $this->str_ends_with( $domain, $_domain );
$has_match = $full_match || $suffix_match;
if( $mode == 'ban' && $has_match ) {
return false;
} else if( $mode == 'limit' && $has_match ) {
return true;
}
}
return $mode == 'limit' ? false : true;
}
function str_ends_with( $string, $text ) {
$length = strlen( $string );
$text_length = strlen( $text );
if( $text_length > $length ) {
return false;
}
return substr_compare( $string, $text, $length - $text_length, $text_length ) === 0;
}
}
To only accept submissions from a given email domain you can do something like this:
new GW_Email_Domain_Validator( array(
'form_id' => 326,
'field_id' => 1,
'domains' => array( 'gmail.com', 'hotmail.com', '.co.uk' ),
'validation_message' => __( 'Oh no! <strong>%s</strong> email accounts are not eligible for this form.' ),
'mode' => 'limit'
) );

Can't able to get mobile number from user table wordpress

I am implementing the sms gateway plugin is called as a wp-sms. When new user signup or register the admin will get the notification and user information. Its working fine. But i can't able to get the user phone number there.
I used the nicename as a mobilenumber it stored the database correctly when i get the information for sms notification it displays the username. Can anyone tell me why it happens like that.
/**
* #param $user_id
*/
public function new_user( $user_id ) {
$user = get_userdata( $user_id );
$template_vars = array(
'%user_login%' => $user->user_login,
'%user_email%' => $user->user_email,
'%user_mobile%' => $user->user_nicename,
'%date_register%' => $this->date,
);
When i call the %user_mobile% it displays the user_login value. But in database it stores the mobile number. can anyone help me regarding this.
I used usermeta code like this but it returns empty value:
/**
* #param $user_id
*/
public function new_user( $user_id ) {
$user = get_userdata( $user_id );
$mobile = get_user_meta( $user_id, billing_phone, true );
$template_vars = array(
'%user_login%' => $user->user_login,
'%user_email%' => $user->user_email,
'%user_mobile%' =>$mobile,
'%date_register%' => $this->date,
);
My Full Code:
<?php
/**
* WP SMS notifications class
*
* #category class
* #package WP_SMS
* #version 1.0
*/
class WP_SMS_Notifications {
public $sms;
public $date;
public $options;
/**
* Wordpress Database
*
* #var string
*/
protected $db;
/**
* Wordpress Table prefix
*
* #var string
*/
protected $tb_prefix;
/**
* WP_SMS_Notifications constructor.
*/
public function __construct() {
global $wpsms_option, $sms, $wp_version, $wpdb, $table_prefix;
$this->sms = $sms;
$this->date = WP_SMS_CURRENT_DATE;
$this->options = $wpsms_option;
$this->db = $wpdb;
$this->tb_prefix = $table_prefix;
if ( isset( $this->options['notif_publish_new_post'] ) ) {
add_action( 'add_meta_boxes', array( $this, 'notification_meta_box' ) );
add_action( 'publish_post', array( $this, 'new_post' ), 10, 2 );
}
// Wordpress new version
if ( isset( $this->options['notif_publish_new_wpversion'] ) ) {
$update = get_site_transient( 'update_core' );
$update = $update->updates;
if ( isset( $update[1] ) ) {
if ( $update[1]->current > $wp_version and $this->sms->GetCredit() ) {
if ( get_option( 'wp_last_send_notification' ) == false ) {
$this->sms->to = array( $this->options['admin_mobile_number'] );
$this->sms->msg = sprintf( __( 'WordPress %s is available! Please update now', 'wp-sms' ), $update[1]->current );
$this->sms->SendSMS();
update_option( 'wp_last_send_notification', true );
}
} else {
update_option( 'wp_last_send_notification', false );
}
}
}
if ( isset( $this->options['notif_register_new_user'] ) ) {
add_action( 'user_register', array( $this, 'new_user' ), 10, 1 );
}
if ( isset( $this->options['notif_new_comment'] ) ) {
add_action( 'wp_insert_comment', array( $this, 'new_comment' ), 99, 2 );
}
if ( isset( $this->options['notif_user_login'] ) ) {
add_action( 'wp_login', array( $this, 'login_user' ), 99, 2 );
}
}
public function notification_meta_box() {
add_meta_box( 'subscribe-meta-box', __( 'SMS', 'wp-sms' ), array(
$this,
'notification_meta_box_handler'
), 'post', 'normal', 'high' );
}
/**
* #param $post
*/
public function notification_meta_box_handler( $post ) {
global $wpdb, $table_prefix;
$get_group_result = $wpdb->get_results( "SELECT * FROM `{$table_prefix}sms_subscribes_group`" );
$username_active = $wpdb->query( "SELECT * FROM {$table_prefix}sms_subscribes WHERE status = '1'" );
include_once dirname( __FILE__ ) . "/templates/wp-sms-meta-box.php";
}
/**
* #param $ID
* #param $post
*
* #return null
* #internal param $post_id
*/
public function new_post( $ID, $post ) {
if ( $_REQUEST['wps_send_subscribe'] == 'yes' ) {
if ( $_REQUEST['wps_subscribe_group'] == 'all' ) {
$this->sms->to = $this->db->get_col( "SELECT mobile FROM {$this->tb_prefix}sms_subscribes" );
} else {
$this->sms->to = $this->db->get_col( "SELECT mobile FROM {$this->tb_prefix}sms_subscribes WHERE group_ID = '{$_REQUEST['wps_subscribe_group']}'" );
}
$template_vars = array(
'%post_title%' => get_the_title( $ID ),
'%post_content%' => wp_trim_words( $post->post_content, 10 ),
'%post_url%' => wp_get_shortlink( $ID ),
'%post_date%' => get_post_time( 'Y-m-d', true, $ID, true ),
);
$message = str_replace( array_keys( $template_vars ), array_values( $template_vars ), $_REQUEST['wpsms_text_template'] );
$this->sms->msg = $message;
$this->sms->SendSMS();
}
}
/**
* #param $user_id
*/
public function new_user( $user_id ) {
$user = get_userdata( $user_id );
$mobile = get_user_meta( $user_id, 'billing_phone', true );
$template_vars = array(
'%user_login%' => $user->user_login,
'%user_email%' => $user->user_email,
'%user_mobile%' =>$mobile
'%date_register%' => $this->date,
);
// Send SMS to admin
$this->sms->to = array( $this->options['admin_mobile_number'] );
$message = str_replace( array_keys( $template_vars ), array_values( $template_vars ), $this->options['notif_register_new_user_admin_template'] );
$this->sms->msg = $message;
$this->sms->SendSMS();
// Send SMS to user register
if ( isset( $user->mobile ) ) {
$this->sms->to = array( $user->mobile );
$message = str_replace( array_keys( $template_vars ), array_values( $template_vars ), $this->options['notif_register_new_user_template'] );
$this->sms->msg = $message;
$this->sms->SendSMS();
}
}
/**
* #param $comment_id
* #param $comment_object
*/
public function new_comment( $comment_id, $comment_object ) {
if ( $comment_object->comment_type == 'order_note' ) {
return;
}
if ( $comment_object->comment_type == 'edd_payment_note' ) {
return;
}
$this->sms->to = array( $this->options['admin_mobile_number'] );
$template_vars = array(
'%comment_author%' => $comment_object->comment_author,
'%comment_author_email%' => $comment_object->comment_author_email,
'%comment_author_url%' => $comment_object->comment_author_url,
'%comment_author_IP%' => $comment_object->comment_author_IP,
'%comment_date%' => $comment_object->comment_date,
'%comment_content%' => $comment_object->comment_content
);
$message = str_replace( array_keys( $template_vars ), array_values( $template_vars ), $this->options['notif_new_comment_template'] );
$this->sms->msg = $message;
$this->sms->SendSMS();
}
/**
* #param $username_login
* #param $username
*/
public function login_user( $username_login, $username ) {
$this->sms->to = array( $this->options['admin_mobile_number'] );
$template_vars = array(
'%username_login%' => $username->user_login,
'%display_name%' => $username->display_name
);
$message = str_replace( array_keys( $template_vars ), array_values( $template_vars ), $this->options['notif_user_login_template'] );
$this->sms->msg = $message;
$this->sms->SendSMS();
}
}
new WP_SMS_Notifications();
/**
* WP SMS notifications class
*
* #category class
* #package WP_SMS
* #version 1.0
*/
class WP_SMS_Notifications {
public $sms;
public $date;
public $options;
/**
* Wordpress Database
*
* #var string
*/
protected $db;
/**
* Wordpress Table prefix
*
* #var string
*/
protected $tb_prefix;
/**
* WP_SMS_Notifications constructor.
*/
public function __construct() {
global $wpsms_option, $sms, $wp_version, $wpdb, $table_prefix;
$this->sms = $sms;
$this->date = WP_SMS_CURRENT_DATE;
$this->options = $wpsms_option;
$this->db = $wpdb;
$this->tb_prefix = $table_prefix;
if ( isset( $this->options['notif_publish_new_post'] ) ) {
add_action( 'add_meta_boxes', array( $this, 'notification_meta_box' ) );
add_action( 'publish_post', array( $this, 'new_post' ), 10, 2 );
}
// Wordpress new version
if ( isset( $this->options['notif_publish_new_wpversion'] ) ) {
$update = get_site_transient( 'update_core' );
$update = $update->updates;
if ( isset( $update[1] ) ) {
if ( $update[1]->current > $wp_version and $this->sms->GetCredit() ) {
if ( get_option( 'wp_last_send_notification' ) == false ) {
$this->sms->to = array( $this->options['admin_mobile_number'] );
$this->sms->msg = sprintf( __( 'WordPress %s is available! Please update now', 'wp-sms' ), $update[1]->current );
$this->sms->SendSMS();
update_option( 'wp_last_send_notification', true );
}
} else {
update_option( 'wp_last_send_notification', false );
}
}
}
if ( isset( $this->options['notif_register_new_user'] ) ) {
add_action( 'user_register', array( $this, 'new_user' ), 10, 1 );
}
if ( isset( $this->options['notif_new_comment'] ) ) {
add_action( 'wp_insert_comment', array( $this, 'new_comment' ), 99, 2 );
}
if ( isset( $this->options['notif_user_login'] ) ) {
add_action( 'wp_login', array( $this, 'login_user' ), 99, 2 );
}
add_action( 'user_register', array(this,'myplugin_registration_save'), 10, 1 );
}
public function notification_meta_box() {
add_meta_box( 'subscribe-meta-box', __( 'SMS', 'wp-sms' ), array(
$this,
'notification_meta_box_handler'
), 'post', 'normal', 'high' );
}
/**
* #param $post
*/
public function notification_meta_box_handler( $post ) {
global $wpdb, $table_prefix;
$get_group_result = $wpdb->get_results( "SELECT * FROM `{$table_prefix}sms_subscribes_group`" );
$username_active = $wpdb->query( "SELECT * FROM {$table_prefix}sms_subscribes WHERE status = '1'" );
include_once dirname( __FILE__ ) . "/templates/wp-sms-meta-box.php";
}
/**
* #param $ID
* #param $post
*
* #return null
* #internal param $post_id
*/
public function new_post( $ID, $post ) {
if ( $_REQUEST['wps_send_subscribe'] == 'yes' ) {
if ( $_REQUEST['wps_subscribe_group'] == 'all' ) {
$this->sms->to = $this->db->get_col( "SELECT mobile FROM {$this->tb_prefix}sms_subscribes" );
} else {
$this->sms->to = $this->db->get_col( "SELECT mobile FROM {$this->tb_prefix}sms_subscribes WHERE group_ID = '{$_REQUEST['wps_subscribe_group']}'" );
}
$template_vars = array(
'%post_title%' => get_the_title( $ID ),
'%post_content%' => wp_trim_words( $post->post_content, 10 ),
'%post_url%' => wp_get_shortlink( $ID ),
'%post_date%' => get_post_time( 'Y-m-d', true, $ID, true ),
);
$message = str_replace( array_keys( $template_vars ), array_values( $template_vars ), $_REQUEST['wpsms_text_template'] );
$this->sms->msg = $message;
$this->sms->SendSMS();
}
}
/**
* #param $user_id
*/
public function new_user( $user_id ) {
$user = get_userdata( $user_id );
$mobile = get_user_meta( $user_id, 'billing_phone', true );
$template_vars = array(
'%user_login%' => $user->user_login,
'%user_email%' => $user->user_email,
'%user_mobile%' =>$mobile,
'%date_register%' => $this->date,
);
// Send SMS to admin
$this->sms->to = array( $this->options['admin_mobile_number'] );
$message = str_replace( array_keys( $template_vars ), array_values( $template_vars ), $this->options['notif_register_new_user_admin_template'] );
$this->sms->msg = $message;
$this->sms->SendSMS();
// Send SMS to user register
if ( isset( $user->mobile ) ) {
$this->sms->to = array( $user->mobile );
$message = str_replace( array_keys( $template_vars ), array_values( $template_vars ), $this->options['notif_register_new_user_template'] );
$this->sms->msg = $message;
$this->sms->SendSMS();
}
}
/**
* #param $comment_id
* #param $comment_object
*/
public function new_comment( $comment_id, $comment_object ) {
if ( $comment_object->comment_type == 'order_note' ) {
return;
}
if ( $comment_object->comment_type == 'edd_payment_note' ) {
return;
}
$this->sms->to = array( $this->options['admin_mobile_number'] );
$template_vars = array(
'%comment_author%' => $comment_object->comment_author,
'%comment_author_email%' => $comment_object->comment_author_email,
'%comment_author_url%' => $comment_object->comment_author_url,
'%comment_author_IP%' => $comment_object->comment_author_IP,
'%comment_date%' => $comment_object->comment_date,
'%comment_content%' => $comment_object->comment_content
);
$message = str_replace( array_keys( $template_vars ), array_values( $template_vars ), $this->options['notif_new_comment_template'] );
$this->sms->msg = $message;
$this->sms->SendSMS();
}
/**
* #param $username_login
* #param $username
*/
public function login_user( $username_login, $username ) {
$this->sms->to = array( $this->options['admin_mobile_number'] );
$template_vars = array(
'%username_login%' => $username->user_login,
'%display_name%' => $username->display_name
);
$message = str_replace( array_keys( $template_vars ), array_values( $template_vars ), $this->options['notif_user_login_template'] );
$this->sms->msg = $message;
$this->sms->SendSMS();
}
public function myplugin_registration_save( $user_id ) {
if ( isset( $_POST['billing_phone'] ) )
update_user_meta($user_id, 'billing_phone', $_POST['billing_phone']);
}
}
new WP_SMS_Notifications();

wordpress I have class file which use for paypal express checkout Instead of express checkout i want to it replace to adaptive payment

/**
* Class PayPal
* #package Bookly\Lib\Payment
*/
class PayPal
{
// Array for cleaning PayPal request
static public $remove_parameters = array( 'action', 'token', 'PayerID', 'ab_fid', 'error_msg', 'type' );
/**
* The array of products for checkout
*
* #var array
*/
protected $products = array();
/**
* Send the Express Checkout NVP request
*
* #param $form_id
* #throws \Exception
*/
public function send_EC_Request( $form_id )
{
if ( !session_id() ) {
#session_start();
}
if ( ! count( $this->products ) ) {
throw new \Exception( 'Products not found!' );
}
$total = 0;
// create the data to send on PayPal
$data = array(
'SOLUTIONTYPE' => 'Sole',
'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
'PAYMENTREQUEST_0_CURRENCYCODE' => get_option( 'ab_currency' ),
'NOSHIPPING' => 1,
'RETURNURL' => add_query_arg( array( 'action' => 'ab-paypal-return', 'ab_fid' => $form_id ), Lib\Utils\Common::getCurrentPageURL() ),
'CANCELURL' => add_query_arg( array( 'action' => 'ab-paypal-cancel', 'ab_fid' => $form_id ), Lib\Utils\Common::getCurrentPageURL() )
);
foreach ( $this->products as $index => $product ) {
$data[ 'L_PAYMENTREQUEST_0_NAME' . $index ] = $product->name;
$data[ 'L_PAYMENTREQUEST_0_AMT' . $index ] = $product->price;
$data[ 'L_PAYMENTREQUEST_0_QTY' . $index ] = $product->qty;
$total += ( $product->qty * $product->price );
}
$data['PAYMENTREQUEST_0_AMT'] = $total;
$data['PAYMENTREQUEST_0_ITEMAMT'] = $total;
echo "<pre>";
print_r($data);
exit;
// send the request to PayPal
$response = self::sendNvpRequest( 'SetExpressCheckout', $data );
// Respond according to message we receive from PayPal
if ( 'SUCCESS' == strtoupper( $response['ACK'] ) || 'SUCCESSWITHWARNING' == strtoupper( $response['ACK'] ) ) {
//$paypalurl = 'https://www' . get_option( 'ab_paypal_ec_mode' ) . '.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=commit&token=' . urldecode( $response['TOKEN'] );
$paypalurl = 'https://www' . get_option( 'ab_paypal_ec_mode' ) . '.paypal.com/cgi-bin/webscr?cmd=_ap-payment&useraction=commit&token=' . urldecode( $response['TOKEN'] );
header( 'Location: ' . $paypalurl );
exit;
} else {
header( 'Location: ' . wp_sanitize_redirect( add_query_arg( array( 'action' => 'ab-paypal-error', 'ab_fid' => $form_id, 'error_msg' => str_replace( ' ', '%20', $response['L_LONGMESSAGE0'] ) ), Lib\Utils\Common::getCurrentPageURL() ) ) );
exit;
}
}
/**
* Send the NVP Request to the PayPal
*
* #param $method
* #param array $data
* #return array
*/
public function sendNvpRequest( $method, array $data )
{
$url = 'https://api-3t' . get_option( 'ab_paypal_ec_mode' ) . '.paypal.com/nvp';
$curl = new Lib\Curl\Curl();
$curl->options['CURLOPT_SSL_VERIFYPEER'] = false;
$curl->options['CURLOPT_SSL_VERIFYHOST'] = false;
$data['METHOD'] = $method;
$data['VERSION'] = '76.0';
$data['USER'] = get_option( 'ab_paypal_api_username' );
$data['PWD'] = get_option( 'ab_paypal_api_password' );
$data['SIGNATURE'] = get_option( 'ab_paypal_api_signature' );
$httpResponse = $curl->post( $url, $data );
if ( ! $httpResponse ) {
exit( $curl->error() );
}
// Extract the response details.
parse_str( $httpResponse, $PayPalResponse );
if ( ! array_key_exists( 'ACK', $PayPalResponse ) ) {
exit( 'Invalid HTTP Response for POST request to ' . $url );
}
return $PayPalResponse;
}
public static function renderForm( $form_id )
{
$html = '<form method="post" class="ab-paypal-form">';
$html .= '<input type="hidden" name="action" value="ab-paypal-checkout"/>';
$html .= '<input type="hidden" name="ab_fid" value="' . $form_id . '"/>';
$html .= '<button class="ab-left ab-back-step ab-btn ladda-button" data-style="zoom-in" data-spinner-size="40"><span class="ladda-label">' . Lib\Utils\Common::getTranslatedOption( 'ab_appearance_text_button_back' ) . '</span></button>';
$html .= '<button class="ab-right ab-next-step ab-btn ladda-button" data-style="zoom-in" data-spinner-size="40"><span class="ladda-label">' . Lib\Utils\Common::getTranslatedOption( 'ab_appearance_text_button_next' ) . '</span></button>';
$html .= '</form>';
echo $html;
}
/**
* #return array
*/
public function getProducts()
{
return $this->products;
}
/**
* Add the Product for payment
*
* #param \stdClass $product
*/
public function addProduct( \stdClass $product )
{
$this->products[] = $product;
}
}

Woocommerce booking :Fatal error: Call to a member function has_persons() on a non-object in

I need your great skills on WordPress and woocommerce, I have an issue that I don't know why woocommerce booking throw this :
**Fatal error: Call to a member function `has_persons()` on a non-object in `xxx/plugins/woocommerce-bookings/includes/class-wc-booking.php` on line 557**
and it stop all scripts executions.
the woocommerce booking class :
<?php
/**
* Main model class for all bookings, this handles all the data
*/
class WC_Booking {
/** #public int */
public $id;
/** #public string */
public $booking_date;
/** #public string */
public $start;
/** #public string */
public $end;
/** #public bool */
public $all_day;
/** #public string */
public $modified_date;
/** #public object */
public $post;
/** #public int */
public $product_id;
/** #public object */
public $product;
/** #public int */
public $order_id;
/** #public object */
public $order;
/** #public int */
public $customer_id;
/** #public string */
public $status;
/** #public array - contains all post meta values for this booking */
public $custom_fields;
/** #public bool */
public $populated;
/** #private array - used to temporarily hold order data for new bookings */
private $order_data;
/**
* Constructor, possibly sets up with post or id belonging to existing booking
* or supplied with an array to construct a new booking
* #param int/array/obj $booking_data
*/
public function __construct( $booking_data = false ) {
$populated = false;
if ( is_array( $booking_data ) ) {
$this->order_data = $booking_data;
$populated = false;
} else if ( is_int( intval( $booking_data ) ) && 0 < $booking_data ) {
$populated = $this->populate_data( $booking_data );
} else if ( is_object( $booking_data ) && isset( $booking_data->ID ) ) {
$this->post = $booking_data;
$populated = $this->populate_data( $booking_data->ID );
}
$this->populated = $populated;
}
/**
* Actual create for the new booking belonging to an order
* #param string Status for new order
*/
public function create( $status = 'unpaid' ) {
$this->new_booking( $status, $this->order_data );
$this->schedule_events();
}
/**
* Schedule events for this booking
*/
public function schedule_events() {
switch ( get_post_status( $this->id ) ) {
case "paid" :
if ( $this->start && $this->get_order() ) {
$order_status = $this->get_order()->get_status();
if ( ! in_array( $order_status, array( 'cancelled', 'refunded', 'pending', 'on-hold' ) ) ) {
wp_schedule_single_event( strtotime( '-' . absint( apply_filters( 'woocommerce_bookings_remind_before_days', 1 ) ) . ' day', $this->start ), 'wc-booking-reminder', array( $this->id ) );
}
}
if ( $this->end ) {
wp_schedule_single_event( $this->end, 'wc-booking-complete', array( $this->id ) );
}
break;
default :
wp_clear_scheduled_hook( 'wc-booking-reminder', array( $this->id ) );
wp_clear_scheduled_hook( 'wc-booking-complete', array( $this->id ) );
break;
}
}
/**
* Makes the new booking belonging to an order
* #param string $status The status for this new booking
* #param array $order_data Array with all the new order data
*/
private function new_booking( $status, $order_data ) {
global $wpdb;
$order_data = wp_parse_args( $order_data, array(
'user_id' => 0,
'resource_id' => '',
'product_id' => '',
'order_item_id' => '',
'persons' => array(),
'cost' => '',
'start_date' => '',
'end_date' => '',
'all_day' => 0,
'parent_id' => 0,
) );
// Get parent data
if ( $order_data['parent_id'] ) {
if ( ! $order_data['order_item_id'] ) {
$order_data['order_item_id'] = get_post_meta( $order_data['parent_id'], '_booking_order_item_id', true );
}
if ( ! $order_data['user_id'] ) {
$order_data['user_id'] = get_post_meta( $order_data['parent_id'], '_booking_customer_id', true );
}
}
// Get order ID from order item
if ( $order_data['order_item_id'] ) {
$order_id = $wpdb->get_var( $wpdb->prepare( "SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", $order_data['order_item_id'] ) );
} else {
$order_id = 0;
}
$booking_data = array(
'post_type' => 'wc_booking',
'post_title' => sprintf( __( 'Booking – %s', 'woocommerce-bookings' ), strftime( _x( '%b %d, %Y # %I:%M %p', 'Booking date parsed by strftime', 'woocommerce-bookings' ) ) ),
'post_status' => $status,
'ping_status' => 'closed',
'post_parent' => $order_id
);
$this->id = wp_insert_post( $booking_data );
// Setup the required data for the current user
if ( ! $order_data['user_id'] ) {
if ( is_user_logged_in() ) {
$order_data['user_id'] = get_current_user_id();
} else {
$order_data['user_id'] = 0;
}
}
// Convert booking start and end to requried format
if ( is_numeric( $order_data['start_date'] ) ) {
// Convert timestamp
$order_data['start_date'] = date( 'YmdHis', $order_data['start_date'] );
$order_data['end_date'] = date( 'YmdHis', $order_data['end_date'] );
} else {
$order_data['start_date'] = date( 'YmdHis', strtotime( $order_data['start_date'] ) );
$order_data['end_date'] = date( 'YmdHis', strtotime( $order_data['end_date'] ) );
}
$meta_args = array(
'_booking_order_item_id' => $order_data['order_item_id'],
'_booking_product_id' => $order_data['product_id'],
'_booking_resource_id' => $order_data['resource_id'],
'_booking_persons' => $order_data['persons'],
'_booking_cost' => $order_data['cost'],
'_booking_start' => $order_data['start_date'],
'_booking_end' => $order_data['end_date'],
'_booking_all_day' => intval( $order_data['all_day'] ),
'_booking_parent_id' => $order_data['parent_id'],
'_booking_customer_id' => $order_data['user_id'],
);
foreach ( $meta_args as $key => $value ) {
update_post_meta( $this->id, $key, $value );
}
WC_Cache_Helper::get_transient_version( 'bookings', true );
do_action( 'woocommerce_new_booking', $this->id );
}
/**
* Assign this booking to an order and order item by ID
* #param int $order_id
* #param int $order_item_id
*/
public function set_order_id( $order_id, $order_item_id ) {
$this->order_id = $order_id;
wp_update_post( array( 'ID' => $this->id, 'post_parent' => $this->order_id ) );
update_post_meta( $this->id, '_booking_order_item_id', $order_item_id );
}
/**
* Populate the data with the id of the booking provided
* Will query for the post belonging to this booking and store it
* #param int $booking_id
*/
public function populate_data( $booking_id ) {
if ( ! isset( $this->post ) ) {
$post = get_post( $booking_id );
}
if ( is_object( $post ) ) {
// We have the post object belonging to this booking, now let's populate
$this->id = $post->ID;
$this->booking_date = $post->post_date;
$this->modified_date = $post->post_modified;
$this->customer_id = $post->post_author;
$this->custom_fields = get_post_meta( $this->id );
$this->status = $post->post_status;
$this->order_id = $post->post_parent;
// Define the data we're going to load: Key => Default value
$load_data = array(
'product_id' => '',
'resource_id' => '',
'persons' => array(),
'cost' => '',
'start' => '',
'customer_id' => '',
'end' => '',
'all_day' => 0,
'parent_id' => 0,
);
// Load the data from the custom fields (with prefix for this plugin)
$meta_prefix = '_booking_';
foreach ( $load_data as $key => $default ) {
if ( isset( $this->custom_fields[ $meta_prefix . $key ][0] ) && $this->custom_fields[ $meta_prefix . $key ][0] !== '' ) {
$this->$key = maybe_unserialize( $this->custom_fields[ $meta_prefix . $key ][0] );
} else {
$this->$key = $default;
}
}
// Start and end date converted to timestamp
$this->start = strtotime( $this->start );
$this->end = strtotime( $this->end );
// Save the post object itself for future reference
$this->post = $post;
return true;
}
return false;
}
/**
* Will change the booking status once the order is paid for
* #return bool
*/
public function paid() {
$current_status = $this->status;
$event = wp_get_schedule( 'wc-booking-reminder', array( $this->id ) );
if ( $this->populated && in_array( $current_status, array( 'unpaid', 'confirmed' ) ) ) {
$this->update_status( 'paid' );
if ( ! empty( $event ) ) {
$this->schedule_events();
}
return true;
}
return false;
}
/**
* Set the new status for this booking
* #param string $status
* #return bool
*/
public function update_status( $status ) {
$current_status = $this->get_status( true );
$allowed_statuses = array( 'unpaid', 'pending-confirmation', 'confirmed', 'paid', 'cancelled', 'complete', 'in-cart', 'was-in-cart' );
if ( $this->populated ) {
if ( in_array( $status, $allowed_statuses ) ) {
wp_update_post( array( 'ID' => $this->id, 'post_status' => $status ) );
// Reschedule cron
$this->schedule_events();
// Trigger actions
do_action( 'woocommerce_booking_' . $current_status . '_to_' . $status, $this->id );
do_action( 'woocommerce_booking_' . $status, $this->id );
// Note in the order
if ( $order = $this->get_order() ) {
$order->add_order_note( sprintf( __( 'Booking #%d status changed from "%s" to "%s', 'woocommerce-bookings' ), $this->id, $current_status, $status ) );
}
return true;
}
}
return false;
}
/**
* Checks the booking status against a passed in status.
*
* #return bool
*/
public function has_status( $status ) {
return apply_filters( 'woocommerce_booking_has_status', ( is_array( $status ) && in_array( $this->get_status(), $status ) ) || $this->get_status() === $status ? true : false, $this, $status );
}
/**
* Returns the status of this booking
* #param Bool to ask for pretty status name (if false)
* #return String of the booking status
*/
public function get_status( $raw = true ) {
if ( $this->populated ) {
if ( $raw ) {
return $this->status;
} else {
$status_object = get_post_status_object( $this->status );
return $status_object->label;
}
}
return false;
}
/**
* Returns the id of this booking
* #return Id of the booking or false if booking is not populated
*/
public function get_id() {
if ( $this->populated ) {
return $this->id;
}
return false;
}
/**
* Get the product ID for the booking
* #return int or false if booking is not populated
*/
public function get_product_id() {
if ( $this->populated ) {
return $this->product_id;
}
return false;
}
/**
* Returns the object of the order corresponding to this booking
* #return Product object or false if booking is not populated
*/
public function get_product() {
if ( empty( $this->product ) ) {
if ( $this->populated && $this->product_id ) {
$this->product = get_product( $this->product_id );
} else {
return false;
}
}
return $this->product;
}
/**
* Returns the object of the order corresponding to this booking
* #return Order object or false if booking is not populated
*/
public function get_order() {
if ( empty( $this->order ) ) {
if ( $this->populated && ! empty( $this->order_id ) && 'shop_order' === get_post_type( $this->order_id ) ) {
$this->order = wc_get_order( $this->order_id );
} else {
return false;
}
}
return $this->order;
}
/**
* Returns the cancel URL for a booking
*
* #param string $redirect
* #return string
*/
public function get_cancel_url( $redirect = '' ) {
$cancel_page = get_permalink( wc_get_page_id( 'myaccount' ) );
if ( ! $cancel_page ) {
$cancel_page = home_url();
}
return apply_filters( 'bookings_cancel_booking_url', wp_nonce_url( add_query_arg( array( 'cancel_booking' => 'true', 'booking_id' => $this->id, 'redirect' => $redirect ), $cancel_page ), 'woocommerce-bookings-cancel_booking' ) );
}
/**
* Return if all day event
* #return boolean
*/
public function is_all_day() {
if ( $this->populated ) {
if ( $this->all_day ) {
return true;
} else {
return false;
}
}
return false;
}
/**
* See if this booking is booked on said date
* #return boolean
*/
public function is_booked_on_day( $block_start, $block_end ) {
if ( $this->populated ) {
$loop_date = $this->start;
$multiday_booking = date( 'Y-m-d', $this->start ) < date( 'Y-m-d', $this->end );
if ( $multiday_booking ) {
if ( date( 'YmdHi', $block_end ) > date( 'YmdHi', $this->start ) || date( 'YmdHi', $block_start ) < date( 'YmdHi', $this->end ) ) {
return true;
}
return false;
}
while ( $loop_date <= $this->end ) {
if ( date( 'Y-m-d', $loop_date ) === date( 'Y-m-d', $block_start ) ) {
return true;
}
$loop_date = strtotime( "+1 day", $loop_date );
}
}
return false;
}
/**
* See if this booking can still be cancelled by the user or not
* #return boolean
*/
public function passed_cancel_day() {
$booking = $this->get_product();
if ( $booking !== false ) {
$cancel_limit = $booking->wc_booking_cancel_limit;
$cancel_limit_unit = $cancel_limit > 1 ? $booking->wc_booking_cancel_limit_unit . 's' : $booking->wc_booking_cancel_limit_unit;
$cancel_string = sprintf( 'now +%d %s', $cancel_limit, $cancel_limit_unit );
if ( strtotime( $cancel_string ) >= $this->start ) {
return true;
}
}
return false;
}
/**
* Returns booking start date
* #return string Date formatted via date_i18n
*/
public function get_start_date( $date_format = null, $time_format = null ) {
if ( $this->populated && ! empty( $this->start ) ) {
if ( is_null( $date_format ) ) {
$date_format = apply_filters( 'woocommerce_bookings_date_format', 'M jS Y' );
}
if ( is_null( $time_format ) ) {
$time_format = apply_filters( 'woocommerce_bookings_time_format', ', g:ia' );
}
if ( $this->is_all_day() ) {
return date_i18n( $date_format, $this->start );
} else {
return date_i18n( $date_format . $time_format, $this->start );
}
}
return false;
}
/**
* Returns booking end date
* #return string Date formatted via date_i18n
*/
public function get_end_date( $date_format = null, $time_format = null ) {
if ( $this->populated && ! empty( $this->end ) ) {
if ( is_null( $date_format ) ) {
$date_format = apply_filters( 'woocommerce_bookings_date_format', 'M jS Y' );
}
if ( is_null( $time_format ) ) {
$time_format = apply_filters( 'woocommerce_bookings_time_format', ', g:ia' );
}
if ( $this->is_all_day() ) {
return date_i18n( $date_format, $this->end );
} else {
return date_i18n( $date_format . $time_format, $this->end );
}
}
return false;
}
/**
* Returns information about the customer of this order
* #return array containing customer information
*/
public function get_customer() {
if ( $this->populated ) {
$order = $this->get_order();
if ( $order )
return (object) array(
'name' => trim( $order->billing_first_name . ' ' . $order->billing_last_name ),
'email' => $order->billing_email,
'user_id' => $order->customer_user,
);
elseif ( $this->customer_id ) {
$user = get_user_by( 'id', $this->customer_id );
return (object) array(
'name' => $user->display_name,
'email' => $user->user_email,
'user_id' => $this->customer_id
);
}
}
return false;
}
/**
* Returns if persons are enabled/needed for the booking product
* #return boolean
*/
public function has_persons() {
return $this->get_product()->has_persons();
}
/**
* Returns if resources are enabled/needed for the booking product
* #return boolean
*/
public function has_resources() {
return $this->get_product()->has_resources();
}
/**
* Return a array with the booking persons.
* #return array
*/
public function get_persons() {
return (array) $this->persons;
}
/**
* Return the amount of persons for this booking.
* #return int
*/
public function get_persons_total() {
return array_sum( $this->get_persons() );
}
/**
* Get the resource id
* #return int
*/
public function get_resource_id() {
if ( $this->populated ) {
return absint( $this->resource_id );
}
return 0;
}
/**
* Get the resource/type for this booking if applicable.
* #return bool|object WP_Post
*/
public function get_resource() {
$resource_id = $this->get_resource_id();
if ( ! $resource_id || ! ( $product = $this->get_product() ) || ! method_exists( $product, 'get_resource' ) ) {
return false;
}
return $product->get_resource( $resource_id );
}
}
and on line 57
/**
* Returns if persons are enabled/needed for the booking product
* #return boolean
*/
public function has_persons() {
return $this->get_product()->has_persons();
}
Can someone help me please?
Thank you
I solved exactly the same error message with this fix :
In folder
/var/www/html/wp-content/plugins/woocommerce-bookings/includes
In file :
class-wc-booking.php
Replace :
/**
* Returns if persons are enabled/needed for the booking product
* #return boolean
*/
public function has_persons() {
return $this->get_product()->has_persons();
}
By :
/**
* Returns if persons are enabled/needed for the booking product
* #return boolean
*/
public function has_persons() {
if ($this->get_product()) {
return $this->get_product()->has_persons();
} else
{
return 0;
}
}

Symfony2 refactoring controller logic into a service

I'm slowly beginning to understand how things in Symfony2 are working.
I have set up a service which pulls json data from a live feed.
My controller uses this service to pull the data and then persist it to my database, I currently have 3 entities, though there are likely to be quite a few more.
All the logic at present is in FantasyPro/DataBundle
I'm currently breaking all sorts of rules, such as the logic for persisting my data is in a controller, so i'm thinking i need to take all this logic and put it into a service which i can use to persist the pulled data into my database via doctrine.
I would like to create this new PersistServce in the DataBundle
As the service will need to use doctrine all the entitys i have as well as the api service i'm not sure how to go about making these available to the service.
It probably worth mentioning that i intend to create commands so that i can run cron jobs to pull this data, in fact i don't think i will need the controller at all as they will only be used internally and not for generating requests.
I have it in a controller right now simply for testing purposes.
Whats the best way to refactor this code into a service?
Heres my messy controller code
<?php
namespace FantasyPro\DataBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use FantasyPro\DataBundle\Entity\Stadium;
use FantasyPro\DataBundle\Entity\Team;
use FantasyPro\DataBundle\Entity\Player;
class DefaultController extends Controller
{
public function indexAction($name)
{
return $this->render('DataBundle:Default:index.html.twig', array('name' => $name));
}
/**
* #return \Symfony\Component\HttpFoundation\Response
*/
public function updateStadiumAction(){
//get list of stadiums
$client = $this->container->get('fantasyapi');
$stadiumData = $client->Stadiums();
//get the entity manager
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository('DataBundle:Stadium');
$log = array();
$log = $this->addStadiumList( $stadiumData, $repo, $em, $log );
$em->flush();
return $this->render('DataBundle:Default:index.html.twig', array('log' => $log));
}
public function updateTeamAction()
{
//get list of teams
$client = $this->container->get('fantasyapi');
$teamData = $client->Teams();
//get the entity manager
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository('DataBundle:Team');
$log = array();
$log = $this->addTeamList( $teamData, $repo, $em, $log, 'Team' );
$em->flush();
return $this->render('DataBundle:Default:index.html.twig', array('log' => $log));
}
public function updatePlayerAction()
{
//get the api client
$client = $this->container->get('fantasyapi');
//get the manager
$em = $this->getDoctrine()->getManager();
$teamRepo = $em->getRepository('DataBundle:Team');
$playerRepo = $em->getRepository('DataBundle:Player');
$log = array();
//first we need to get a list of teams as players can only be collected via a teamID
/** #var Team $teams */
$teams = $client->Teams();
//var_dump($teams);die;
//loop through the teams and pull the playerData
foreach($teams as $team){
//log the team we are processing
$logData = ['action' => 'Processing Players for:', 'itemID' => $team['TeamID'], 'itemName' => $team['FullName']];
$log[] = $logData;
//get list players on this team
$players = $client->Players(['Team' => $team['Key']]);
//loop through the players
$log = $this->addPlayerList( $players, $playerRepo, $em, $log, 'Added Active Player' );
}
//now get free agents
$freeAgents = $client->FreeAgents();
$log = $this->addPlayerList($freeAgents, $playerRepo, $em, $log, 'Free Agent');
$em->flush();
return $this->render('DataBundle:Default:index.html.twig', array('log' => $log));
}
public function parseDate($dateString)
{
if ($dateString) {
preg_match( '/\/Date\((\d+)([-+])(\d+)\)\//', $dateString, $date );
$timestamp = $date[1] / 1000;
$operator = $date[2];
$hours = $date[3] * 36; // Get the seconds
// $datetime = new \DateTime($timestamp, new \DateTimeZone('America/New_York'));
$datetime = new \DateTime();
$datetime->setTimestamp($timestamp);
$datetime->modify( $operator.$hours.' seconds' );
$datetime->setTimezone(new \DateTimeZone('UTC'));
//$datetime->format( 'd-m-Y H:i:s' );
//var_dump( $datetime );
//echo('*');
return ($datetime);
}
return(null);
}
/**
* #param Array $players
* #param $playerRepo
* #param $em
* #param Array $log
*
* #param String $logTitle
*
* #return array
*/
public function addPlayerList( $players, $playerRepo, $em, $log, $logTitle )
{
foreach ($players as $player) {
// Get the current player in the list
$criteria = array( 'playerID' => $player['PlayerID'] );
/** #var Player $storedPlayer */
$storedPlayer = $playerRepo->FindOneBy( $criteria );
//var_dump($player);
if ( ! $storedPlayer) {
//no player exists with the PlayerID passed
//create a new entry
/** #var Player $entry */
$entry = new Player();
$entry->setTeam( $player['Team'] );
$entry->setPlayerID( $player['PlayerID'] );
$entry->setNumber( $player['Number'] );
$entry->setFirstName( $player['FirstName'] );
$entry->setLastName( $player['LastName'] );
$entry->setPosition( $player['Position'] );
$entry->setStatus( $player['Status'] );
$entry->setHeight( $player['Height'] );
$entry->setWeight( $player['Weight'] );
//need to parse the date on this field
$entry->setBirthDate( $this->parseDate( $player['BirthDate']));
$entry->setCollege( $player['College'] );
$entry->setExperience( $player['Experience'] );
$entry->setFantasyPosition( $player['FantasyPosition'] );
$entry->setActive( $player['Active'] );
$entry->setPositionCategory( $player['PositionCategory'] );
$entry->setName( $player['Name'] );
$entry->setAge( $player['Age'] );
$entry->setExperienceString( $player['ExperienceString'] );
$entry->setBirthDateString( $player['BirthDateString'] );
$entry->setPhotoUrl( $player['PhotoUrl'] );
$entry->setByeWeek( $player['ByeWeek'] );
$entry->setUpcomingGameOpponent( $player['UpcomingGameOpponent'] );
$entry->setUpcomingGameWeek( $player['UpcomingGameWeek'] );
$entry->setShortName( $player['ShortName'] );
$entry->setAverageDraftPos( $player['AverageDraftPosition'] );
$entry->setDepthPositionCategory( $player['DepthPositionCategory'] );
$entry->setDepthPosition( $player['DepthOrder'] );
$entry->setDepthDisplayOrder( $player['DepthDisplayOrder'] );
$entry->setCurrentTeam( $player['CurrentTeam'] );
$entry->setCollegeDraftTeam( $player['CollegeDraftTeam'] );
$entry->setCollegeDraftYear( $player['CollegeDraftYear'] );
$entry->setCollegeDraftRound( $player['CollegeDraftRound'] );
$entry->setCollegeDraftPick( $player['CollegeDraftPick'] );
$entry->setIsUndraftedFreeAgent( $player['IsUndraftedFreeAgent'] );
$entry->setHeightFeet( $player['HeightFeet'] );
$entry->setHeightInches( $player['HeightInches'] );
$entry->setUpcomingOpponentRank( $player['UpcomingOpponentRank'] );
$entry->setUpcomingOpponentPositionRank( $player['UpcomingOpponentPositionRank'] );
$entry->setCurrentStatus( $player['CurrentStatus'] );
$entry->setUpcomingSalary( $player['UpcomingSalary'] );
$em->persist( $entry );
$logData = [ 'action' => 'Added '.$logTitle,
'itemID' => $player['PlayerID'],
'itemName' => $player['Name']
];
$log[] = $logData;
} else {
$storedPlayer->setPlayerID( $player['PlayerID'] );
$storedPlayer->setTeam( $player['Team'] );
$storedPlayer->setPlayerID( $player['PlayerID'] );
$storedPlayer->setNumber( $player['Number'] );
$storedPlayer->setFirstName( $player['FirstName'] );
$storedPlayer->setLastName( $player['LastName'] );
$storedPlayer->setPosition( $player['Position'] );
$storedPlayer->setStatus( $player['Status'] );
$storedPlayer->setHeight( $player['Height'] );
$storedPlayer->setWeight( $player['Weight'] );
//need to parse the date on this field
$storedPlayer->setBirthDate( $this->parseDate( $player['BirthDate']));
$storedPlayer->setCollege( $player['College'] );
$storedPlayer->setExperience( $player['Experience'] );
$storedPlayer->setFantasyPosition( $player['FantasyPosition'] );
$storedPlayer->setActive( $player['Active'] );
$storedPlayer->setPositionCategory( $player['PositionCategory'] );
$storedPlayer->setName( $player['Name'] );
$storedPlayer->setAge( $player['Age'] );
$storedPlayer->setExperienceString( $player['ExperienceString'] );
$storedPlayer->setBirthDateString( $player['BirthDateString'] );
$storedPlayer->setPhotoUrl( $player['PhotoUrl'] );
$storedPlayer->setByeWeek( $player['ByeWeek'] );
$storedPlayer->setUpcomingGameOpponent( $player['UpcomingGameOpponent'] );
$storedPlayer->setUpcomingGameWeek( $player['UpcomingGameWeek'] );
$storedPlayer->setShortName( $player['ShortName'] );
$storedPlayer->setAverageDraftPos( $player['AverageDraftPosition'] );
$storedPlayer->setDepthPositionCategory( $player['DepthPositionCategory'] );
$storedPlayer->setDepthPosition( $player['DepthOrder'] );
$storedPlayer->setDepthDisplayOrder( $player['DepthDisplayOrder'] );
$storedPlayer->setCurrentTeam( $player['CurrentTeam'] );
$storedPlayer->setCollegeDraftTeam( $player['CollegeDraftTeam'] );
$storedPlayer->setCollegeDraftYear( $player['CollegeDraftYear'] );
$storedPlayer->setCollegeDraftRound( $player['CollegeDraftRound'] );
$storedPlayer->setCollegeDraftPick( $player['CollegeDraftPick'] );
$storedPlayer->setIsUndraftedFreeAgent( $player['IsUndraftedFreeAgent'] );
$storedPlayer->setHeightFeet( $player['HeightFeet'] );
$storedPlayer->setHeightInches( $player['HeightInches'] );
$storedPlayer->setUpcomingOpponentRank( $player['UpcomingOpponentRank'] );
$storedPlayer->setUpcomingOpponentPositionRank( $player['UpcomingOpponentPositionRank'] );
$storedPlayer->setCurrentStatus( $player['CurrentStatus'] );
$storedPlayer->setUpcomingSalary( $player['UpcomingSalary'] );
$em->persist( $storedPlayer );
$logData = [ 'action' => 'Updated '.$logTitle,
'itemID' => $player['PlayerID'],
'itemName' => $player['Name']
];
$log[] = $logData;
}
}
return ($log);
}
/**
* #param Array $teamData
* #param $repo
* #param $em
* #param String $logTitle
*
* #return array
*/
public function addTeamList( $teamData, $repo, $em, $log, $logTitle )
{
foreach ($teamData as $team) {
// Get the current team in the list
$criteria = array( 'teamID' => $team['TeamID'] );
//var_dump($criteria);
/** #var Team $storedTeam */
$storedTeam = $repo->FindOneBy( $criteria );
if ( ! $storedTeam) {
//no stadium exists with the StadiumID passed
//create a new entry
/** #var Team $entry */
$entry = new Team();
$entry->setTeamKey( $team['Key'] );
$entry->setTeamID( $team['TeamID'] );
$entry->setPlayerID( $team['PlayerID'] );
$entry->setCity( $team['City'] );
$entry->setName( $team['Name'] );
$entry->setConference( $team['Conference'] );
$entry->setDivision( $team['Division'] );
$entry->setFullName( $team['FullName'] );
$entry->setStadiumID( $team['StadiumID'] );
$entry->setByeWeek( $team['ByeWeek'] );
$entry->setAvergageDraftPos( $team['AverageDraftPosition'] );
$entry->setAverageDraftPosPPR( $team['AverageDraftPositionPPR'] );
$entry->setHeadCoach( $team['HeadCoach'] );
$entry->setOffensiveCoordinator( $team['OffensiveCoordinator'] );
$entry->setDefensiveCoordinator( $team['DefensiveCoordinator'] );
$entry->setSpecialTeamsCoach( $team['SpecialTeamsCoach'] );
$entry->setOffensiveScheme( $team['OffensiveScheme'] );
$entry->setDefensiveScheme( $team['DefensiveScheme'] );
$entry->setUpcomingSalary( $team['UpcomingSalary'] );
$entry->setUpcomingOpponentRank( $team['UpcomingOpponentRank'] );
$entry->setUpcomingOpponentPositionRank( $team['UpcomingOpponentPositionRank'] );
$em->persist( $entry );
$logData = [ 'action' => 'Added New '.$logTitle , 'itemID' => $team['TeamID'], 'itemName' => $team['Name'] ];
$log[] = $logData;
} else {
$storedTeam->setTeamKey( $team['Key'] );
$storedTeam->setPlayerID( $team['PlayerID'] );
$storedTeam->setCity( $team['City'] );
$storedTeam->setName( $team['Name'] );
$storedTeam->setConference( $team['Conference'] );
$storedTeam->setDivision( $team['Division'] );
$storedTeam->setFullName( $team['FullName'] );
$storedTeam->setStadiumID( $team['StadiumID'] );
$storedTeam->setByeWeek( $team['ByeWeek'] );
$storedTeam->setAvergageDraftPos( $team['AverageDraftPosition'] );
$storedTeam->setAverageDraftPosPPR( $team['AverageDraftPositionPPR'] );
$storedTeam->setHeadCoach( $team['HeadCoach'] );
$storedTeam->setOffensiveCoordinator( $team['OffensiveCoordinator'] );
$storedTeam->setDefensiveCoordinator( $team['DefensiveCoordinator'] );
$storedTeam->setSpecialTeamsCoach( $team['SpecialTeamsCoach'] );
$storedTeam->setOffensiveScheme( $team['OffensiveScheme'] );
$storedTeam->setDefensiveScheme( $team['DefensiveScheme'] );
$storedTeam->setUpcomingSalary( $team['UpcomingSalary'] );
$storedTeam->setUpcomingOpponentRank( $team['UpcomingOpponentRank'] );
$storedTeam->setUpcomingOpponentPositionRank( $team['UpcomingOpponentPositionRank'] );
$em->persist( $storedTeam );
$logData = [ 'action' => 'Updated '.$logTitle , 'itemID' => $team['TeamID'], 'itemName' => $team['Name'] ];
$log[] = $logData;
}
}
return $log;
}
/**
* #param Array $stadiumData
* #param $repo
* #param $em
* #param $log
*
* #return array
*/
public function addStadiumList( $stadiumData, $repo, $em, $log )
{
foreach ($stadiumData as $stadium) {
// Get the current stadium in the list
$criteria = array( 'stadiumID' => $stadium['StadiumID'] );
//var_dump($criteria);
/** #var Stadium $storedStadium */
$storedStadium = $repo->FindOneBy( $criteria );
if ( ! $storedStadium) {
//no stadium exists with the StadiumID passed
//create a new entry
/** #var Stadium $entry */
$entry = new Stadium();
$entry->setStadiumID( $stadium['StadiumID'] );
$entry->setName( $stadium['Name'] );
$entry->setCity( $stadium['City'] );
$entry->setState( $stadium['State'] );
$entry->setCountry( $stadium['Country'] );
$entry->setCapacity( $stadium['Capacity'] );
$entry->setPlayingSurface( $stadium['PlayingSurface'] );
$em->persist( $entry );
$logData = [ 'action' => 'Added New Stadium',
'itemID' => $stadium['StadiumID'],
'itemName' => $stadium['Name']
];
$log[] = $logData;
} else {
$storedStadium->setStadiumID( $stadium['StadiumID'] );
$storedStadium->setName( $stadium['Name'] );
$storedStadium->setCity( $stadium['City'] );
$storedStadium->setState( $stadium['State'] );
$storedStadium->setCountry( $stadium['Country'] );
$storedStadium->setCapacity( $stadium['Capacity'] );
$storedStadium->setPlayingSurface( $stadium['PlayingSurface'] );
$em->persist( $storedStadium );
$logData = [ 'action' => 'Updated Stadium',
'itemID' => $stadium['StadiumID'],
'itemName' => $stadium['Name']
];
$log[] = $logData;
}
}
return $log;
}
}
The best way to handle your purposes for me is to create extended repository classes for your entities.
See Symfony2 - Doctrine documentation
In your case this might be:
namespace SomeBundle\Repository;
use Doctrine\ORM\EntityRepository;
class PlayerRepository extends EntityRepository
{
/**
* #param Array $players
* #param $playerRepo
* #param $em
* #param Array $log
*
* #param String $logTitle
*
* #return array
*/
public function addPlayerList($players, $log, $logTitle)
{
foreach ($players as $player) {
// Get the current player in the list
$criteria = array('playerID' => $player['PlayerID']);
/** #var Player $storedPlayer */
$storedPlayer = $this->findOneBy($criteria);
if (!$storedPlayer) {
$storedPlayer = new Player();
$logData = [
'action' => 'Added '.$logTitle,
'itemID' => $player['PlayerID'],
'itemName' => $player['Name']
];
$log[] = $logData;
} else {
$logData = [
'action' => 'Updated '.$logTitle,
'itemID' => $player['PlayerID'],
'itemName' => $player['Name']
];
$log[] = $logData;
}
$storedPlayer->setPlayerID($player['PlayerID']);
$storedPlayer->setTeam($player['Team']);
$storedPlayer->setPlayerID($player['PlayerID']);
$storedPlayer->setNumber($player['Number']);
$storedPlayer->setFirstName($player['FirstName']);
$storedPlayer->setLastName($player['LastName']);
$storedPlayer->setPosition($player['Position']);
$storedPlayer->setStatus($player['Status']);
$storedPlayer->setHeight($player['Height']);
$storedPlayer->setWeight($player['Weight']);
//need to parse the date on this field
$storedPlayer->setBirthDate($this->parseDate($player['BirthDate']));
$storedPlayer->setCollege($player['College']);
$storedPlayer->setExperience($player['Experience']);
$storedPlayer->setFantasyPosition($player['FantasyPosition']);
$storedPlayer->setActive($player['Active']);
$storedPlayer->setPositionCategory($player['PositionCategory']);
$storedPlayer->setName($player['Name']);
$storedPlayer->setAge($player['Age']);
$storedPlayer->setExperienceString($player['ExperienceString']);
$storedPlayer->setBirthDateString($player['BirthDateString']);
$storedPlayer->setPhotoUrl($player['PhotoUrl']);
$storedPlayer->setByeWeek($player['ByeWeek']);
$storedPlayer->setUpcomingGameOpponent($player['UpcomingGameOpponent']);
$storedPlayer->setUpcomingGameWeek($player['UpcomingGameWeek']);
$storedPlayer->setShortName($player['ShortName']);
$storedPlayer->setAverageDraftPos($player['AverageDraftPosition']);
$storedPlayer->setDepthPositionCategory($player['DepthPositionCategory']);
$storedPlayer->setDepthPosition($player['DepthOrder']);
$storedPlayer->setDepthDisplayOrder($player['DepthDisplayOrder']);
$storedPlayer->setCurrentTeam($player['CurrentTeam']);
$storedPlayer->setCollegeDraftTeam($player['CollegeDraftTeam']);
$storedPlayer->setCollegeDraftYear($player['CollegeDraftYear']);
$storedPlayer->setCollegeDraftRound($player['CollegeDraftRound']);
$storedPlayer->setCollegeDraftPick($player['CollegeDraftPick']);
$storedPlayer->setIsUndraftedFreeAgent($player['IsUndraftedFreeAgent']);
$storedPlayer->setHeightFeet($player['HeightFeet']);
$storedPlayer->setHeightInches($player['HeightInches']);
$storedPlayer->setUpcomingOpponentRank($player['UpcomingOpponentRank']);
$storedPlayer->setUpcomingOpponentPositionRank($player['UpcomingOpponentPositionRank']);
$storedPlayer->setCurrentStatus($player['CurrentStatus']);
$storedPlayer->setUpcomingSalary($player['UpcomingSalary']);
}
return ($log);
}
}
Also on my own I'll rather created date parser class to parse date inside this repositories like
$date = (new CustomDateTimeParser('your fancy date string here'))->getDateTime();

Resources