コード例 #1
0
 /**
  *        get the revenue per day  for the Transaction Admin page Reports Tab
  *
  * @access        public
  * @param string $period
  * @return \stdClass[]
  */
 public function get_revenue_per_day_report($period = '-1 month')
 {
     $sql_date = $this->convert_datetime_for_query('TXN_timestamp', date('Y-m-d H:i:s', strtotime($period)), 'Y-m-d H:i:s', 'UTC');
     EE_Registry::instance()->load_helper('DTT_Helper');
     $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'TXN_timestamp');
     $results = $this->_get_all_wpdb_results(array(array('TXN_timestamp' => array('>=', $sql_date)), 'group_by' => 'txnDate', 'order_by' => array('TXN_timestamp' => 'ASC')), OBJECT, array('txnDate' => array('DATE(' . $query_interval . ')', '%s'), 'revenue' => array('SUM(Transaction.TXN_paid)', '%d')));
     return $results;
 }
コード例 #2
0
 /**
  * Handles saving everything related to Tickets (datetimes, tickets, prices)
  * @param  EE_Event $evtobj The Event object we're attaching data to
  * @param  array    $data   The request data from the form
  * @return bool             success or fail
  */
 protected function _default_tickets_update(EE_Event $evtobj, $data)
 {
     $success = true;
     $saved_dtt = null;
     $saved_tickets = array();
     $incoming_date_formats = array('Y-m-d', 'h:i a');
     foreach ($data['edit_event_datetimes'] as $row => $dtt) {
         //trim all values to ensure any excess whitespace is removed.
         $dtt = array_map('trim', $dtt);
         $dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && !empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end'] : $dtt['DTT_EVT_start'];
         $datetime_values = array('DTT_ID' => !empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : NULL, 'DTT_EVT_start' => $dtt['DTT_EVT_start'], 'DTT_EVT_end' => $dtt['DTT_EVT_end'], 'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'], 'DTT_order' => $row);
         //if we have an id then let's get existing object first and then set the new values.  Otherwise we instantiate a new object for save.
         if (!empty($dtt['DTT_ID'])) {
             $DTM = EE_Registry::instance()->load_model('Datetime', array($evtobj->get_timezone()))->get_one_by_ID($dtt['DTT_ID']);
             $DTM->set_date_format($incoming_date_formats[0]);
             $DTM->set_time_format($incoming_date_formats[1]);
             foreach ($datetime_values as $field => $value) {
                 $DTM->set($field, $value);
             }
             //make sure the $dtt_id here is saved just in case after the add_relation_to() the autosave replaces it.  We need to do this so we dont' TRASH the parent DTT.
             $saved_dtts[$DTM->ID()] = $DTM;
         } else {
             $DTM = EE_Registry::instance()->load_class('Datetime', array($datetime_values), FALSE, FALSE);
             $DTM->set_date_format($incoming_date_formats[0]);
             $DTM->set_time_format($incoming_date_formats[1]);
             $DTM->set_timezone($evtobj->get_timezone());
             foreach ($datetime_values as $field => $value) {
                 $DTM->set($field, $value);
             }
         }
         $DTM->save();
         $DTT = $evtobj->_add_relation_to($DTM, 'Datetime');
         //load DTT helper
         //before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
         if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) {
             $DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start'));
             $DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days');
             $DTT->save();
         }
         //now we got to make sure we add the new DTT_ID to the $saved_dtts array  because it is possible there was a new one created for the autosave.
         $saved_dtt = $DTT;
         $success = !$success ? $success : $DTT;
         //if ANY of these updates fail then we want the appropriate global error message. //todod this is actually sucky we need a better error message but this is what it is for now.
     }
     //no dtts get deleted so we don't do any of that logic here.
     //update tickets next
     $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
     foreach ($data['edit_tickets'] as $row => $tkt) {
         $incoming_date_formats = array('Y-m-d', 'h:i a');
         $update_prices = false;
         $ticket_price = isset($data['edit_prices'][$row][1]['PRC_amount']) ? $data['edit_prices'][$row][1]['PRC_amount'] : 0;
         // trim inputs to ensure any excess whitespace is removed.
         $tkt = array_map('trim', $tkt);
         if (empty($tkt['TKT_start_date'])) {
             //let's use now in the set timezone.
             $now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
             $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
         }
         if (empty($tkt['TKT_end_date'])) {
             //use the start date of the first datetime
             $dtt = $evtobj->first_datetime();
             $tkt['TKT_end_date'] = $dtt->start_date_and_time($incoming_date_formats[0], $incoming_date_formats[1]);
         }
         $TKT_values = array('TKT_ID' => !empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : NULL, 'TTM_ID' => !empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0, 'TKT_name' => !empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '', 'TKT_description' => !empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '', 'TKT_start_date' => $tkt['TKT_start_date'], 'TKT_end_date' => $tkt['TKT_end_date'], 'TKT_qty' => !isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'], 'TKT_uses' => !isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'], 'TKT_min' => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'], 'TKT_max' => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'], 'TKT_row' => $row, 'TKT_order' => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row, 'TKT_price' => $ticket_price);
         //if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly, which means in turn that the prices will become new prices as well.
         if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
             $TKT_values['TKT_ID'] = 0;
             $TKT_values['TKT_is_default'] = 0;
             $TKT_values['TKT_price'] = $ticket_price;
             $update_prices = TRUE;
         }
         //if we have a TKT_ID then we need to get that existing TKT_obj and update it
         //we actually do our saves a head of doing any add_relations to because its entirely possible that this ticket didn't removed or added to any datetime in the session but DID have it's items modified.
         //keep in mind that if the TKT has been sold (and we have changed pricing information), then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
         if (!empty($tkt['TKT_ID'])) {
             $TKT = EE_Registry::instance()->load_model('Ticket', array($evtobj->get_timezone()))->get_one_by_ID($tkt['TKT_ID']);
             if ($TKT instanceof EE_Ticket) {
                 $ticket_sold = $TKT->count_related('Registration', array(array('STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete))))) > 0 ? true : false;
                 //let's just check the total price for the existing ticket and determine if it matches the new total price.  if they are different then we create a new ticket (if tkts sold) if they aren't different then we go ahead and modify existing ticket.
                 $create_new_TKT = $ticket_sold && $ticket_price != $TKT->get('TKT_price') && !$TKT->get('TKT_deleted') ? true : false;
                 $TKT->set_date_format($incoming_date_formats[0]);
                 $TKT->set_time_format($incoming_date_formats[1]);
                 //set new values
                 foreach ($TKT_values as $field => $value) {
                     if ($field == 'TKT_qty') {
                         $TKT->set_qty($value);
                     } else {
                         $TKT->set($field, $value);
                     }
                 }
                 //if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
                 if ($create_new_TKT) {
                     //archive the old ticket first
                     $TKT->set('TKT_deleted', 1);
                     $TKT->save();
                     //make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine.
                     $saved_tickets[$TKT->ID()] = $TKT;
                     //create new ticket that's a copy of the existing except a new id of course (and not archived) AND has the new TKT_price associated with it.
                     $TKT = clone $TKT;
                     $TKT->set('TKT_ID', 0);
                     $TKT->set('TKT_deleted', 0);
                     $TKT->set('TKT_price', $ticket_price);
                     $TKT->set('TKT_sold', 0);
                     //now we need to make sure that $new prices are created as well and attached to new ticket.
                     $update_prices = true;
                 }
                 //make sure price is set if it hasn't been already
                 $TKT->set('TKT_price', $ticket_price);
             }
         } else {
             //no TKT_id so a new TKT
             $TKT_values['TKT_price'] = $ticket_price;
             $TKT = EE_Registry::instance()->load_class('Ticket', array($TKT_values), FALSE, FALSE);
             if ($TKT instanceof EE_Ticket) {
                 //need to reset values to properly account for the date formats
                 $TKT->set_date_format($incoming_date_formats[0]);
                 $TKT->set_time_format($incoming_date_formats[1]);
                 $TKT->set_timezone($evtobj->get_timezone());
                 //set new values
                 foreach ($TKT_values as $field => $value) {
                     if ($field == 'TKT_qty') {
                         $TKT->set_qty($value);
                     } else {
                         $TKT->set($field, $value);
                     }
                 }
                 $update_prices = TRUE;
             }
         }
         // cap ticket qty by datetime reg limits
         $TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit')));
         //update ticket.
         $TKT->save();
         //before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
         if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
             $TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
             $TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
             $TKT->save();
         }
         //initially let's add the ticket to the dtt
         $saved_dtt->_add_relation_to($TKT, 'Ticket');
         $saved_tickets[$TKT->ID()] = $TKT;
         //add prices to ticket
         $this->_add_prices_to_ticket($data['edit_prices'][$row], $TKT, $update_prices);
     }
     //however now we need to handle permanently deleting tickets via the ui.  Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.  However, it does allow for deleting tickets that have no tickets sold, in which case we want to get rid of permanently because there is no need to save in db.
     $old_tickets = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets;
     $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
     foreach ($tickets_removed as $id) {
         $id = absint($id);
         //get the ticket for this id
         $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
         //need to get all the related datetimes on this ticket and remove from every single one of them (remember this process can ONLY kick off if there are NO tkts_sold)
         $dtts = $tkt_to_remove->get_many_related('Datetime');
         foreach ($dtts as $dtt) {
             $tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
         }
         //need to do the same for prices (except these prices can also be deleted because again, tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
         $tkt_to_remove->delete_related_permanently('Price');
         //finally let's delete this ticket (which should not be blocked at this point b/c we've removed all our relationships)
         $tkt_to_remove->delete_permanently();
     }
     return array($saved_dtt, $saved_tickets);
 }
コード例 #3
0
 /**
  * admin_footer_global
  * Anything triggered by the wp 'admin_footer' wp hook should be put in here. This particluar method will apply on ALL EE_Admin Pages.
  *
  * @access  public
  * @return  void
  */
 public function admin_footer_global()
 {
     //dialog container for dialog helper
     $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n";
     $d_cont .= '<div class="ee-notices"></div>';
     $d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>';
     $d_cont .= '</div>';
     echo $d_cont;
     //help tour stuff?
     if (isset($this->_help_tour[$this->_req_action])) {
         echo implode('<br />', $this->_help_tour[$this->_req_action]);
     }
     //current set timezone for timezone js
     EE_Registry::instance()->load_helper('DTT_Helper');
     echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>';
 }
 /**
  * _revenue_per_event_report
  * generates Business Report showing total revenue per event.
  *
  * @param string $period  The period (acceptable by PHP Datetime constructor) for which the report is generated.
  * @return int
  */
 private function _revenue_per_event_report($period = '-1 month')
 {
     $report_ID = 'txn-admin-revenue-per-event-report-dv';
     $TXN = EEM_Transaction::instance();
     $results = $TXN->get_revenue_per_event_report($period);
     $results = (array) $results;
     $revenue = array();
     $subtitle = '';
     if ($results) {
         $revenue[] = array(__('Event (only events that have a revenue greater than 1 are shown)', 'event_espresso'), __('Total Revenue', 'event_espresso'));
         foreach ($results as $result) {
             if ($result->revenue > 1) {
                 $event_name = stripslashes(html_entity_decode($result->event_name, ENT_QUOTES, 'UTF-8'));
                 $event_name = wp_trim_words($event_name, 5, '...');
                 $revenue[] = array($event_name, (double) $result->revenue);
             }
         }
         //setup the date range.
         EE_Registry::instance()->load_helper('DTT_Helper');
         $beginning_date = new DateTime('now' . $period, new DateTimeZone(EEH_DTT_Helper::get_timezone()));
         $ending_date = new DateTime('now', new DateTimeZone(EEH_DTT_Helper::get_timezone()));
         $subtitle = sprintf(_x('For the period: %s to %s', 'Used to give date range', 'event_espresso'), $beginning_date->format('Y-m-d'), $ending_date->format('Y-m-d'));
     }
     $report_title = __('Total Revenue per Event');
     $report_params = array('title' => $report_title, 'subtitle' => $subtitle, 'id' => $report_ID, 'revenue' => $revenue, 'noResults' => empty($revenue), 'noTxnMsg' => sprintf(__('%sThere are currently no transaction records in the last month for this report.%s', 'event_espresso'), '<h2>' . $report_title . '</h2><p>', '</p>'));
     wp_localize_script('ee-txn-reports-js', 'txnRevPerEvent', $report_params);
     return $report_ID;
 }
コード例 #5
0
 /**
  * This returns a wpdb->results 		Array of all DTT month and years matching the incoming query params and grouped by month and year.
  * @param  array $where_params 		Array of query_params as described in the comments for EEM_Base::get_all()
  * @param  string $evt_active_status 		A string representing the evt active status to filter the months by.
  * 		Can be:
  * 			- '' = no filter
  * 			- upcoming = Published events with at least one upcoming datetime.
  * 			- expired = Events with all datetimes expired.
  * 			- active = Events that are published and have at least one datetime that starts before now and ends after now.
  * 			- inactive = Events that are either not published.
  * @return wpdb results array
  */
 public function get_dtt_months_and_years($where_params, $evt_active_status = '')
 {
     $current_time_for_DTT_EVT_start = $this->current_time_for_query('DTT_EVT_start');
     $current_time_for_DTT_EVT_end = $this->current_time_for_query('DTT_EVT_end');
     switch ($evt_active_status) {
         case 'upcoming':
             $where_params['Event.status'] = 'publish';
             //if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
             if (isset($where_params['DTT_EVT_start'])) {
                 $where_params['DTT_EVT_start*****'] = $where_params['DTT_EVT_start'];
             }
             $where_params['DTT_EVT_start'] = array('>', $current_time_for_DTT_EVT_start);
             break;
         case 'expired':
             if (isset($where_params['Event.status'])) {
                 unset($where_params['Event.status']);
             }
             //get events to exclude
             $exclude_query[0] = array_merge($where_params, array('DTT_EVT_end' => array('>', $current_time_for_DTT_EVT_end)));
             //first get all events that have datetimes where its not expired.
             $event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Datetime.EVT_ID');
             $event_ids = array_keys($event_ids);
             if (isset($where_params['DTT_EVT_end'])) {
                 $where_params['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
             }
             $where_params['DTT_EVT_end'] = array('<', $current_time_for_DTT_EVT_end);
             $where_params['Event.EVT_ID'] = array('NOT IN', $event_ids);
             break;
         case 'active':
             $where_params['Event.status'] = 'publish';
             if (isset($where_params['DTT_EVT_start'])) {
                 $where_params['Datetime.DTT_EVT_start******'] = $where_params['DTT_EVT_start'];
             }
             if (isset($where_params['Datetime.DTT_EVT_end'])) {
                 $where_params['Datetime.DTT_EVT_end*****'] = $where_params['DTT_EVT_end'];
             }
             $where_params['DTT_EVT_start'] = array('<', $current_time_for_DTT_EVT_start);
             $where_params['DTT_EVT_end'] = array('>', $current_time_for_DTT_EVT_end);
             break;
         case 'inactive':
             if (isset($where_params['Event.status'])) {
                 unset($where_params['Event.status']);
             }
             if (isset($where_params['OR'])) {
                 $where_params['AND']['OR'] = $where_params['OR'];
             }
             if (isset($where_params['DTT_EVT_end'])) {
                 $where_params['AND']['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
                 unset($where_params['DTT_EVT_end']);
             }
             if (isset($where_params['DTT_EVT_start'])) {
                 $where_params['AND']['DTT_EVT_start'] = $where_params['DTT_EVT_start'];
                 unset($where_params['DTT_EVT_start']);
             }
             $where_params['AND']['Event.status'] = array('!=', 'publish');
             break;
     }
     $query_params[0] = $where_params;
     $query_params['group_by'] = array('dtt_year', 'dtt_month');
     $query_params['order_by'] = array('DTT_EVT_start' => 'DESC');
     $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'DTT_EVT_start');
     $columns_to_select = array('dtt_year' => array('YEAR(' . $query_interval . ')', '%s'), 'dtt_month' => array('MONTHNAME(' . $query_interval . ')', '%s'), 'dtt_month_num' => array('MONTH(' . $query_interval . ')', '%s'));
     return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
 }
 /**
  * update tickets
  * @param  EE_Event         $evtobj     Event object being updated
  * @param  EE_Datetime[]    $saved_dtts an array of datetime ids being updated
  * @param  array            $data       incoming request data
  * @return bool                 		success or fail
  */
 private function _update_tkts($evtobj, $saved_dtts, $data)
 {
     //stripslashes because WP filtered the $_POST ($data) array to add slashes
     $data = stripslashes_deep($data);
     $timezone = isset($data['timezone_string']) ? $data['timezone_string'] : NULL;
     $success = TRUE;
     $saved_tickets = $dtts_on_existing = array();
     $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
     //load money helper
     EE_Registry::instance()->load_helper('Money');
     foreach ($data['edit_tickets'] as $row => $tkt) {
         $update_prices = $create_new_TKT = $ticket_sold = FALSE;
         $new_default = $new_tkt = NULL;
         //figure out what dtts were added to the ticket and what dtts were removed from the ticket in the session.
         $starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][$row]);
         $tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][$row]);
         $dtts_added = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
         $dtts_removed = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
         //note we are doing conversions to floats here instead of allowing EE_Money_Field to handle because we're doing calcs prior to using the models.
         //note incoming ['TKT_price'] value is already in standard notation (via js).
         $ticket_price = isset($tkt['TKT_price']) ? round((double) $tkt['TKT_price'], 3) : 0;
         //note incoming base price needs converted from localized value.
         $base_price = isset($tkt['TKT_base_price']) ? EEH_Money::convert_to_float_from_localized_money($tkt['TKT_base_price']) : 0;
         //if ticket price == 0 and $base_price != 0 then ticket price == base_price
         $ticket_price = $ticket_price === 0 && $base_price !== 0 ? $base_price : $ticket_price;
         $base_price_id = isset($tkt['TKT_base_price_ID']) ? $tkt['TKT_base_price_ID'] : 0;
         $price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][$row]) ? $data['edit_prices'][$row] : array();
         $TKT_values = array('TKT_ID' => !empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : NULL, 'TTM_ID' => !empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0, 'TKT_name' => !empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '', 'TKT_description' => !empty($tkt['TKT_description']) && $tkt['TKT_description'] != __('You can modify this description', 'event_espresso') ? $tkt['TKT_description'] : '', 'TKT_start_date' => isset($tkt['TKT_start_date']) ? $tkt['TKT_start_date'] : current_time('mysql'), 'TKT_end_date' => isset($tkt['TKT_end_date']) ? $tkt['TKT_end_date'] : current_time('mysql'), 'TKT_qty' => empty($tkt['TKT_qty']) ? INF : $tkt['TKT_qty'], 'TKT_uses' => empty($tkt['TKT_uses']) ? INF : $tkt['TKT_uses'], 'TKT_min' => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'], 'TKT_max' => empty($tkt['TKT_max']) ? INF : $tkt['TKT_max'], 'TKT_row' => $row, 'TKT_order' => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : 0, 'TKT_taxable' => !empty($tkt['TKT_taxable']) ? 1 : 0, 'TKT_required' => !empty($tkt['TKT_required']) ? 1 : 0, 'TKT_price' => $ticket_price);
         //if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly, which means in turn that the prices will become new prices as well.
         if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
             $TKT_values['TKT_ID'] = 0;
             $TKT_values['TKT_is_default'] = 0;
             $update_prices = TRUE;
         }
         //if we have a TKT_ID then we need to get that existing TKT_obj and update it
         //we actually do our saves ahead of doing any add_relations to because its entirely possible that this ticket didn't removed or added to any datetime in the session but DID have it's items modified.
         //keep in mind that if the TKT has been sold (and we have changed pricing information), then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
         if (!empty($TKT_values['TKT_ID'])) {
             $TKT = EE_Registry::instance()->load_model('Ticket', array($timezone))->get_one_by_ID($tkt['TKT_ID']);
             $ticket_sold = $TKT->count_related('Registration', array(array('STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete))))) > 0 ? true : false;
             //let's just check the total price for the existing ticket and determine if it matches the new total price.  if they are different then we create a new ticket (if tkts sold) if they aren't different then we go ahead and modify existing ticket.
             $orig_price = $TKT->price();
             $create_new_TKT = $ticket_sold && $ticket_price != $orig_price && !$TKT->get('TKT_deleted') ? TRUE : FALSE;
             //set new values
             foreach ($TKT_values as $field => $value) {
                 $TKT->set($field, $value);
             }
             //make sure price is set if it hasn't been already
             $TKT->set('TKT_price', $ticket_price);
             //if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
             if ($create_new_TKT) {
                 //@TODO need to move this logic into its own method that just receives the ticket object (and other necessary info)
                 $new_tkt = clone $TKT;
                 //we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
                 $dtts_on_existing = $TKT->get_many_related('Datetime');
                 //TKT will get archived later b/c we are NOT adding it to the saved_tickets array.
                 //if existing $TKT has sold amount, then we need to adjust the qty for the new TKT to = the remaining available.
                 if ($TKT->get('TKT_sold') > 0) {
                     $new_qty = $TKT->get('TKT_qty') - $TKT->get('TKT_sold');
                     $new_tkt->set_qty($new_qty);
                 }
                 //create new ticket that's a copy of the existing except a new id of course (and not archived) AND has the new TKT_price associated with it.
                 $new_tkt->set('TKT_ID', 0);
                 $new_tkt->set('TKT_deleted', 0);
                 $new_tkt->set('TKT_price', $ticket_price);
                 $new_tkt->set('TKT_sold', 0);
                 //now we update the prices just for this ticket
                 $new_tkt = $this->_add_prices_to_ticket($price_rows, $new_tkt, TRUE);
                 //and we update the base price
                 $new_tkt = $this->_add_prices_to_ticket(array(), $new_tkt, TRUE, $base_price, $base_price_id);
                 foreach ($dtts_on_existing as $adddtt) {
                     $new_tkt->_add_relation_to($adddtt, 'Datetime');
                 }
             }
         } else {
             //no TKT_id so a new TKT
             $TKT_values['TKT_price'] = $ticket_price;
             $TKT = EE_Registry::instance()->load_class('Ticket', array($TKT_values, $timezone), FALSE, FALSE);
             $update_prices = TRUE;
         }
         $TKT->save();
         //make sure any current values have been saved.
         //before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
         if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
             $TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
             EE_Registry::instance()->load_helper('DTT_Helper');
             $TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
         }
         //let's make sure the base price is handled
         $TKT = !$create_new_TKT ? $this->_add_prices_to_ticket(array(), $TKT, $update_prices, $base_price, $base_price_id) : $TKT;
         //add/update price_modifiers
         $TKT = !$create_new_TKT ? $this->_add_prices_to_ticket($price_rows, $TKT, $update_prices) : $TKT;
         //need to make sue that the TKT_price is accurate after saving the prices.
         $TKT->ensure_TKT_Price_correct();
         //handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
         if (!defined('DOING_AUTOSAVE')) {
             if (!empty($tkt['TKT_is_default_selector'])) {
                 $update_prices = TRUE;
                 $new_default = clone $TKT;
                 $new_default->set('TKT_ID', 0);
                 $new_default->set('TKT_is_default', 1);
                 $new_default->set('TKT_row', 1);
                 $new_default->set('TKT_price', $ticket_price);
                 //remove any dtt relations cause we DON'T want dtt relations attached (note this is just removing the cached relations in the object)
                 $new_default->_remove_relations('Datetime');
                 $new_default->save();
                 //todo we need to add the current attached prices as new prices to the new default ticket.
                 $new_default = $this->_add_prices_to_ticket($price_rows, $new_default, $update_prices);
                 //don't forget the base price!
                 $new_default = $this->_add_prices_to_ticket(array(), $new_default, $update_prices, $base_price, $base_price_id);
             }
         }
         //now we just have to add the ticket to all the datetimes its supposed to be with and removing the ticket from datetimes it got removed from.
         //first let's do the add_relation_to()
         $dtts_added = empty($dtts_added) || is_array($dtts_added) && (isset($dtts_added[0]) && $dtts_added[0] == '') ? array() : $dtts_added;
         foreach ($dtts_added as $dttrow) {
             $dttrow = (int) $dttrow;
             $TKT->_add_relation_to($saved_dtts[$dttrow], 'Datetime');
             //now wait a minute.  Does this tkt have any sold?  Cause if it does then we need to add that to the DTT sold because this DTT is getting added.
             if ($TKT->get('TKT_sold') > 0) {
                 $saved_dtts[$dttrow]->increase_sold($TKT->get('TKT_sold'));
                 $saved_dtts[$dttrow]->save();
             }
             //if we have a new_tkt... let's add to it as well
             if (!empty($new_tkt)) {
                 $new_tkt->_add_relation_to($saved_dtts[$dttrow], 'Datetime');
             }
         }
         $dtts_removed = empty($dtts_removed) || is_array($dtts_removed) && isset($dtts_removed[0]) && $dtts_removed[0] == '' ? array() : $dtts_removed;
         //now let's do the remove_relation_to()
         foreach ($dtts_removed as $dttrow) {
             $dttrow = (int) $dttrow;
             //its entirely possible that a datetime got deleted (instead of just removed from relationship.  So make sure we skip over this if the dtt isn't in the saved_dtts array)
             if (empty($saved_dtts[$dttrow]) || !$saved_dtts[$dttrow] instanceof EE_Datetime) {
                 continue;
             }
             $TKT->_remove_relation_to($saved_dtts[$dttrow], 'Datetime');
             //now wait a minute.  Does this tkt have any sold? Cause if it does then we need to remove it's sold from the DTT_sold.
             if ($TKT->get('TKT_sold') > 0) {
                 $saved_dtts[$dttrow]->decrease_sold($TKT->get('TKT_sold'));
                 $saved_dtts[$dttrow]->save();
             }
             if (!empty($new_tkt)) {
                 $new_tkt->_remove_relation_to($saved_dtts[$dttrow], 'Datetime');
             }
         }
         //DO ALL dtt relationships for both current tickets and any archived tickets for the given dtt that are related to the current ticket. TODO... not sure exactly how we're going to do this considering we don't know what current ticket the archived tickets are related to (and TKT_parent is used for autosaves so that's not a field we can reliably use).
         //let's assign any tickets that have been setup to the saved_tickets tracker
         //save existing TKT
         $TKT->save();
         if ($create_new_TKT) {
             //save new TKT
             $new_tkt->save();
             //add new ticket to array
             $saved_tickets[$new_tkt->ID()] = $new_tkt;
             do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket', $new_tkt, $row, $tkt, $data);
         } else {
             //add tkt to saved tkts
             //save existing TKT
             $saved_tickets[$TKT->ID()] = $TKT;
             do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket', $TKT, $row, $tkt, $data);
         }
     }
     //now we need to handle tickets actually "deleted permanently".  There are cases where we'd want this to happen (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).  Or a draft event was saved and in the process of editing a ticket is trashed.  No sense in keeping all the related data in the db!
     $old_tickets = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets;
     $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
     /*var_dump($old_tickets);
     		var_dump($saved_tickets);
     		var_dump($tickets_removed);*/
     foreach ($tickets_removed as $id) {
         $id = absint($id);
         //get the ticket for this id
         $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
         //if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
         if ($tkt_to_remove->get('TKT_is_default')) {
             continue;
         }
         //if this tkt has any registrations attached so then we just ARCHIVE because we don't actually permanently delete these tickets.
         if ($tkt_to_remove->count_related('Registration') > 0) {
             $tkt_to_remove->delete();
             continue;
         }
         //need to get all the related datetimes on this ticket and remove from every single one of them (remember this process can ONLY kick off if there are NO tkts_sold)
         $dtts = $tkt_to_remove->get_many_related('Datetime');
         foreach ($dtts as $dtt) {
             $tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
         }
         //need to do the same for prices (except these prices can also be deleted because again, tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
         $tkt_to_remove->delete_related_permanently('Price');
         do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $tkt_to_remove);
         //finally let's delete this ticket (which should not be blocked at this point b/c we've removed all our relationships)
         $tkt_to_remove->delete_permanently();
     }
 }
コード例 #7
0
 /**
  * This receives a timestring for a given field and ensures that it is setup to match what the internal settings
  * for the model are.  Returns a DateTime object.
  *
  * Note: a gotcha for when you send in unixtimestamp.  Remember a unixtimestamp is already timezone agnostic,
  * (functionally the equivalent of UTC+0).  So when you send it in, whatever timezone string you include is ignored.
  *
  * @param string $field_name The field being setup.
  * @param string $timestring   The date timestring being used.
  * @param string $incoming_format        The format for the time string.
  * @param string $timezone   By default, it is assumed the incoming timestring is in timezone for
  *                           		the blog.  If this is not the case, then it can be specified here.  If incoming format is
  *                           		'U', this is ignored.
  * @return DateTime
  */
 public function convert_datetime_for_query($field_name, $timestring, $incoming_format, $timezone = '')
 {
     //just using this to ensure the timezone is set correctly internally
     $this->get_formats_for($field_name);
     //load EEH_DTT_Helper
     EE_Registry::instance()->load_helper('DTT_Helper');
     $set_timezone = empty($timezone) ? EEH_DTT_Helper::get_timezone() : $timezone;
     $incomingDateTime = date_create_from_format($incoming_format, $timestring, new DateTimeZone($set_timezone));
     return $incomingDateTime->setTimeZone(new DateTimeZone($this->_timezone));
 }
 /**
  * update tickets
  * @param  EE_Event         $evtobj     Event object being updated
  * @param  EE_Datetime[]    $saved_dtts an array of datetime ids being updated
  * @param  array            $data       incoming request data
  * @return EE_Ticket[]
  */
 protected function _update_tkts($evtobj, $saved_dtts, $data)
 {
     $new_tkt = null;
     $new_default = null;
     //stripslashes because WP filtered the $_POST ($data) array to add slashes
     $data = stripslashes_deep($data);
     $timezone = isset($data['timezone_string']) ? $data['timezone_string'] : NULL;
     $saved_tickets = $dtts_on_existing = array();
     $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
     //load money helper
     EE_Registry::instance()->load_helper('Money');
     foreach ($data['edit_tickets'] as $row => $tkt) {
         $update_prices = $create_new_TKT = FALSE;
         //figure out what dtts were added to the ticket and what dtts were removed from the ticket in the session.
         $starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][$row]);
         $tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][$row]);
         $dtts_added = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
         $dtts_removed = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
         // trim inputs to ensure any excess whitespace is removed.
         $tkt = array_map(function ($ticket_data) {
             return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
         }, $tkt);
         //note we are doing conversions to floats here instead of allowing EE_Money_Field to handle because we're doing calcs prior to using the models.
         //note incoming ['TKT_price'] value is already in standard notation (via js).
         $ticket_price = isset($tkt['TKT_price']) ? round((double) $tkt['TKT_price'], 3) : 0;
         //note incoming base price needs converted from localized value.
         $base_price = isset($tkt['TKT_base_price']) ? EEH_Money::convert_to_float_from_localized_money($tkt['TKT_base_price']) : 0;
         //if ticket price == 0 and $base_price != 0 then ticket price == base_price
         $ticket_price = $ticket_price === 0 && $base_price !== 0 ? $base_price : $ticket_price;
         $base_price_id = isset($tkt['TKT_base_price_ID']) ? $tkt['TKT_base_price_ID'] : 0;
         $price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][$row]) ? $data['edit_prices'][$row] : array();
         $now = null;
         if (empty($tkt['TKT_start_date'])) {
             //lets' use now in the set timezone.
             $now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
             $tkt['TKT_start_date'] = $now->format($this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time']);
         }
         if (empty($tkt['TKT_end_date'])) {
             /**
              * set the TKT_end_date to the first datetime attached to the ticket.
              */
             $first_dtt = $saved_dtts[reset($tkt_dtt_rows)];
             $tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_format_strings['date'] . ' ' . $this->_date_format_string['time']);
         }
         $TKT_values = array('TKT_ID' => !empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : NULL, 'TTM_ID' => !empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0, 'TKT_name' => !empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '', 'TKT_description' => !empty($tkt['TKT_description']) && $tkt['TKT_description'] != __('You can modify this description', 'event_espresso') ? $tkt['TKT_description'] : '', 'TKT_start_date' => $tkt['TKT_start_date'], 'TKT_end_date' => $tkt['TKT_end_date'], 'TKT_qty' => !isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'], 'TKT_uses' => !isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'], 'TKT_min' => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'], 'TKT_max' => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'], 'TKT_row' => $row, 'TKT_order' => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : 0, 'TKT_taxable' => !empty($tkt['TKT_taxable']) ? 1 : 0, 'TKT_required' => !empty($tkt['TKT_required']) ? 1 : 0, 'TKT_price' => $ticket_price);
         //if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly, which means in turn that the prices will become new prices as well.
         if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
             $TKT_values['TKT_ID'] = 0;
             $TKT_values['TKT_is_default'] = 0;
             $update_prices = TRUE;
         }
         // if we have a TKT_ID then we need to get that existing TKT_obj and update it
         // we actually do our saves ahead of doing any add_relations to
         // because its entirely possible that this ticket wasn't removed or added to any datetime in the session
         // but DID have it's items modified.
         // keep in mind that if the TKT has been sold (and we have changed pricing information),
         // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
         if (absint($TKT_values['TKT_ID'])) {
             $TKT = EE_Registry::instance()->load_model('Ticket', array($timezone))->get_one_by_ID($tkt['TKT_ID']);
             if ($TKT instanceof EE_Ticket) {
                 $TKT = $this->_update_ticket_datetimes($TKT, $saved_dtts, $dtts_added, $dtts_removed);
                 // are there any registrations using this ticket ?
                 $tickets_sold = $TKT->count_related('Registration', array(array('STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete)))));
                 //set ticket formats
                 $TKT->set_date_format($this->_date_format_strings['date']);
                 $TKT->set_time_format($this->_date_format_strings['time']);
                 // let's just check the total price for the existing ticket
                 // and determine if it matches the new total price.
                 // if they are different then we create a new ticket (if tkts sold)
                 // if they aren't different then we go ahead and modify existing ticket.
                 $create_new_TKT = $tickets_sold > 0 && $ticket_price != $TKT->price() && !$TKT->deleted() ? TRUE : FALSE;
                 //set new values
                 foreach ($TKT_values as $field => $value) {
                     if ($field === 'TKT_qty') {
                         $TKT->set_qty($value);
                     } else {
                         $TKT->set($field, $value);
                     }
                 }
                 //if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
                 if ($create_new_TKT) {
                     $new_tkt = $this->_duplicate_ticket($TKT, $price_rows, $ticket_price, $base_price, $base_price_id);
                 }
             }
         } else {
             // no TKT_id so a new TKT
             $TKT = EE_Ticket::new_instance($TKT_values, $timezone, array($this->_date_format_strings['date'], $this->_date_format_strings['time']));
             if ($TKT instanceof EE_Ticket) {
                 // make sure ticket has an ID of setting relations won't work
                 $TKT->save();
                 $TKT = $this->_update_ticket_datetimes($TKT, $saved_dtts, $dtts_added, $dtts_removed);
                 $update_prices = TRUE;
             }
         }
         //make sure any current values have been saved.
         //$TKT->save();
         //before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
         if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
             $TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
             EE_Registry::instance()->load_helper('DTT_Helper');
             $TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
         }
         //let's make sure the base price is handled
         $TKT = !$create_new_TKT ? $this->_add_prices_to_ticket(array(), $TKT, $update_prices, $base_price, $base_price_id) : $TKT;
         //add/update price_modifiers
         $TKT = !$create_new_TKT ? $this->_add_prices_to_ticket($price_rows, $TKT, $update_prices) : $TKT;
         //need to make sue that the TKT_price is accurate after saving the prices.
         $TKT->ensure_TKT_Price_correct();
         //handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
         if (!defined('DOING_AUTOSAVE')) {
             if (!empty($tkt['TKT_is_default_selector'])) {
                 $update_prices = TRUE;
                 $new_default = clone $TKT;
                 $new_default->set('TKT_ID', 0);
                 $new_default->set('TKT_is_default', 1);
                 $new_default->set('TKT_row', 1);
                 $new_default->set('TKT_price', $ticket_price);
                 //remove any dtt relations cause we DON'T want dtt relations attached (note this is just removing the cached relations in the object)
                 $new_default->_remove_relations('Datetime');
                 //todo we need to add the current attached prices as new prices to the new default ticket.
                 $new_default = $this->_add_prices_to_ticket($price_rows, $new_default, $update_prices);
                 //don't forget the base price!
                 $new_default = $this->_add_prices_to_ticket(array(), $new_default, $update_prices, $base_price, $base_price_id);
                 $new_default->save();
                 do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket', $new_default, $row, $TKT, $data);
             }
         }
         //DO ALL dtt relationships for both current tickets and any archived tickets for the given dtt that are related to the current ticket. TODO... not sure exactly how we're going to do this considering we don't know what current ticket the archived tickets are related to (and TKT_parent is used for autosaves so that's not a field we can reliably use).
         //let's assign any tickets that have been setup to the saved_tickets tracker
         //save existing TKT
         $TKT->save();
         if ($create_new_TKT && $new_tkt instanceof EE_Ticket) {
             //save new TKT
             $new_tkt->save();
             //add new ticket to array
             $saved_tickets[$new_tkt->ID()] = $new_tkt;
             do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket', $new_tkt, $row, $tkt, $data);
         } else {
             //add tkt to saved tkts
             $saved_tickets[$TKT->ID()] = $TKT;
             do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket', $TKT, $row, $tkt, $data);
         }
     }
     // now we need to handle tickets actually "deleted permanently".
     // There are cases where we'd want this to happen
     // (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
     // Or a draft event was saved and in the process of editing a ticket is trashed.
     // No sense in keeping all the related data in the db!
     $old_tickets = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets;
     $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
     foreach ($tickets_removed as $id) {
         $id = absint($id);
         //get the ticket for this id
         $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
         //if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
         if ($tkt_to_remove->get('TKT_is_default')) {
             continue;
         }
         // if this tkt has any registrations attached so then we just ARCHIVE
         // because we don't actually permanently delete these tickets.
         if ($tkt_to_remove->count_related('Registration') > 0) {
             $tkt_to_remove->delete();
             continue;
         }
         // need to get all the related datetimes on this ticket and remove from every single one of them
         // (remember this process can ONLY kick off if there are NO tkts_sold)
         $dtts = $tkt_to_remove->get_many_related('Datetime');
         foreach ($dtts as $dtt) {
             $tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
         }
         // need to do the same for prices (except these prices can also be deleted because again,
         // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
         $tkt_to_remove->delete_related_permanently('Price');
         do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $tkt_to_remove);
         // finally let's delete this ticket
         // (which should not be blocked at this point b/c we've removed all our relationships)
         $tkt_to_remove->delete_permanently();
     }
     return $saved_tickets;
 }
コード例 #9
0
 /**
  * @since 4.6.x
  */
 public function test_create_new_blank_datetime()
 {
     //if timezone is empty string then the setUp didn't work correctly.  For the purpose of this test
     //we want a high positive timezone, so let's force that if necessary
     if (get_option('timezone_string') != 'Australia/Sydney') {
         update_option('timezone_string', 'Australia/Sydney');
         EEM_Datetime::reset();
         EEM_Datetime::instance();
     }
     EE_Registry::instance()->load_helper('DTT_Helper');
     //make sure now is in the timezone we want to test with.
     $now = new Datetime('@' . (time() + DAY_IN_SECONDS * 30));
     $now->setTimeZone(new DateTimeZone(EEH_DTT_Helper::get_timezone()));
     $now->setTime('8', '0', '0');
     $now->setTimeZone(new DateTimeZone('America/Toronto'));
     //get the default datetime
     $default_date = EEM_Datetime::instance()->create_new_blank_datetime();
     $default_date = reset($default_date);
     //assert instance
     $this->assertInstanceOf('EE_Datetime', $default_date);
     //set its timezone to match our expected timezone
     $default_date->set_timezone('America/Toronto');
     $actual = $default_date->get_DateTime_object('DTT_EVT_start');
     $this->assertInstanceOf('DateTime', $actual);
     //assert timezones are the same
     $this->assertEquals($now->getTimezone(), $actual->getTimeZone());
     //assert that we have the correct values on the date... we'll do each part separately to verify.
     $this->assertEquals($now->format('Y'), $actual->format('Y'));
     $this->assertEquals($now->format('m'), $actual->format('m'));
     $this->assertEquals($now->format('d'), $actual->format('d'));
     $this->assertEquals($now->format('H'), $actual->format('H'));
     $this->assertEquals($now->format('i'), $actual->format('i'));
 }
コード例 #10
0
 /**
  *		get the number of registrations per day  for the Registration Admin page Reports Tab.
  *		(doesn't utilize models because it's a fairly specialized query)
  * 		@access		public
  *		@param $period string which can be passed to php's strtotime function (eg "-1 month")
  *		@return stdClass[] with properties regDate and total
  */
 public function get_registrations_per_day_report($period = '-1 month')
 {
     $sql_date = $this->convert_datetime_for_query('REG_date', date("Y-m-d H:i:s", strtotime($period)), 'Y-m-d H:i:s', 'UTC');
     $where = array('REG_date' => array('>=', $sql_date), 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete));
     if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) {
         $where['Event.EVT_wp_user'] = get_current_user_id();
     }
     EE_Registry::instance()->load_helper('DTT_Helper');
     $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'REG_date');
     $results = $this->_get_all_wpdb_results(array($where, 'group_by' => 'regDate', 'order_by' => array('REG_date' => 'ASC')), OBJECT, array('regDate' => array('DATE(' . $query_interval . ')', '%s'), 'total' => array('count(REG_ID)', '%d')));
     return $results;
 }
コード例 #11
0
 /**
  * retrieve  all payments from db between two dates,
  *
  * @param string $start_date incoming start date. If empty the beginning of today is used.
  * @param string $end_date   incoming end date. If empty the end of today is used.
  * @param string $format  	If you include $start_date or $end_date then you must include the format string
  *                         		for the format your date is in.
  * @param string $timezone   If your range is in a different timezone then the current setting on this
  *                           		WordPress install, then include it here.
  * @throws EE_Error
  *
  * @return EE_Payment[]
  */
 public function get_payments_made_between_dates($start_date = '', $end_date = '', $format = '', $timezone = '')
 {
     EE_Registry::instance()->load_helper('DTT_Helper');
     $timezone = empty($timezone) ? EEH_DTT_Helper::get_timezone() : $timezone;
     //if $start_date or $end date, verify $format is included.
     if ((!empty($start_date) || !empty($end_date)) && empty($format)) {
         throw new EE_Error(__('You included a start date and/or a end date for this method but did not include a format string.  The format string is needed for setting up the query', 'event_espresso'));
     }
     $now = new DateTime('now');
     // setup timezone objects once
     $modelDateTimeZone = new DateTimeZone($this->_timezone);
     $passedDateTimeZone = new DateTimeZone($timezone);
     // setup start date
     $start_date = !empty($start_date) ? date_create_from_format($format, $start_date, $passedDateTimeZone) : $now;
     $start_date->setTimeZone($modelDateTimeZone);
     $start_date = $start_date->format('Y-m-d') . ' 00:00:00';
     $start_date = strtotime($start_date);
     // setup end date
     $end_date = !empty($end_date) ? date_create_from_format($format, $end_date, $passedDateTimeZone) : $now;
     $end_date->setTimeZone($modelDateTimeZone);
     $end_date = $end_date->format('Y-m-d') . ' 23:59:59';
     $end_date = strtotime($end_date);
     // make sure our start date is the lowest value and vice versa
     $start = min($start_date, $end_date);
     $end = max($start_date, $end_date);
     //yes we generated the date and time string in utc but we WANT this start date and time used in the set timezone on the model.
     $start_date = $this->convert_datetime_for_query('PAY_timestamp', date('Y-m-d', $start) . ' 00:00:00', 'Y-m-d H:i:s', $this->get_timezone());
     $end_date = $this->convert_datetime_for_query('PAY_timestamp', date('Y-m-d', $end) . ' 23:59:59', 'Y-m-d H:i:s', $this->get_timezone());
     return $this->get_all(array(array('PAY_timestamp' => array('>=', $start_date), 'PAY_timestamp*' => array('<=', $end_date))));
 }
 /**
  * Generates Business Report showing total registrations per event.
  * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
  *
  * @return string
  */
 private function _registrations_per_event_report($period = '-1 month')
 {
     $report_ID = 'reg-admin-registrations-per-event-report-dv';
     $REG = EEM_Registration::instance();
     $results = $REG->get_registrations_per_event_report($period);
     $results = (array) $results;
     $regs = array();
     $subtitle = '';
     if ($results) {
         $regs[] = array(__('Event', 'event_espresso'), __('Total Registrations', 'event_espresso'));
         foreach ($results as $result) {
             $regs[] = array(wp_trim_words($result->event_name, 4, '...'), (int) $result->total);
         }
         //setup the date range.
         EE_Registry::instance()->load_helper('DTT_Helper');
         $beginning_date = new DateTime("now " . $period, new DateTimeZone(EEH_DTT_Helper::get_timezone()));
         $ending_date = new DateTime("now", new DateTimeZone(EEH_DTT_Helper::get_timezone()));
         $subtitle = sprintf(_x('For the period: %s to %s', 'Used to give date range', 'event_espresso'), $beginning_date->format('Y-m-d'), $ending_date->format('Y-m-d'));
     }
     $report_title = __('Total Registrations per Event', 'event_espresso');
     $report_params = array('title' => $report_title, 'subtitle' => $subtitle, 'id' => $report_ID, 'regs' => $regs, 'noResults' => empty($regs), 'noRegsMsg' => sprintf(__('%sThere are currently no registration records in the last month for this report.%s', 'event_espresso'), '<h2>' . $report_title . '</h2><p>', '</p>'));
     wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params);
     return $report_ID;
 }
コード例 #13
0
 /**
  * Get the number of registrations per day including the count of registrations for each Registration Status.
  * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results.
  *
  * @param string $period
  *
  * @return stdClass[] with properties Registration_REG_date and a column for each registration status as the STS_ID
  *                    (i.e. RAP)
  */
 public function get_registrations_per_day_and_per_status_report($period = '-1 month')
 {
     global $wpdb;
     $registration_table = $wpdb->prefix . 'esp_registration';
     $event_table = $wpdb->posts;
     $sql_date = date("Y-m-d H:i:s", strtotime($period));
     //prepare the query interval for displaying offset
     $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'dates.REG_date');
     //inner date query
     $inner_date_query = "SELECT DISTINCT REG_date from {$registration_table} ";
     $inner_where = " WHERE";
     //exclude events not authored by user if permissions in effect
     if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
         $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID";
         $inner_where .= " post_author = " . get_current_user_id() . " AND";
     }
     $inner_where .= " REG_date >= '{$sql_date}'";
     $inner_date_query .= $inner_where;
     //start main query
     $select = "SELECT DATE({$query_interval}) as Registration_REG_date, ";
     $join = '';
     $join_parts = array();
     $select_parts = array();
     //loop through registration stati to do parts for each status.
     foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) {
         if ($STS_ID === EEM_Registration::status_id_incomplete) {
             continue;
         }
         $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}";
         $join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.REG_date = dates.REG_date AND {$STS_code}.STS_ID = '{$STS_ID}'";
     }
     //setup the selects
     $select .= implode(', ', $select_parts);
     $select .= " FROM ({$inner_date_query}) AS dates LEFT JOIN ";
     //setup the joins
     $join .= implode(" LEFT JOIN ", $join_parts);
     //now let's put it all together
     $query = $select . $join . ' GROUP BY Registration_REG_date';
     //and execute it
     $results = $wpdb->get_results($query, ARRAY_A);
     return $results;
 }
コード例 #14
0
 /**
  * promotion_date_range
  * returns the first and last chronologically ordered dates for a promotion (if different)
  *
  * @return string
  */
 public function promotion_date_range()
 {
     EE_Registry::instance()->load_helper('DTT_Helper');
     $start_date = $this->get_DateTime_object('PRO_start');
     $end_date = $this->get_DateTime_object('PRO_end');
     // if the promo starts at midnight on one day, and the promo ends at midnight on the very next day
     // (this also verifies that $dates are DateTime objects)
     if (EEH_DTT_Helper::dates_represent_one_24_hour_date($start_date, $end_date)) {
         return $start_date->format(EE_Datetime_Field::mysql_time_format) == '00:00:00' ? $this->get_i18n_datetime('PRO_start', $this->_dt_frmt) : $this->get_i18n_datetime('PRO_start');
     } else {
         if (!$start_date instanceof DateTime && $end_date instanceof DateTime) {
             return sprintf(_x('Ends: %s', 'Value is the end date for a promotion', 'event_espresso'), $this->get_i18n_datetime('PRO_end'));
         } else {
             if ($start_date instanceof DateTime && !$end_date instanceof DateTime) {
                 return sprintf(_x('Starts: %s', 'Value is the start date for a promotion', 'event_espresso'), $this->get_i18n_datetime('PRO_start'));
             } else {
                 if ($start_date instanceof DateTime && $end_date instanceof DateTime) {
                     return sprintf(_x('%s - %s', 'First value is start date and second value is end date in a date range.', 'event_espresso'), $this->get_i18n_datetime('PRO_start'), $this->get_i18n_datetime('PRO_end'));
                 } else {
                     return __('Ongoing Promotion', 'event_espresso');
                 }
             }
         }
     }
 }
コード例 #15
0
 /**
  *    check_for_invalid_datetime_formats
  *
  *    if an admin changes their date or time format settings on the WP General Settings admin page, verify that their selected format can be parsed by PHP
  *
  * @access    public
  * @param    $value
  * @param    $option
  * @throws EE_Error
  * @return    string
  */
 public function check_for_invalid_datetime_formats($value, $option)
 {
     EE_Registry::instance()->load_helper('DTT_Helper');
     // check for date_format or time_format
     switch ($option) {
         case 'date_format':
             $date_time_format = $value . ' ' . get_option('time_format');
             break;
         case 'time_format':
             $date_time_format = get_option('date_format') . ' ' . $value;
             break;
         default:
             $date_time_format = FALSE;
     }
     // do we have a date_time format to check ?
     if ($date_time_format) {
         $error_msg = EEH_DTT_Helper::validate_format_string($date_time_format);
         if (is_array($error_msg)) {
             $msg = '<p>' . sprintf(__('The following date time "%s" ( %s ) is difficult to be properly parsed by PHP for the following reasons:', 'event_espresso'), date($date_time_format), $date_time_format) . '</p><p><ul>';
             foreach ($error_msg as $error) {
                 $msg .= '<li>' . $error . '</li>';
             }
             $msg .= '</ul></p><p>' . sprintf(__('%sPlease note that your date and time formats have been reset to "F j, Y" and "g:i a" respectively.%s', 'event_espresso'), '<span style="color:#D54E21;">', '</span>') . '</p>';
             // trigger WP settings error
             add_settings_error('date_format', 'date_format', $msg);
             // set format to something valid
             switch ($option) {
                 case 'date_format':
                     $value = 'F j, Y';
                     break;
                 case 'time_format':
                     $value = 'g:i a';
                     break;
             }
         }
     }
     return $value;
 }
コード例 #16
0
 /**
  * Writes some meta data to the CSV as a bunch of columns. Initially we're only
  * mentioning the version and timezone
  * @param resource $filehandle
  */
 public function write_metadata_to_csv($filehandle)
 {
     EE_Registry::instance()->load_helper('DTT_Helper');
     $data_row = array(EE_CSV::metadata_header);
     //do NOT translate because this exact string is used when importing
     $this->fputcsv2($filehandle, $data_row);
     EE_Registry::instance()->load_helper('DTT_Helper');
     $meta_data = array(0 => array('version' => espresso_version(), 'timezone' => EEH_DTT_Helper::get_timezone(), 'time_of_export' => current_time('mysql'), 'site_url' => site_url()));
     $this->write_data_array_to_csv($filehandle, $meta_data);
 }
 /**
  * Generates Business Report showing total registrations per event.
  * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
  *
  * @return string
  */
 private function _registrations_per_event_report($period = '-1 month')
 {
     $report_ID = 'reg-admin-registrations-per-event-report-dv';
     $results = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period);
     $results = (array) $results;
     $regs = array();
     $subtitle = '';
     if ($results) {
         $column_titles = array();
         $tracker = 0;
         foreach ($results as $result) {
             $report_column_values = array();
             foreach ($result as $property_name => $property_value) {
                 $property_value = $property_name == 'Registration_Event' ? wp_trim_words($property_value, 4, '...') : (int) $property_value;
                 $report_column_values[] = $property_value;
                 if ($tracker === 0) {
                     if ($property_name == 'Registration_Event') {
                         $column_titles[] = __('Event', 'event_espresso');
                     } else {
                         $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
                     }
                 }
             }
             $tracker++;
             $regs[] = $report_column_values;
         }
         //make sure the column_titles is pushed to the beginning of the array
         array_unshift($regs, $column_titles);
         //setup the date range.
         $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone());
         $beginning_date = new DateTime("now " . $period, $DateTimeZone);
         $ending_date = new DateTime("now", $DateTimeZone);
         $subtitle = sprintf(_x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), $beginning_date->format('Y-m-d'), $ending_date->format('Y-m-d'));
     }
     $report_title = __('Total Registrations per Event', 'event_espresso');
     $report_params = array('title' => $report_title, 'subtitle' => $subtitle, 'id' => $report_ID, 'regs' => $regs, 'noResults' => empty($regs), 'noRegsMsg' => sprintf(__('%sThere are currently no registration records in the last month for this report.%s', 'event_espresso'), '<h2>' . $report_title . '</h2><p>', '</p>'));
     wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params);
     return $report_ID;
 }
コード例 #18
0
 /**
  * Simply takes an incoming UTC timestamp or DateTime object and does calculations on it based on the incoming parameters and returns the new timestamp or DateTime.
  * @param  int | DateTime $DateTime_or_timestamp     DateTime object or Unix timestamp
  * @param  string  $period   a value to indicate what interval is being used in the calculation. The options are 'years', 'months', 'days', 'hours', 'minutes', 'seconds'. Defaults to years.
  * @param  integer $value  What you want to increment the date by
  * @param  string  $operand What operand you wish to use for the calculation
  * @return mixed string|DateTime          return whatever type came in.
  */
 public static function calc_date($DateTime_or_timestamp, $period = 'years', $value = 1, $operand = '+')
 {
     if ($DateTime_or_timestamp instanceof DateTime) {
         return EEH_DTT_Helper::_modify_datetime_object($DateTime_or_timestamp, $period, $value, $operand);
     } else {
         if (preg_match(EE_Datetime_Field::unix_timestamp_regex, $DateTime_or_timestamp)) {
             return EEH_DTT_Helper::_modify_timestamp($DateTime_or_timestamp, $period, $value, $operand);
         } else {
             //error
             return $DateTime_or_timestamp;
         }
     }
 }
コード例 #19
0
 /**
  * This will take an incoming timezone string and return the abbreviation for that timezone
  * @param  string $timezone_string
  * @return string           abbreviation
  */
 public function get_timezone_abbrev($timezone_string)
 {
     $timezone_string = EEH_DTT_Helper::get_valid_timezone_string($timezone_string);
     $dateTime = new DateTime('now', new DateTimeZone($timezone_string));
     return $dateTime->format('T');
 }
コード例 #20
0
 /**
  * This will return a timestamp for the website timezone but ONLY when the current website timezone is different than the timezone set for the website.
  *
  * NOTE, this currently only works well with methods that return values.  If you use it with methods that echo values the $_timestamp property may not get reset to its original value and that could lead to some unexpected results!
  *
  * @access public
  * @param string               $field_name This is the name of the field on the object that contains the date/time value being returned.
  * @param string               $callback   must match a valid method in this class (defaults to get_datetime)
  * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
  * @param string               $prepend    You can include something to prepend on the timestamp
  * @param string               $append     You can include something to append on the timestamp
  * @throws EE_Error
  * @return string timestamp
  */
 public function display_in_my_timezone($field_name, $callback = 'get_datetime', $args = NULL, $prepend = '', $append = '')
 {
     EE_Registry::instance()->load_helper('DTT_Helper');
     $timezone = EEH_DTT_Helper::get_timezone();
     if ($timezone == $this->_timezone) {
         return '';
     }
     $original_timezone = $this->_timezone;
     $this->set_timezone($timezone);
     $fn = (array) $field_name;
     $args = array_merge($fn, (array) $args);
     if (!method_exists($this, $callback)) {
         throw new EE_Error(sprintf(__('The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling', 'event_espresso'), $callback));
     }
     $args = (array) $args;
     $return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
     $this->set_timezone($original_timezone);
     return $return;
 }
コード例 #21
0
 /**
  *  @since 4.7.0
  */
 public function test_dates_represent_one_24_hour_date()
 {
     $midnight_start = new DateTime('2015-01-25 00:00:00');
     $midnight_end = new DateTime('2015-01-26 00:00:00');
     $midday_start = new DateTime('2015-01-25 12:00:00');
     $midday_end = new DateTime('2015-01-26 12:00:00');
     $midnight_next_day = new DateTime('2015-01-27 00:00:00');
     //first test nulls
     $this->assertFalse(EEH_DTT_Helper::dates_represent_one_24_hour_date(null, $midnight_end));
     $this->assertFalse(EEH_DTT_Helper::dates_represent_one_24_hour_date($midnight_start, null));
     //test non midnights
     $this->assertFalse(EEH_DTT_Helper::dates_represent_one_24_hour_date($midnight_start, $midday_end));
     $this->assertFalse(EEH_DTT_Helper::dates_represent_one_24_hour_date($midday_start, $midnight_end));
     //test midnights but not 24 hours difference
     $this->assertFalse(EEH_DTT_Helper::dates_represent_one_24_hour_date($midnight_start, $midnight_next_day));
     //test correct range
     $this->assertTrue(EEH_DTT_Helper::dates_represent_one_24_hour_date($midnight_start, $midnight_end));
 }