protected function _get_table_filters()
 {
     $filters = $where = array();
     EE_Registry::instance()->load_helper('Form_Fields');
     if (empty($this->_dtts_for_event)) {
         //this means we don't have an event so let's setup a filter dropdown for all the events to select
         //note possible capability restrictions
         if (!EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
             $where['status**'] = array('!=', 'private');
         }
         if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
             $where['EVT_wp_user'] = get_current_user_id();
         }
         $events = EEM_Event::instance()->get_all(array($where, 'order_by' => array('EVT_name' => 'asc')));
         $evts[] = array('id' => 0, 'text' => __('To toggle Check-in status, select an event', 'event_espresso'));
         foreach ($events as $evt) {
             //any registrations for this event?
             if (!$evt->get_count_of_all_registrations()) {
                 continue;
             }
             $evts[] = array('id' => $evt->ID(), 'text' => $evt->get('EVT_name'));
         }
         $filters[] = EEH_Form_Fields::select_input('event_id', $evts);
     } else {
         //DTT datetimes filter
         $cur_dtt = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : $this->_evt->primary_datetime()->ID();
         $dtts = array();
         foreach ($this->_dtts_for_event as $dtt) {
             $datetime_string = $dtt->start_date_and_time() . ' - ' . $dtt->end_date_and_time();
             $dtts[] = array('id' => $dtt->ID(), 'text' => $datetime_string);
         }
         $filters[] = EEH_Form_Fields::select_input('DTT_ID', $dtts, $cur_dtt);
     }
     return $filters;
 }
 /**
  *    get_event
  *    attempts to retrieve an EE_Event object any way it can
  *
  * @access    public
  * @param    int $EVT_ID
  * @return    object
  */
 public static function get_event($EVT_ID = 0)
 {
     $EVT_ID = $EVT_ID instanceof WP_Post ? $EVT_ID->ID : absint($EVT_ID);
     // do we already have the Event  you are looking for?
     if (EEH_Event_View::$_event instanceof EE_Event && $EVT_ID && EEH_Event_View::$_event->ID() === $EVT_ID) {
         return EEH_Event_View::$_event;
     }
     EEH_Event_View::$_event = NULL;
     // international newspaper?
     global $post;
     // if this is being called from an EE_Event post, then we can just grab the attached EE_Event object
     if (isset($post->post_type) && $post->post_type == 'espresso_events' || $EVT_ID) {
         //			d( $post );
         // grab the event we're looking for
         if (isset($post->EE_Event) && ($EVT_ID == 0 || $EVT_ID == $post->ID)) {
             EEH_Event_View::$_event = $post->EE_Event;
             //				d( EEH_Event_View::$_event );
         }
         // now if we STILL do NOT have an EE_Event model object, BUT we have an Event ID...
         if (!EEH_Event_View::$_event instanceof EE_Event && $EVT_ID) {
             // sigh... pull it from the db
             EEH_Event_View::$_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
             //				d( EEH_Event_View::$_event );
         }
     }
     return EEH_Event_View::$_event;
 }
 protected function _column_name_action_setup(EE_Event $item)
 {
     $export_query_args = array('action' => 'export_events', 'EVT_ID' => $item->ID());
     $export_event_link = EE_Admin_Page::add_query_args_and_nonce($export_query_args, EVENTS_ADMIN_URL);
     $actions = parent::_column_name_action_setup($item);
     //		$actions['export'] = '<a href="' . $export_event_link . '" title="' . __('Export Event', 'event_espresso') . '">' . __('Export', 'event_espresso') . '</a>';
     return $actions;
 }
 /**
  * Handles attaching Message Templates to the Event on save.
  * @param  EE_Event $evtobj EE event object
  * @param  array       $data   The request data from the form
  * @return bool         success or fail
  */
 public function attach_evt_message_templates($evtobj, $data)
 {
     //first we remove all existing relations on the Event for message types.
     $evtobj->_remove_relations('Message_Template_Group');
     //now let's just loop throught the selected templates and add relations!
     foreach ($data['event_message_templates_relation'] as $grp_ID) {
         $evtobj->_add_relation_to($grp_ID, 'Message_Template_Group');
     }
     //now save
     return $evtobj->save();
 }
 public function test_events()
 {
     $a = EE_Attendee::new_instance();
     $a->save();
     $this->assertNotEquals($a->ID(), 0);
     $e1 = EE_Event::new_instance(array('EVT_name' => '1'));
     $e1->save();
     $this->assertNotEquals($e1->ID(), 0);
     $e2 = EE_Event::new_instance(array('EVT_name' => '2'));
     $e2->save();
     $this->assertNotEquals($e2->ID(), 0);
     $e3 = EE_Event::new_instance(array('EVT_name' => '3'));
     $e3->save();
     $this->assertNotEquals($e3->ID(), 0);
     $r1 = EE_Registration::new_instance(array('EVT_ID' => $e1->ID(), 'ATT_ID' => $a->ID()));
     $r1->save();
     $this->assertNotEquals($r1->ID(), 0);
     $r2 = EE_Registration::new_instance(array('EVT_ID' => $e2->ID(), 'ATT_ID' => $a->ID()));
     $r2->save();
     $this->assertNotEquals($r2->ID(), 0);
     $events = $a->events();
     $this->assertArrayContains($e1, $events);
     $this->assertArrayContains($e2, $events);
     $this->assertArrayDoesNotContain($e3, $events);
 }
 /**
  * This grabs an EE_Messages_Addressee object for the Preview data handler.
  *
  * @return EE_Messages_Addressee
  */
 protected function _get_addressee($context = 'primary_attendee')
 {
     $data = new EE_Messages_Preview_incoming_data(array('event_ids' => array($this->_event->ID())));
     /**
      * @see EE_message_type::_init_data()
      */
     $addressee_data = array('billing' => $data->billing, 'taxes' => $data->taxes, 'tax_line_items' => $data->tax_line_items, 'additional_line_items' => $data->additional_line_items, 'grand_total_line_item' => $data->grand_total_line_item, 'txn' => $data->txn, 'payments' => $data->payments, 'payment' => isset($data->payment) ? $data->payment : NULL, 'reg_objs' => $data->reg_objs, 'registrations' => $data->registrations, 'datetimes' => $data->datetimes, 'tickets' => $data->tickets, 'line_items_with_children' => $data->line_items_with_children, 'questions' => $data->questions, 'answers' => $data->answers, 'txn_status' => $data->txn_status, 'total_ticket_count' => $data->total_ticket_count);
     if (is_array($data->primary_attendee_data)) {
         $addressee_data = array_merge($addressee_data, $data->primary_attendee_data);
         $addressee_data['primary_att_obj'] = $data->primary_attendee_data['att_obj'];
         $addressee_data['primary_reg_obj'] = $data->primary_attendee_data['reg_obj'];
     }
     /**
      * @see EE_message_type::_process_data()
      */
     switch ($context) {
         case 'primary_attendee':
         case 'purchaser':
             $aee = $addressee_data;
             $aee['events'] = $data->events;
             $aee['attendees'] = $data->attendees;
             return new EE_Messages_Addressee($aee);
             break;
         case 'attendee':
             //for the purpose of testing we're just going to do ONE attendee
             $attendee = reset($data->attendees);
             foreach ($attendee as $item => $value) {
                 $aee[$item] = $value;
                 if ($item == 'line_ref') {
                     foreach ($value as $event_id) {
                         $aee['events'][$event_id] = $data->events[$event_id];
                     }
                 }
             }
             $aee['reg_obj'] = array_shift($attendee['reg_objs']);
             $aee['attendees'] = $data->attendees;
             return new EE_Messages_Addressee($aee);
             break;
         case 'admin':
             //for the purpose of testing we're only setting up for the event we have active for testing.
             $aee['user_id'] = $this->_event->get('EVT_wp_user');
             $aee['events'] = $data->events;
             $aee['attendees'] = $data->attendees;
             return new EE_Messages_Addressee($aee);
     }
 }
 /**
  * update event_datetimes
  * @param  EE_Event 	$evt_obj Event being updated
  * @param  array    	$data    the request data from the form
  * @return EE_Datetime           array of EE_Datetime ids created/updated.
  */
 private function _update_dtts($evt_obj, $data)
 {
     $timezone = isset($data['timezone_string']) ? $data['timezone_string'] : NULL;
     $success = TRUE;
     foreach ($data['edit_event_datetimes'] as $row => $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_name' => !empty($dtt['DTT_name']) ? $dtt['DTT_name'] : '', 'DTT_description' => !empty($dtt['DTT_description']) ? $dtt['DTT_description'] : '', 'DTT_EVT_start' => $dtt['DTT_EVT_start'], 'DTT_EVT_end' => $dtt['DTT_EVT_end'], 'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? INF : $dtt['DTT_reg_limit'], 'DTT_order' => !isset($dtt['DTT_order']) ? $row : $dtt['DTT_order']);
         //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($timezone))->get_one_by_ID($dtt['DTT_ID']);
             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, $timezone), FALSE, FALSE);
         }
         $DTM->save();
         $DTT = $evt_obj->_add_relation_to($DTM, 'Datetime');
         //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'));
             EE_Registry::instance()->load_helper('DTT_Helper');
             EE_Registry::instance()->load_helper('DTT_Helper');
             $DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days');
             $DTT->save();
         }
         $datetimes_start_times[$DTT->start_date_and_time('Y-m-d', 'H:i:s')] = $DTT->ID();
         //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_dtts[$DTT->ID()] = $DTT;
         $saved_dtt_objs[$row] = $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.
     }
     //now we need to REMOVE any dtts that got deleted.  Keep in mind that this process will only kick in for DTT's that don't have any DTT_sold on them. So its safe to permanently delete at this point.
     $old_datetimes = explode(',', $data['datetime_IDs']);
     $old_datetimes = $old_datetimes[0] == '' ? array() : $old_datetimes;
     if (is_array($old_datetimes)) {
         $dtts_to_delete = array_diff($old_datetimes, array_keys($saved_dtts));
         foreach ($dtts_to_delete as $id) {
             $id = absint($id);
             if (empty($id)) {
                 continue;
             }
             $dtt_to_remove = EE_Registry::instance()->load_model('Datetime')->get_one_by_ID($id);
             //remove tkt relationships.
             $related_tickets = $dtt_to_remove->get_many_related('Ticket');
             foreach ($related_tickets as $tkt) {
                 $dtt_to_remove->_remove_relation_to($tkt, 'Ticket');
             }
             $evt_obj->_remove_relation_to($id, 'Datetime');
         }
     }
     return $saved_dtt_objs;
 }
 public function test_get_all__caps__delete__with_assign_event_category()
 {
     //log the user in
     global $current_user;
     $current_user = $this->user;
     $current_user->add_cap('ee_edit_events');
     $current_user->add_cap('ee_assign_event_category');
     //now check they can only see the term relationship for their own event
     $term_rs = EEM_Term_Relationship::instance()->get_all(array(array('object_id' => array('IN', array($this->my_event->ID(), $this->others_event->ID()))), 'order_by' => array('object_id' => 'ASC'), 'caps' => EEM_Base::caps_delete));
     $this->assertEEModelObjectsEquals($this->term_r_for_my_event, reset($term_rs));
     $this->assertEquals(1, count($term_rs));
 }
 function test_get_number_of_tickets_sold()
 {
     $e = EE_Event::new_instance();
     $e->save();
     $d_now = EE_Datetime::new_instance(array('EVT_ID' => $e->ID(), 'DTT_EVT_start' => time() - 100, 'DTT_EVT_end' => time() - 50, 'DTT_sold' => 5));
     $d_now->save();
     $d_exp = EE_Datetime::new_instance(array('EVT_ID' => $e->ID(), 'DTT_EVT_start' => time() - 10, 'DTT_EVT_end' => time() - 5, 'DTT_sold' => 15));
     $d_exp->save();
     $this->assertEquals(20, $e->get_number_of_tickets_sold());
     $e->_remove_relation_to($d_now, 'Datetime');
     $this->assertEquals(15, $e->get_number_of_tickets_sold());
 }
 /**
  * 	display_ticket_selector_submit
  *
  *	@access public
  * 	@access 		public
  * 	@return		string
  */
 public static function display_view_details_btn()
 {
     if (!self::$_event->get_permalink()) {
         $msg = __('The URL for the Event Details page could not be retrieved.', 'event_espresso');
         EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
     }
     $view_details_btn = '<form id="" method="POST" action="' . self::$_event->get_permalink() . '">';
     $btn_text = apply_filters('FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text', __('View Details', 'event_espresso'));
     $view_details_btn .= '<input id="ticket-selector-submit-' . self::$_event->ID() . '-btn" class="ticket-selector-submit-btn" type="submit" value="' . $btn_text . '" /><div class="clear"><br/></div>';
     $view_details_btn .= '</form>';
     return $view_details_btn;
 }
 public function setUp()
 {
     parent::setUp();
     //let's make sure we start off with NO tickets in the DB
     EEM_Ticket::instance()->delete_permanently(EEM_Ticket::instance()->alter_query_params_so_deleted_and_undeleted_items_included(), false);
     $this->assertEquals(0, EEM_Ticket::instance()->count(EEM_Ticket::instance()->alter_query_params_so_deleted_and_undeleted_items_included()));
     $this->user = $this->factory->user->create_and_get();
     $this->e_mine = $this->new_model_obj_with_dependencies('Event', array('EVT_wp_user' => $this->user->ID, 'status' => 'publish'));
     $this->e_others = $this->new_model_obj_with_dependencies('Event', array('EVT_wp_user' => 99999, 'status' => 'publish'));
     $this->e_private = $this->new_model_obj_with_dependencies('Event', array('EVT_wp_user' => 99999, 'status' => 'private'));
     $this->t_mine = $this->new_model_obj_with_dependencies('Ticket', array('TKT_is_default' => false, 'TKT_wp_user' => $this->user->ID));
     $this->t_others = $this->new_model_obj_with_dependencies('Ticket', array('TKT_is_default' => false, 'TKT_wp_user' => 9999));
     $this->t_private = $this->new_model_obj_with_dependencies('Ticket', array('TKT_is_default' => false, 'TKT_wp_user' => 9999));
     $this->t_mine_default = $this->new_model_obj_with_dependencies('Ticket', array('TKT_is_default' => true, 'TKT_wp_user' => $this->user->ID));
     $this->t_others_default = $this->new_model_obj_with_dependencies('Ticket', array('TKT_is_default' => true, 'TKT_wp_user' => 9999));
     $dtt_to_mine = $this->new_model_obj_with_dependencies('Datetime', array('EVT_ID' => $this->e_mine->ID()));
     $dtt_to_mine->_add_relation_to($this->t_mine, 'Ticket');
     $dtt_to_others = $this->new_model_obj_with_dependencies('Datetime', array('EVT_ID' => $this->e_others->ID()));
     $dtt_to_others->_add_relation_to($this->t_others, 'Ticket');
     $dtt_to_private = $this->new_model_obj_with_dependencies('Datetime', array('EVT_ID' => $this->e_private->ID()));
     $dtt_to_private->_add_relation_to($this->t_private, 'Ticket');
 }
 function test_finalize()
 {
     $t = EE_Transaction::new_instance(array('STS_ID' => EEM_Transaction::complete_status_code));
     $t->save();
     $e = EE_Event::new_instance();
     $e->save();
     $tkt = EE_Ticket::new_instance();
     $tkt->save();
     $d = EE_Datetime::new_instance(array('EVT_ID' => $e->ID()));
     $d->save();
     $tkt->_add_relation_to($d, 'Datetime');
     /** @type EE_Registration_Processor $registration_processor */
     $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
     $reg_url = $registration_processor->generate_reg_url_link(1, EE_Line_Item::new_instance(array('LIN_name' => $tkt->name(), 'LIN_desc' => $tkt->description(), 'LIN_unit_price' => $tkt->price(), 'LIN_quantity' => 1, 'LIN_is_taxable' => $tkt->taxable(), 'LIN_order' => 0, 'LIN_total' => $tkt->price(), 'LIN_type' => EEM_Line_Item::type_line_item, 'OBJ_ID' => $tkt->ID(), 'OBJ_type' => 'Ticket')));
     $r = EE_REgistration::new_instance(array('EVT_ID' => $e->ID(), 'TXN_ID' => $t->ID(), 'TKT_ID' => $tkt->ID(), 'STS_ID' => EEM_Registration::status_id_pending_payment, 'REG_url_link' => $reg_url));
     $r->set_reg_code($registration_processor->generate_reg_code($r));
     $registration_processor->update_registration_after_checkout_or_payment($r);
     $this->assertNotNull($r->reg_code());
     $this->assertEquals(EEM_Registration::status_id_approved, $r->status_ID());
 }
 public function test_insert_and_update_and_delete()
 {
     $term1 = EE_Term::new_instance(array('name' => 'monkey1', 'slug' => 'monkey1'));
     $term2 = EE_Term::new_instance(array('name' => 'monkey2', 'slug' => 'monkey2'));
     $term1->save();
     $term2->save();
     $tt_1 = EE_Term_Taxonomy::new_instance(array('taxonomy' => 'whatever', 'term_id' => $term1->ID()));
     $tt_1->save();
     $tt_2 = EE_Term_Taxonomy::new_instance(array('taxonomy' => 'whatever', 'term_id' => $term2->ID()));
     $tt_2->save();
     $e = EE_Event::new_instance(array('EVT_name' => 'for_term_1'));
     $e->save();
     //ok done setup
     //test INSERT
     $this->assertEquals(0, $tt_1->count());
     $new_tr_id = EEM_Term_Relationship::instance()->insert(array('term_taxonomy_id' => $tt_1->ID(), 'object_id' => $e->ID()));
     $this->assertNotNull($new_tr_id);
     //refresh out term_taxonomy objects, as the database has changed
     $tt_1 = EEM_Term_Taxonomy::reset()->get_one_by_ID($tt_1->ID());
     $tt_2 = EEM_Term_Taxonomy::instance()->get_one_by_ID($tt_2->ID());
     $this->assertEquals(1, $tt_1->count());
     $this->assertEquals(0, $tt_2->count());
     //test UPDATE... except we can't update term_relationship because there's no Primary Key
     //on it. This should be fixed at some point
     //@todo: fix this test
     //		$updated = EEM_Term_Relationship::instance()->update_by_ID(array('term_taxonomy_id'=>$tt_2->ID() ), $new_tr_id );
     //		//refresh out term_taxonomy objects, as the database has changed
     //		$tt_1 = EEM_Term_Taxonomy::reset()->get_one_by_ID( $tt_1->ID() );
     //		$tt_2 = EEM_Term_Taxonomy::instance()->get_one_by_ID($tt_2->ID() );
     //		$this->assertEquals( 0, $tt_1->count() );
     //		$this->assertEquals(1,$tt_2->count() );
     //test DELETE
     //@todo: fix this test too. see above
     //		$count_deleted = EEM_Term_Relationship::instance()->delete_by_ID($new_tr_id);
     //		$this->assertNotEmpty( $count_deleted );
     //		//refresh out term_taxonomy objects, as the database has changed
     //		$tt_1 = EEM_Term_Taxonomy::reset()->get_one_by_ID( $tt_1->ID() );
     //		$tt_2 = EEM_Term_Taxonomy::instance()->get_one_by_ID($tt_2->ID() );
     //		$this->assertEquals( 0, $tt_1->count() );
     //		$this->assertEquals(0,$tt_2->count() );
 }
 protected function _get_table_filters()
 {
     $filters = $where = array();
     if (empty($this->_dtts_for_event)) {
         //this means we don't have an event so let's setup a filter dropdown for all the events to select
         //note possible capability restrictions
         if (!EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
             $where['status**'] = array('!=', 'private');
         }
         if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
             $where['EVT_wp_user'] = get_current_user_id();
         }
         $events = EEM_Event::instance()->get_all(array($where, 'order_by' => array('Datetime.DTT_EVT_start' => 'DESC')));
         $evts[] = array('id' => 0, 'text' => __('To toggle Check-in status, select an event', 'event_espresso'));
         foreach ($events as $evt) {
             //any registrations for this event?
             if (!$evt->get_count_of_all_registrations()) {
                 continue;
             }
             $evts[] = array('id' => $evt->ID(), 'text' => $evt->get('EVT_name'), 'class' => $evt->is_expired() ? 'ee-expired-event' : '');
         }
         $event_filter = '<div class="ee-event-filter">';
         $event_filter .= EEH_Form_Fields::select_input('event_id', $evts);
         $event_filter .= '<br><span class="ee-event-filter-toggle"><input type="checkbox" id="js-ee-hide-expired-events" checked>' . ' ' . __('Hide Expired Events', 'event_espresso') . '</span>';
         $event_filter .= '</div>';
         $filters[] = $event_filter;
     } else {
         //DTT datetimes filter
         $cur_dtt = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : $this->_evt->primary_datetime()->ID();
         $dtts = array();
         foreach ($this->_dtts_for_event as $dtt) {
             $datetime_string = $dtt->start_date_and_time() . ' - ' . $dtt->end_date_and_time();
             $dtts[] = array('id' => $dtt->ID(), 'text' => $datetime_string);
         }
         $filters[] = EEH_Form_Fields::select_input('DTT_ID', $dtts, $cur_dtt);
     }
     return $filters;
 }
 /**
  * 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;
 }
 private function _get_registrations_from_event(EE_Event $event)
 {
     return isset($this->_extra_data['data']->events) ? $this->_extra_data['data']->events[$event->ID()]['reg_objs'] : array();
 }
 public function column_author(EE_Event $item)
 {
     //user author info
     $event_author = get_userdata($item->wp_user());
     $gravatar = get_avatar($item->wp_user(), '15');
     //filter link
     $query_args = array('action' => 'default', 'EVT_wp_user' => $item->wp_user());
     $filter_url = EE_Admin_Page::add_query_args_and_nonce($query_args, EVENTS_ADMIN_URL);
     return $gravatar . '  <a href="' . $filter_url . '" title="' . esc_attr__('Click to filter events by this author.', 'event_espresso') . '">' . $event_author->display_name . '</a>';
 }
 public function column_status(EE_Event $item)
 {
     return '<span class="ee-status-strip ee-status-strip-td event-status-' . $item->get_active_status() . '"></span>';
 }
 /**
  * Helper method to return the user object for the author of the given EE_Event
  *
  * @param EE_Event $event
  *
  * @return WP_User
  */
 private function _get_author_for_event(EE_Event $event)
 {
     $author_id = $event->wp_user();
     $user_data = get_userdata((int) $author_id);
     return $user_data;
 }
 private function _get_datetimes_from_event(EE_Event $event, $reg = NULL)
 {
     $evt_dtts = isset($this->_extra_data['data']->events) ? $this->_extra_data['data']->events[$event->ID()]['dtt_objs'] : array();
     if ($reg instanceof EE_Registration && $this->_extra_data['data'] instanceof EE_Messages_Addressee) {
         $adj_dtts = array();
         //return only dtts for the given attendee
         foreach ($evt_dtts as $dtt) {
             if (isset($this->_extra_data['data']->registrations[$reg->ID()]['dtt_objs'][$dtt->ID()])) {
                 $adj_dtts[] = $dtt;
             }
         }
         $evt_dtts = $adj_dtts;
     }
     return $evt_dtts;
 }
 /**
  * Contains tests for the update_dtts method and update_tkts method.
  * @since 4.6
  */
 public function test_update_dtts_and_update_tkts()
 {
     $this->_load_pricing_mock();
     $formats_to_test = $this->date_formats_to_test();
     $saved_dtts_for_tickets = $formats_for_compare = $saved_tkts = array();
     //test each date and time format combination for creating datetime objects
     foreach ($formats_to_test['date'] as $date_format) {
         foreach ($formats_to_test['time'] as $time_format) {
             $full_format = $date_format . ' ' . $time_format;
             $this->_pricingMock->set_date_format_strings(array('date' => $date_format, 'time' => $time_format));
             $data = $this->_get_save_data($full_format);
             $dtts = $this->_pricingMock->update_dtts($this->_event, $data);
             foreach ($dtts as $dtt) {
                 $this->assertInstanceof('EE_Datetime', $dtt);
                 //verify start and date
                 $this->assertEquals($dtt->start_date_and_time(), $this->_default_dates['DTT_start']->format($full_format), sprintf('Start Date Format Tested: %s', $full_format));
                 $this->assertEquals($dtt->end_date_and_time(), $this->_default_dates['DTT_end']->format($full_format), sprintf('End Date Format Tested: %s', $full_format));
                 $saved_dtts_for_tickets[$full_format] = $dtt;
                 $formats_for_compare[$dtt->ID()] = array($date_format, $time_format);
             }
         }
     }
     //test each date and time format combination for creating ticket objects
     foreach ($formats_to_test['date'] as $date_format) {
         foreach ($formats_to_test['time'] as $time_format) {
             $full_format = $date_format . ' ' . $time_format;
             $this->_pricingMock->set_date_format_strings(array('date' => $date_format, 'time' => $time_format));
             $data = $this->_get_save_data($full_format);
             $dtt_for_ticket['1'] = $saved_dtts_for_tickets[$full_format];
             $tkts = $this->_pricingMock->update_tkts($this->_event, $dtt_for_ticket, $data);
             foreach ($tkts as $tkt) {
                 $this->assertInstanceof('EE_Ticket', $tkt, sprintf('Format: %s', $full_format));
                 //verify start and date
                 $this->assertEquals($tkt->start_date(), $this->_default_dates['TKT_start']->format($full_format), sprintf('Start Ticket DateFormat Tested: %s', $full_format));
                 $this->assertEquals($tkt->end_date(), $this->_default_dates['TKT_end']->format($full_format), sprintf('End Ticket Date Format Tested: %s', $full_format));
                 $saved_tkts[$full_format] = $tkt;
             }
         }
     }
     //now let's verify these items were saved corectly in the db.
     /*$new_tkts = $new_dtts = array();
     		foreach ( $tkt as $format => $tkt ) {
     			$new_tkts[$format] = EEM_Ticket::instance()->refresh_entity_map_from_db( $tkt->ID() );
     		}
     
     		foreach ( $saved_dtts_for_tickets[$full_format] as $format => $dtt ) {
     			$new_dtts[$format] = EEM_Datetime::instance()->refresh_entity_map_from_db( $dtt->ID() );
     		}/**/
     $new_event = EEM_Event::instance()->refresh_entity_map_from_db($this->_event->ID());
     $new_event->set_timezone('America/Vancouver');
     $evt_dtts = $new_event->datetimes_ordered();
     //now let's do comparisons.
     foreach ($evt_dtts as $edtt) {
         $formats = $formats_for_compare[$edtt->ID()];
         $format = $formats[0] . ' ' . $formats[1];
         $this->assertEquals($edtt->start_date_and_time($formats[0], $formats[1]), $this->_default_dates['DTT_start']->format($format), sprintf('DB DTT/Default DTT Start Date Format Checked: %s', $format));
         $this->assertEquals($edtt->end_date_and_time($formats[0], $formats[1]), $this->_default_dates['DTT_end']->format($format), sprintf('DB DTT/Default DTT End Date Format Checked: %s', $format));
         $this->assertEquals($edtt->start_date_and_time($formats[0], $formats[1]), $saved_dtts_for_tickets[$format]->start_date_and_time(), sprintf('DB DTT/Orig DTT Start Date Format Checked: %s', $format));
         $this->assertEquals($edtt->end_date_and_time($formats[0], $formats[1]), $saved_dtts_for_tickets[$format]->end_date_and_time(), sprintf('DB DTT/Orig DTT End Date Format Checked: %s', $format));
         //get related ticket on this $edtt
         $evt_tkt = $edtt->get_first_related('Ticket');
         $this->assertEquals($evt_tkt->start_date($formats[0], $formats[1]), $this->_default_dates['TKT_start']->format($format), sprintf('DB TKT/Default TKT Start Date Format Checked: %s', $format));
         $this->assertEquals($evt_tkt->end_date($formats[0], $formats[1]), $this->_default_dates['TKT_end']->format($format), sprintf('DB TKT/Default TKT End Date Format Checked: %s', $format));
         $this->assertEquals($evt_tkt->start_date($formats[0], $formats[1]), $saved_tkts[$format]->start_date($formats[0], $formats[1]), sprintf('DB TKT/Orig TKT Start Date Format Checked: %s', $format));
         $this->assertEquals($evt_tkt->end_date($formats[0], $formats[1]), $saved_tkts[$format]->end_date($formats[0], $formats[1]), sprintf('DB TKT/Orig TKT End Date Format Checked: %s', $format));
     }
 }
 public function test_delete()
 {
     $e1 = EE_Event::new_instance();
     $e1->save();
     $e2 = EE_Event::new_instance();
     $e2->save();
     $e3 = EE_Event::new_instance();
     $e3->save();
     //now assert things are as they should be: the items are in teh Db and the entity map
     $this->assertEquals(EEM_Event::instance()->get_one_by_ID($e1->ID()), $e1);
     $this->assertEquals(EEM_Event::instance()->get_one_by_ID($e2->ID()), $e2);
     $this->assertEquals(EEM_Event::instance()->get_one_by_ID($e3->ID()), $e3);
     $this->assertEquals(EEM_Event::instance()->get_from_entity_map($e1->ID()), $e1);
     $this->assertEquals(EEM_Event::instance()->get_from_entity_map($e2->ID()), $e2);
     $this->assertEquals(EEM_Event::instance()->get_from_entity_map($e3->ID()), $e3);
     //now run a delete query that should have deleted $e1 and $e2
     EEM_Event::instance()->delete_permanently(array(array('EVT_ID' => array('<=', $e2->ID()))));
     //check $e1 and $e2 don't exist in the DB anymore
     $this->assertEmpty(EEM_Event::instance()->get_one_by_ID($e1->ID()));
     $this->assertEmpty(EEM_Event::instance()->get_one_by_ID($e2->ID()));
     $this->assertEquals(EEM_Event::instance()->get_one_by_ID($e3->ID()), $e3);
     //and now chekc $e1 and $e2 don't exist in the entity map either
     $this->assertEmpty(EEM_Event::instance()->get_from_entity_map($e1->ID()));
     $this->assertEmpty(EEM_Event::instance()->get_from_entity_map($e2->ID()));
     $this->assertEquals(EEM_Event::instance()->get_from_entity_map($e3->ID()), $e3);
 }
 /**
  * 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);
 }
 function test_parent()
 {
     $e = EE_Event::new_instance(array('parent' => 12));
     $this->assertEquals($e->parent(), 12);
 }
 /**
  * @param EE_Event $item
  *
  * @return string
  */
 public function column_actions(EE_Event $item)
 {
     //todo: remove when attendees is active
     if (!defined('REG_ADMIN_URL')) {
         define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
     }
     $actionlinks = array();
     $view_link = get_permalink($item->ID());
     $actionlinks[] = '<a href="' . $view_link . '" title="' . esc_attr__('View Event', 'event_espresso') . '" target="_blank">';
     $actionlinks[] = '<div class="dashicons dashicons-search"></div></a>';
     if (EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'espresso_events_edit', $item->ID())) {
         $edit_query_args = array('action' => 'edit', 'post' => $item->ID());
         $edit_link = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
         $actionlinks[] = '<a href="' . $edit_link . '" title="' . esc_attr__('Edit Event', 'event_espresso') . '"><div class="ee-icon ee-icon-calendar-edit"></div></a>';
     }
     if (EE_Registry::instance()->CAP->current_user_can('ee_read_registration', 'espresso_registrations_view_registration', $item->ID())) {
         $attendees_query_args = array('action' => 'default', 'event_id' => $item->ID());
         $attendees_link = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
         $actionlinks[] = '<a href="' . $attendees_link . '" title="' . esc_attr__('View Registrants', 'event_espresso') . '"><div class="dashicons dashicons-groups"></div></a>';
     }
     $actionlinks = apply_filters('FHEE__Events_Admin_List_Table__column_actions__action_links', $actionlinks, $item);
     return $this->_action_string(implode("\n\t", $actionlinks), $item, 'div');
 }
 /**
  * @param \EE_Transaction $transaction
  * @param \EE_Ticket $ticket
  * @param \EE_Event $event
  * @param float $REG_final_price
  * @return \EE_Registration
  * @throws \EE_Error
  */
 public function get_registration_mock(EE_Transaction $transaction, EE_Ticket $ticket, EE_Event $event, $REG_final_price = 10.0)
 {
     return $this->new_model_obj_with_dependencies('Registration', array('TXN_ID' => $transaction->ID(), 'TKT_ID' => $ticket->ID(), 'EVT_ID' => $event->ID(), 'REG_final_price' => $REG_final_price, 'REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT));
 }
 private function _get_datetimes_from_event(EE_Event $event, $att = NULL)
 {
     return isset($this->_extra_data['data']->events) ? $this->_extra_data['data']->events[$event->ID()]['dtt_objs'] : array();
 }
 /**
  *    get_all_event_tickets
  *
  * @access    protected
  * @param \EE_Event $event
  * @return array
  */
 protected static function get_all_event_tickets(EE_Event $event)
 {
     $tickets = array();
     // get active events
     foreach ($event->datetimes_ordered(false) as $datetime) {
         $datetime_tickets = $datetime->ticket_types_available_for_purchase();
         foreach ($datetime_tickets as $datetime_ticket) {
             if ($datetime_ticket instanceof EE_Ticket) {
                 $tickets[$datetime_ticket->ID()] = $datetime_ticket;
             }
         }
     }
     return $tickets;
 }
 protected function _parser($shortcode)
 {
     EE_Registry::instance()->load_helper('Formatter');
     $this->_event = $this->_data instanceof EE_Event ? $this->_data : null;
     //if no event, then let's see if there is a reg_obj.  If there IS, then we'll try and grab the event from the reg_obj instead.
     if (empty($this->_event)) {
         $aee = $this->_data instanceof EE_Messages_Addressee ? $this->_data : NULL;
         $aee = $this->_extra_data instanceof EE_Messages_Addressee ? $this->_extra_data : $aee;
         $this->_event = $aee instanceof EE_Messages_Addressee && $aee->reg_obj instanceof EE_Registration ? $aee->reg_obj->event() : NULL;
     }
     //If there is no event objecdt by now then get out.
     if (!$this->_event instanceof EE_Event) {
         return '';
     }
     switch ($shortcode) {
         case '[EVENT_ID]':
             return $this->_event->ID();
             break;
         case '[EVENT_IDENTIFIER]':
             return isset($this->_data['line_ref']) ? $this->_data['line_ref'] : '';
             break;
         case '[EVENT]':
         case '[EVENT_NAME]':
             return $this->_event->get('EVT_name');
             break;
         case '[EVENT_PHONE]':
             return $this->_event->get('EVT_phone');
             break;
         case '[EVENT_DESCRIPTION]':
             return $this->_event->get('EVT_desc');
             break;
         case '[EVENT_EXCERPT]':
             return $this->_event->get('EVT_short_desc');
             break;
         case '[EVENT_LINK]':
             return $this->_get_event_link($this->_event);
             break;
         case '[EVENT_URL]':
             return $this->_get_event_link($this->_event, FALSE);
             break;
         case '[VIRTUAL_URL]':
             $venue = $this->_event->get_first_related('Venue');
             if (empty($venue)) {
                 return '';
             }
             return $venue->get('VNU_virtual_url');
         case '[VIRTUAL_PHONE]':
             $venue = $this->_event->get_first_related('Venue');
             if (empty($venue)) {
                 return '';
             }
             return $venue->get('VNU_virtual_phone');
             break;
         case '[EVENT_IMAGE]':
             $image = $this->_event->feature_image_url(array(600, 300));
             // @todo: eventually we should make this an attribute shortcode so that em can send along what size they want returned.
             return !empty($image) ? '<img src="' . $image . '" alt="' . sprintf(esc_attr__('%s Feature Image', 'event_espresso'), $this->_event->get('EVT_name')) . '" />' : '';
             break;
         case '[EVENT_FACEBOOK_URL]':
             $facebook_url = $this->_event->get_post_meta('event_facebook', true);
             return empty($facebook_url) ? EE_Registry::instance()->CFG->organization->get_pretty('facebook') : $facebook_url;
             break;
         case '[EVENT_TWITTER_URL]':
             $twitter_url = $this->_event->get_post_meta('event_twitter', true);
             return empty($twitter_url) ? EE_Registry::instance()->CFG->organization->get_pretty('twitter') : $twitter_url;
             break;
         case '[EVENT_AUTHOR_EMAIL]':
             $author_id = $this->_event->get('EVT_wp_user');
             $user_data = get_userdata((int) $author_id);
             return $user_data->user_email;
             break;
         case '[EVENT_TOTAL_SPOTS_TAKEN]':
             return EEM_Registration::instance()->count(array(array('EVT_ID' => $this->_event->ID(), 'STS_ID' => EEM_Registration::status_id_approved)), 'REG_ID', true);
             break;
         case '[REGISTRATION_LIST_TABLE_FOR_EVENT_URL]':
             EE_Registry::instance()->load_helper('URL');
             return EEH_URL::add_query_args_and_nonce(array('event_id' => $this->_event->ID(), 'page' => 'espresso_registrations', 'action' => 'default'), admin_url('admin.php'), true);
             break;
     }
     if (strpos($shortcode, '[EVENT_META_*') !== false) {
         $shortcode = str_replace('[EVENT_META_*', '', $shortcode);
         $shortcode = trim(str_replace(']', '', $shortcode));
         //pull the meta value from the event post
         $event_meta = $this->_event->get_post_meta($shortcode, true);
         return !empty($event_meta) ? $this->_event->get_post_meta($shortcode, true) : '';
     }
     if (strpos($shortcode, '[EVENT_TOTAL_AVAILABLE_SPACES_*') !== false) {
         $attrs = $this->_get_shortcode_attrs($shortcode);
         $method = empty($attrs['method']) ? 'current' : $attrs['method'];
         $method = $method === 'current';
         $available = $this->_event->total_available_spaces($method);
         return $available === INF ? '&infin;' : $available;
     }
     return '';
 }
 /**
  * used by factory to create event object
  *
  * @since 4.3.0
  *
  * @param array $args Incoming field values to set on the new object
  *
  * @return EE_Event|false
  */
 public function create_object($args)
 {
     $event = EE_Event::new_instance($args);
     $evtID = $event->save();
     return $evtID ? $event : false;
 }