Completed
Branch BUG-10851-events-shortcode (1f397b)
by
unknown
11:46 queued 10s
created
core/services/commands/attendee/CreateAttendeeCommandHandler.php 2 patches
Indentation   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -35,7 +35,7 @@  discard block
 block discarded – undo
35 35
 	 * @param EEM_Attendee $attendee_model
36 36
 	 */
37 37
 	public function __construct(EEM_Attendee $attendee_model ) {
38
-        $this->attendee_model = $attendee_model;
38
+		$this->attendee_model = $attendee_model;
39 39
 	}
40 40
 
41 41
 
@@ -83,7 +83,7 @@  discard block
 block discarded – undo
83 83
 	private function findExistingAttendee( EE_Registration $registration, array $attendee_data ) {
84 84
 		$existing_attendee = null;
85 85
 		// does this attendee already exist in the db ?
86
-        // we're searching using a combination of first name, last name, AND email address
86
+		// we're searching using a combination of first name, last name, AND email address
87 87
 		$ATT_fname = ! empty( $attendee_data['ATT_fname'] )
88 88
 			? $attendee_data['ATT_fname']
89 89
 			: '';
@@ -124,8 +124,8 @@  discard block
 block discarded – undo
124 124
 	 */
125 125
 	private function updateExistingAttendeeData( EE_Attendee $existing_attendee, array $attendee_data ) {
126 126
 		// first remove fname, lname, and email from attendee data
127
-        // because these properties will be exactly the same as the returned attendee object,
128
-        // since they were used in the query to get the attendee object in the first place
127
+		// because these properties will be exactly the same as the returned attendee object,
128
+		// since they were used in the query to get the attendee object in the first place
129 129
 		$dont_set = array( 'ATT_fname', 'ATT_lname', 'ATT_email' );
130 130
 		// now loop thru what's left and add to attendee CPT
131 131
 		foreach ( $attendee_data as $property_name => $property_value ) {
Please login to merge, or discard this patch.
Spacing   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -9,7 +9,7 @@  discard block
 block discarded – undo
9 9
 use EventEspresso\core\services\commands\CommandHandler;
10 10
 use EventEspresso\core\services\commands\CommandInterface;
11 11
 
12
-defined( 'EVENT_ESPRESSO_VERSION' ) || exit;
12
+defined('EVENT_ESPRESSO_VERSION') || exit;
13 13
 
14 14
 
15 15
 
@@ -34,7 +34,7 @@  discard block
 block discarded – undo
34 34
 	/**
35 35
 	 * @param EEM_Attendee $attendee_model
36 36
 	 */
37
-	public function __construct(EEM_Attendee $attendee_model ) {
37
+	public function __construct(EEM_Attendee $attendee_model) {
38 38
         $this->attendee_model = $attendee_model;
39 39
 	}
40 40
 
@@ -46,10 +46,10 @@  discard block
 block discarded – undo
46 46
 	 * @throws EE_Error
47 47
 	 * @throws InvalidEntityException
48 48
 	 */
49
-	public function handle( CommandInterface $command ) {
49
+	public function handle(CommandInterface $command) {
50 50
 		/** @var CreateAttendeeCommand $command */
51
-		if ( ! $command instanceof CreateAttendeeCommand ) {
52
-			throw new InvalidEntityException( get_class( $command ), 'CreateAttendeeCommand' );
51
+		if ( ! $command instanceof CreateAttendeeCommand) {
52
+			throw new InvalidEntityException(get_class($command), 'CreateAttendeeCommand');
53 53
 		}
54 54
 		// have we met before?
55 55
 		$attendee = $this->findExistingAttendee(
@@ -57,7 +57,7 @@  discard block
 block discarded – undo
57 57
 			$command->attendeeDetails()
58 58
 		);
59 59
 		// did we find an already existing record for this attendee ?
60
-		if ( $attendee instanceof EE_Attendee ) {
60
+		if ($attendee instanceof EE_Attendee) {
61 61
 			$attendee = $this->updateExistingAttendeeData(
62 62
 				$attendee,
63 63
 				$command->attendeeDetails()
@@ -80,21 +80,21 @@  discard block
 block discarded – undo
80 80
 	 * @param  array           $attendee_data
81 81
 	 * @return EE_Attendee
82 82
 	 */
83
-	private function findExistingAttendee( EE_Registration $registration, array $attendee_data ) {
83
+	private function findExistingAttendee(EE_Registration $registration, array $attendee_data) {
84 84
 		$existing_attendee = null;
85 85
 		// does this attendee already exist in the db ?
86 86
         // we're searching using a combination of first name, last name, AND email address
87
-		$ATT_fname = ! empty( $attendee_data['ATT_fname'] )
87
+		$ATT_fname = ! empty($attendee_data['ATT_fname'])
88 88
 			? $attendee_data['ATT_fname']
89 89
 			: '';
90
-		$ATT_lname = ! empty( $attendee_data['ATT_lname'] )
90
+		$ATT_lname = ! empty($attendee_data['ATT_lname'])
91 91
 			? $attendee_data['ATT_lname']
92 92
 			: '';
93
-		$ATT_email = ! empty( $attendee_data['ATT_email'] )
93
+		$ATT_email = ! empty($attendee_data['ATT_email'])
94 94
 			? $attendee_data['ATT_email']
95 95
 			: '';
96 96
 		// but only if those have values
97
-		if ( $ATT_fname && $ATT_lname && $ATT_email ) {
97
+		if ($ATT_fname && $ATT_lname && $ATT_email) {
98 98
 			$existing_attendee = $this->attendee_model->find_existing_attendee(
99 99
 				array(
100 100
 					'ATT_fname' => $ATT_fname,
@@ -122,18 +122,18 @@  discard block
 block discarded – undo
122 122
 	 * @return EE_Attendee
123 123
 	 * @throws EE_Error
124 124
 	 */
125
-	private function updateExistingAttendeeData( EE_Attendee $existing_attendee, array $attendee_data ) {
125
+	private function updateExistingAttendeeData(EE_Attendee $existing_attendee, array $attendee_data) {
126 126
 		// first remove fname, lname, and email from attendee data
127 127
         // because these properties will be exactly the same as the returned attendee object,
128 128
         // since they were used in the query to get the attendee object in the first place
129
-		$dont_set = array( 'ATT_fname', 'ATT_lname', 'ATT_email' );
129
+		$dont_set = array('ATT_fname', 'ATT_lname', 'ATT_email');
130 130
 		// now loop thru what's left and add to attendee CPT
131
-		foreach ( $attendee_data as $property_name => $property_value ) {
131
+		foreach ($attendee_data as $property_name => $property_value) {
132 132
 			if (
133
-				! in_array( $property_name, $dont_set, true )
134
-				&& $this->attendee_model->has_field( $property_name )
133
+				! in_array($property_name, $dont_set, true)
134
+				&& $this->attendee_model->has_field($property_name)
135 135
 			) {
136
-				$existing_attendee->set( $property_name, $property_value );
136
+				$existing_attendee->set($property_name, $property_value);
137 137
 			}
138 138
 		}
139 139
 		// better save that now
@@ -151,11 +151,11 @@  discard block
 block discarded – undo
151 151
 	 * @return EE_Attendee
152 152
 	 * @throws EE_Error
153 153
 	 */
154
-	private function createNewAttendee( EE_Registration $registration, array $attendee_data ) {
154
+	private function createNewAttendee(EE_Registration $registration, array $attendee_data) {
155 155
 		// create new attendee object
156
-		$new_attendee = EE_Attendee::new_instance( $attendee_data );
156
+		$new_attendee = EE_Attendee::new_instance($attendee_data);
157 157
 		// set author to event creator
158
-		$new_attendee->set( 'ATT_author', $registration->event()->wp_user() );
158
+		$new_attendee->set('ATT_author', $registration->event()->wp_user());
159 159
 		$new_attendee->save();
160 160
 		return $new_attendee;
161 161
 	}
Please login to merge, or discard this patch.
core/domain/services/registration/CreateRegistrationService.php 2 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -39,8 +39,8 @@
 block discarded – undo
39 39
 	 * @param EE_Transaction $transaction
40 40
 	 * @param EE_Ticket      $ticket
41 41
 	 * @param EE_Line_Item   $ticket_line_item
42
-	 * @param                 $reg_count
43
-	 * @param                 $reg_group_size
42
+	 * @param                 integer $reg_count
43
+	 * @param                 integer $reg_group_size
44 44
      * @param string          $reg_status
45 45
      * @return EE_Registration
46 46
 	 * @throws OutOfRangeException
Please login to merge, or discard this patch.
Indentation   +76 added lines, -76 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
 use OutOfRangeException;
18 18
 
19 19
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
20
-    exit('No direct script access allowed');
20
+	exit('No direct script access allowed');
21 21
 }
22 22
 
23 23
 
@@ -41,54 +41,54 @@  discard block
 block discarded – undo
41 41
 	 * @param EE_Line_Item   $ticket_line_item
42 42
 	 * @param                 $reg_count
43 43
 	 * @param                 $reg_group_size
44
-     * @param string          $reg_status
45
-     * @return EE_Registration
44
+	 * @param string          $reg_status
45
+	 * @return EE_Registration
46 46
 	 * @throws OutOfRangeException
47 47
 	 * @throws EE_Error
48 48
 	 * @throws UnexpectedEntityException
49 49
 	 */
50
-    public function create(
51
-        EE_Event $event,
52
-        EE_Transaction $transaction,
53
-        EE_Ticket $ticket,
54
-        EE_Line_Item $ticket_line_item,
55
-        $reg_count,
56
-        $reg_group_size,
57
-        $reg_status = EEM_Registration::status_id_incomplete
58
-    ) {
59
-        $registrations = $transaction->registrations();
60
-        $reg_count = $reg_count ? $reg_count : count($registrations) + 1;
61
-        $reg_url_link = new RegUrlLink($reg_count, $ticket_line_item);
62
-        $reg_code = new RegCode($reg_url_link, $transaction, $ticket);
63
-        // generate new EE_Registration
64
-        $registration = EE_Registration::new_instance(
65
-            array(
66
-                'EVT_ID'          => $event->ID(),
67
-                'TXN_ID'          => $transaction->ID(),
68
-                'TKT_ID'          => $ticket->ID(),
69
-                'STS_ID'          => $reg_status,
70
-                'REG_final_price' => $this->resolveFinalPrice($transaction, $ticket, $ticket_line_item),
71
-                'REG_session'     => EE_Registry::instance()->SSN->id(),
72
-                'REG_count'       => $reg_count,
73
-                'REG_group_size'  => $reg_group_size ? $reg_group_size : $this->incrementRegCount($registrations),
74
-                'REG_url_link'    => $reg_url_link,
75
-                'REG_code'        => $reg_code,
76
-            )
77
-        );
78
-        if ( ! $registration instanceof EE_Registration) {
79
-            throw new UnexpectedEntityException($registration, 'EE_Registration');
80
-        }
81
-        // save registration so that we have an ID
82
-        $registration->save();
83
-        // track reservation on reg but don't adjust ticket and datetime reserved counts
84
-        // because that is done as soon as the tickets are added/removed from the cart
85
-        $registration->reserve_ticket();
86
-        $registration->_add_relation_to($event, 'Event', array(), $event->ID());
87
-        $registration->_add_relation_to($ticket, 'Ticket', array(), $ticket->ID());
88
-        $transaction->_add_relation_to($registration, 'Registration', array(), $registration->ID());
89
-        $registration->save();
90
-        return $registration;
91
-    }
50
+	public function create(
51
+		EE_Event $event,
52
+		EE_Transaction $transaction,
53
+		EE_Ticket $ticket,
54
+		EE_Line_Item $ticket_line_item,
55
+		$reg_count,
56
+		$reg_group_size,
57
+		$reg_status = EEM_Registration::status_id_incomplete
58
+	) {
59
+		$registrations = $transaction->registrations();
60
+		$reg_count = $reg_count ? $reg_count : count($registrations) + 1;
61
+		$reg_url_link = new RegUrlLink($reg_count, $ticket_line_item);
62
+		$reg_code = new RegCode($reg_url_link, $transaction, $ticket);
63
+		// generate new EE_Registration
64
+		$registration = EE_Registration::new_instance(
65
+			array(
66
+				'EVT_ID'          => $event->ID(),
67
+				'TXN_ID'          => $transaction->ID(),
68
+				'TKT_ID'          => $ticket->ID(),
69
+				'STS_ID'          => $reg_status,
70
+				'REG_final_price' => $this->resolveFinalPrice($transaction, $ticket, $ticket_line_item),
71
+				'REG_session'     => EE_Registry::instance()->SSN->id(),
72
+				'REG_count'       => $reg_count,
73
+				'REG_group_size'  => $reg_group_size ? $reg_group_size : $this->incrementRegCount($registrations),
74
+				'REG_url_link'    => $reg_url_link,
75
+				'REG_code'        => $reg_code,
76
+			)
77
+		);
78
+		if ( ! $registration instanceof EE_Registration) {
79
+			throw new UnexpectedEntityException($registration, 'EE_Registration');
80
+		}
81
+		// save registration so that we have an ID
82
+		$registration->save();
83
+		// track reservation on reg but don't adjust ticket and datetime reserved counts
84
+		// because that is done as soon as the tickets are added/removed from the cart
85
+		$registration->reserve_ticket();
86
+		$registration->_add_relation_to($event, 'Event', array(), $event->ID());
87
+		$registration->_add_relation_to($ticket, 'Ticket', array(), $ticket->ID());
88
+		$transaction->_add_relation_to($registration, 'Registration', array(), $registration->ID());
89
+		$registration->save();
90
+		return $registration;
91
+	}
92 92
 
93 93
 
94 94
 
@@ -100,40 +100,40 @@  discard block
 block discarded – undo
100 100
 	 * @throws EE_Error
101 101
 	 * @throws OutOfRangeException
102 102
 	 */
103
-    protected function resolveFinalPrice(
104
-        EE_Transaction $transaction,
105
-        EE_Ticket $ticket,
106
-        EE_Line_Item $ticket_line_item
107
-    ) {
108
-        $final_price = EEH_Line_Item::calculate_final_price_for_ticket_line_item(
109
-            $transaction->total_line_item(),
110
-            $ticket_line_item
111
-        );
112
-        $final_price = $final_price !== null ? $final_price : $ticket->get_ticket_total_with_taxes();
113
-        return (float)$final_price;
114
-    }
103
+	protected function resolveFinalPrice(
104
+		EE_Transaction $transaction,
105
+		EE_Ticket $ticket,
106
+		EE_Line_Item $ticket_line_item
107
+	) {
108
+		$final_price = EEH_Line_Item::calculate_final_price_for_ticket_line_item(
109
+			$transaction->total_line_item(),
110
+			$ticket_line_item
111
+		);
112
+		$final_price = $final_price !== null ? $final_price : $ticket->get_ticket_total_with_taxes();
113
+		return (float)$final_price;
114
+	}
115 115
 
116 116
 
117 117
 
118
-    /**
119
-     * @param  EE_Registration[] $registrations
120
-     * @param  boolean            $update_existing_registrations
121
-     * @return int
122
-     * @throws EE_Error
123
-     */
124
-    protected function incrementRegCount(array $registrations, $update_existing_registrations = true)
125
-    {
126
-        $new_reg_count = count($registrations) + 1;
127
-        if ($update_existing_registrations) {
128
-            foreach ($registrations as $registration) {
129
-                if ($registration instanceof EE_Registration) {
130
-                    $registration->set_count($new_reg_count);
131
-                    $registration->save();
132
-                }
133
-            }
134
-        }
135
-        return $new_reg_count;
136
-    }
118
+	/**
119
+	 * @param  EE_Registration[] $registrations
120
+	 * @param  boolean            $update_existing_registrations
121
+	 * @return int
122
+	 * @throws EE_Error
123
+	 */
124
+	protected function incrementRegCount(array $registrations, $update_existing_registrations = true)
125
+	{
126
+		$new_reg_count = count($registrations) + 1;
127
+		if ($update_existing_registrations) {
128
+			foreach ($registrations as $registration) {
129
+				if ($registration instanceof EE_Registration) {
130
+					$registration->set_count($new_reg_count);
131
+					$registration->save();
132
+				}
133
+			}
134
+		}
135
+		return $new_reg_count;
136
+	}
137 137
 
138 138
 
139 139
 }
Please login to merge, or discard this patch.
core/domain/services/ticket/CreateTicketLineItemService.php 2 patches
Indentation   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -5,7 +5,7 @@  discard block
 block discarded – undo
5 5
 use EventEspresso\core\exceptions\UnexpectedEntityException;
6 6
 
7 7
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
8
-    exit('No direct script access allowed');
8
+	exit('No direct script access allowed');
9 9
 }
10 10
 
11 11
 
@@ -21,44 +21,44 @@  discard block
 block discarded – undo
21 21
 class CreateTicketLineItemService extends DomainService
22 22
 {
23 23
 
24
-    /**
25
-     * @param \EE_Transaction $transaction
26
-     * @param \EE_Ticket      $ticket
27
-     * @param int             $quantity
28
-     * @return \EE_Line_Item
29
-     * @throws \EE_Error
30
-     * @throws UnexpectedEntityException
31
-     */
32
-    public function create(
33
-        \EE_Transaction $transaction,
34
-        \EE_Ticket $ticket,
35
-        $quantity = 1
36
-    )
37
-    {
38
-        $total_line_item = $transaction->total_line_item();
39
-        if (! $total_line_item instanceof \EE_Line_Item) {
40
-            throw new UnexpectedEntityException($total_line_item, 'EE_Line_Item');
41
-        }
42
-        // create new line item for ticket
43
-        $ticket_line_item = \EEH_Line_Item::add_ticket_purchase(
44
-            $total_line_item,
45
-            $ticket,
46
-            $quantity
47
-        );
48
-        if ( ! $ticket_line_item instanceof \EE_Line_Item) {
49
-            throw new UnexpectedEntityException($ticket_line_item, 'EE_Line_Item');
50
-        }
51
-        $total_line_item->save_this_and_descendants_to_txn($transaction->ID());
52
-        // apply any applicable promotions that were initially used during registration to new line items
53
-        do_action(
54
-            'AHEE__\EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler__handle__new_ticket_line_item_added',
55
-            $total_line_item,
56
-            $ticket,
57
-            $transaction,
58
-            $quantity
59
-        );
60
-        return $ticket_line_item;
61
-    }
24
+	/**
25
+	 * @param \EE_Transaction $transaction
26
+	 * @param \EE_Ticket      $ticket
27
+	 * @param int             $quantity
28
+	 * @return \EE_Line_Item
29
+	 * @throws \EE_Error
30
+	 * @throws UnexpectedEntityException
31
+	 */
32
+	public function create(
33
+		\EE_Transaction $transaction,
34
+		\EE_Ticket $ticket,
35
+		$quantity = 1
36
+	)
37
+	{
38
+		$total_line_item = $transaction->total_line_item();
39
+		if (! $total_line_item instanceof \EE_Line_Item) {
40
+			throw new UnexpectedEntityException($total_line_item, 'EE_Line_Item');
41
+		}
42
+		// create new line item for ticket
43
+		$ticket_line_item = \EEH_Line_Item::add_ticket_purchase(
44
+			$total_line_item,
45
+			$ticket,
46
+			$quantity
47
+		);
48
+		if ( ! $ticket_line_item instanceof \EE_Line_Item) {
49
+			throw new UnexpectedEntityException($ticket_line_item, 'EE_Line_Item');
50
+		}
51
+		$total_line_item->save_this_and_descendants_to_txn($transaction->ID());
52
+		// apply any applicable promotions that were initially used during registration to new line items
53
+		do_action(
54
+			'AHEE__\EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler__handle__new_ticket_line_item_added',
55
+			$total_line_item,
56
+			$ticket,
57
+			$transaction,
58
+			$quantity
59
+		);
60
+		return $ticket_line_item;
61
+	}
62 62
 
63 63
 
64 64
 
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -36,7 +36,7 @@
 block discarded – undo
36 36
     )
37 37
     {
38 38
         $total_line_item = $transaction->total_line_item();
39
-        if (! $total_line_item instanceof \EE_Line_Item) {
39
+        if ( ! $total_line_item instanceof \EE_Line_Item) {
40 40
             throw new UnexpectedEntityException($total_line_item, 'EE_Line_Item');
41 41
         }
42 42
         // create new line item for ticket
Please login to merge, or discard this patch.
core/services/commands/registration/CreateRegistrationCommandHandler.php 1 patch
Indentation   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -7,7 +7,7 @@  discard block
 block discarded – undo
7 7
 use EventEspresso\core\services\commands\CommandInterface;
8 8
 
9 9
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
10
-    exit('No direct script access allowed');
10
+	exit('No direct script access allowed');
11 11
 }
12 12
 
13 13
 
@@ -23,50 +23,50 @@  discard block
 block discarded – undo
23 23
 class CreateRegistrationCommandHandler extends CommandHandler
24 24
 {
25 25
 
26
-    /**
27
-     * @var CreateRegistrationService $registration_service
28
-     */
29
-    private $registration_service;
26
+	/**
27
+	 * @var CreateRegistrationService $registration_service
28
+	 */
29
+	private $registration_service;
30 30
 
31 31
 
32 32
 
33
-    /**
34
-     * Command constructor
35
-     *
36
-     * @param CreateRegistrationService $registration_service
37
-     */
38
-    public function __construct(CreateRegistrationService $registration_service)
39
-    {
40
-        $this->registration_service = $registration_service;
41
-    }
33
+	/**
34
+	 * Command constructor
35
+	 *
36
+	 * @param CreateRegistrationService $registration_service
37
+	 */
38
+	public function __construct(CreateRegistrationService $registration_service)
39
+	{
40
+		$this->registration_service = $registration_service;
41
+	}
42 42
 
43 43
 
44 44
 
45
-    /**
46
-     * @param  CommandInterface $command
47
-     * @return mixed
48
-     * @throws \OutOfRangeException
49
-     * @throws \EventEspresso\core\exceptions\UnexpectedEntityException
50
-     * @throws \EE_Error
51
-     * @throws \EventEspresso\core\exceptions\InvalidEntityException
52
-     */
53
-    public function handle(CommandInterface $command)
54
-    {
55
-        /** @var CreateRegistrationCommand $command */
56
-        if ( ! $command instanceof CreateRegistrationCommand) {
57
-            throw new InvalidEntityException(get_class($command), 'CreateRegistrationCommand');
58
-        }
59
-        // now create a new registration for the ticket
60
-        return $this->registration_service->create(
61
-            $command->ticket()->get_related_event(),
62
-            $command->transaction(),
63
-            $command->ticket(),
64
-            $command->ticketLineItem(),
65
-            $command->regCount(),
66
-            $command->regGroupSize(),
67
-            $command->regStatus()
68
-        );
69
-    }
45
+	/**
46
+	 * @param  CommandInterface $command
47
+	 * @return mixed
48
+	 * @throws \OutOfRangeException
49
+	 * @throws \EventEspresso\core\exceptions\UnexpectedEntityException
50
+	 * @throws \EE_Error
51
+	 * @throws \EventEspresso\core\exceptions\InvalidEntityException
52
+	 */
53
+	public function handle(CommandInterface $command)
54
+	{
55
+		/** @var CreateRegistrationCommand $command */
56
+		if ( ! $command instanceof CreateRegistrationCommand) {
57
+			throw new InvalidEntityException(get_class($command), 'CreateRegistrationCommand');
58
+		}
59
+		// now create a new registration for the ticket
60
+		return $this->registration_service->create(
61
+			$command->ticket()->get_related_event(),
62
+			$command->transaction(),
63
+			$command->ticket(),
64
+			$command->ticketLineItem(),
65
+			$command->regCount(),
66
+			$command->regGroupSize(),
67
+			$command->regStatus()
68
+		);
69
+	}
70 70
 
71 71
 
72 72
 
Please login to merge, or discard this patch.
modules/single_page_checkout/inc/EE_SPCO_Reg_Step.class.php 2 patches
Indentation   +632 added lines, -632 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if (! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -16,672 +16,672 @@  discard block
 block discarded – undo
16 16
 abstract class EE_SPCO_Reg_Step
17 17
 {
18 18
 
19
-    /**
20
-     *    $_completed - TRUE if this step has fully completed it's duties
21
-     *
22
-     * @access protected
23
-     * @type bool $_completed
24
-     */
25
-    protected $_completed = false;
26
-
27
-    /**
28
-     *    $_is_current_step - TRUE if this is the current step
29
-     *
30
-     * @access protected
31
-     * @type bool $_is_current_step
32
-     */
33
-    protected $_is_current_step = false;
34
-
35
-    /**
36
-     *    $_order - when the reg step should be run relative to other steps
37
-     *
38
-     * @access protected
39
-     * @type int $_template
40
-     */
41
-    protected $_order = 0;
42
-
43
-    /**
44
-     *    $_slug - URL param for this step
45
-     *
46
-     * @access protected
47
-     * @type string $_slug
48
-     */
49
-    protected $_slug;
50
-
51
-    /**
52
-     *    $_name - Step Name - translatable string
53
-     *
54
-     * @access protected
55
-     * @type string $_slug
56
-     */
57
-    protected $_name;
58
-
59
-    /**
60
-     *    $_submit_button_text - translatable string that appears on this step's submit button
61
-     *
62
-     * @access protected
63
-     * @type string $_slug
64
-     */
65
-    protected $_submit_button_text;
66
-
67
-    /**
68
-     *    $_template - template name
69
-     *
70
-     * @access protected
71
-     * @type string $_template
72
-     */
73
-    protected $_template;
74
-
75
-    /**
76
-     *    $_reg_form_name - the form input name and id attribute
77
-     *
78
-     * @access protected
79
-     * @var string $_reg_form_name
80
-     */
81
-    protected $_reg_form_name;
82
-
83
-    /**
84
-     *    $_success_message - text to display upon successful form submission
85
-     *
86
-     * @access private
87
-     * @var string $_success_message
88
-     */
89
-    protected $_success_message;
90
-
91
-    /**
92
-     *    $_instructions - a brief description of how to complete the reg step.
93
-     *    Usually displayed in conjunction with the previous step's success message.
94
-     *
95
-     * @access private
96
-     * @var string $_instructions
97
-     */
98
-    protected $_instructions;
99
-
100
-    /**
101
-     *    $_valid_data - the normalized and validated data for this step
102
-     *
103
-     * @access public
104
-     * @var array $_valid_data
105
-     */
106
-    protected $_valid_data = array();
107
-
108
-    /**
109
-     *    $reg_form - the registration form for this step
110
-     *
111
-     * @access public
112
-     * @var EE_Form_Section_Proper $reg_form
113
-     */
114
-    public $reg_form;
115
-
116
-    /**
117
-     *    $checkout - EE_Checkout object for handling the properties of the current checkout process
118
-     *
119
-     * @access public
120
-     * @var EE_Checkout $checkout
121
-     */
122
-    public $checkout;
123
-
124
-
125
-
126
-    /**
127
-     * @return void
128
-     */
129
-    abstract public function translate_js_strings();
130
-
131
-
19
+	/**
20
+	 *    $_completed - TRUE if this step has fully completed it's duties
21
+	 *
22
+	 * @access protected
23
+	 * @type bool $_completed
24
+	 */
25
+	protected $_completed = false;
26
+
27
+	/**
28
+	 *    $_is_current_step - TRUE if this is the current step
29
+	 *
30
+	 * @access protected
31
+	 * @type bool $_is_current_step
32
+	 */
33
+	protected $_is_current_step = false;
34
+
35
+	/**
36
+	 *    $_order - when the reg step should be run relative to other steps
37
+	 *
38
+	 * @access protected
39
+	 * @type int $_template
40
+	 */
41
+	protected $_order = 0;
42
+
43
+	/**
44
+	 *    $_slug - URL param for this step
45
+	 *
46
+	 * @access protected
47
+	 * @type string $_slug
48
+	 */
49
+	protected $_slug;
50
+
51
+	/**
52
+	 *    $_name - Step Name - translatable string
53
+	 *
54
+	 * @access protected
55
+	 * @type string $_slug
56
+	 */
57
+	protected $_name;
58
+
59
+	/**
60
+	 *    $_submit_button_text - translatable string that appears on this step's submit button
61
+	 *
62
+	 * @access protected
63
+	 * @type string $_slug
64
+	 */
65
+	protected $_submit_button_text;
66
+
67
+	/**
68
+	 *    $_template - template name
69
+	 *
70
+	 * @access protected
71
+	 * @type string $_template
72
+	 */
73
+	protected $_template;
74
+
75
+	/**
76
+	 *    $_reg_form_name - the form input name and id attribute
77
+	 *
78
+	 * @access protected
79
+	 * @var string $_reg_form_name
80
+	 */
81
+	protected $_reg_form_name;
82
+
83
+	/**
84
+	 *    $_success_message - text to display upon successful form submission
85
+	 *
86
+	 * @access private
87
+	 * @var string $_success_message
88
+	 */
89
+	protected $_success_message;
90
+
91
+	/**
92
+	 *    $_instructions - a brief description of how to complete the reg step.
93
+	 *    Usually displayed in conjunction with the previous step's success message.
94
+	 *
95
+	 * @access private
96
+	 * @var string $_instructions
97
+	 */
98
+	protected $_instructions;
99
+
100
+	/**
101
+	 *    $_valid_data - the normalized and validated data for this step
102
+	 *
103
+	 * @access public
104
+	 * @var array $_valid_data
105
+	 */
106
+	protected $_valid_data = array();
107
+
108
+	/**
109
+	 *    $reg_form - the registration form for this step
110
+	 *
111
+	 * @access public
112
+	 * @var EE_Form_Section_Proper $reg_form
113
+	 */
114
+	public $reg_form;
115
+
116
+	/**
117
+	 *    $checkout - EE_Checkout object for handling the properties of the current checkout process
118
+	 *
119
+	 * @access public
120
+	 * @var EE_Checkout $checkout
121
+	 */
122
+	public $checkout;
123
+
124
+
125
+
126
+	/**
127
+	 * @return void
128
+	 */
129
+	abstract public function translate_js_strings();
130
+
131
+
132 132
 
133
-    /**
134
-     * @return void
135
-     */
136
-    abstract public function enqueue_styles_and_scripts();
137
-
138
-
139
-
140
-    /**
141
-     * @return boolean
142
-     */
143
-    abstract public function initialize_reg_step();
144
-
145
-
146
-
147
-    /**
148
-     * @return string
149
-     */
150
-    abstract public function generate_reg_form();
151
-
152
-
153
-
154
-    /**
155
-     * @return boolean
156
-     */
157
-    abstract public function process_reg_step();
158
-
159
-
160
-
161
-    /**
162
-     * @return boolean
163
-     */
164
-    abstract public function update_reg_step();
165
-
166
-
167
-
168
-    /**
169
-     * @return boolean
170
-     */
171
-    public function completed()
172
-    {
173
-        return $this->_completed;
174
-    }
133
+	/**
134
+	 * @return void
135
+	 */
136
+	abstract public function enqueue_styles_and_scripts();
137
+
138
+
139
+
140
+	/**
141
+	 * @return boolean
142
+	 */
143
+	abstract public function initialize_reg_step();
144
+
145
+
146
+
147
+	/**
148
+	 * @return string
149
+	 */
150
+	abstract public function generate_reg_form();
151
+
152
+
153
+
154
+	/**
155
+	 * @return boolean
156
+	 */
157
+	abstract public function process_reg_step();
158
+
159
+
160
+
161
+	/**
162
+	 * @return boolean
163
+	 */
164
+	abstract public function update_reg_step();
165
+
166
+
167
+
168
+	/**
169
+	 * @return boolean
170
+	 */
171
+	public function completed()
172
+	{
173
+		return $this->_completed;
174
+	}
175 175
 
176 176
 
177 177
 
178
-    /**
179
-     * set_completed - toggles $_completed to TRUE
180
-     */
181
-    public function set_completed()
182
-    {
183
-        // DEBUG LOG
184
-        //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
185
-        $this->_completed = apply_filters('FHEE__EE_SPCO_Reg_Step__set_completed___completed', true, $this);
186
-    }
178
+	/**
179
+	 * set_completed - toggles $_completed to TRUE
180
+	 */
181
+	public function set_completed()
182
+	{
183
+		// DEBUG LOG
184
+		//$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
185
+		$this->_completed = apply_filters('FHEE__EE_SPCO_Reg_Step__set_completed___completed', true, $this);
186
+	}
187 187
 
188 188
 
189 189
 
190
-    /**
191
-     * set_completed - toggles $_completed to FALSE
192
-     */
193
-    public function set_not_completed()
194
-    {
195
-        $this->_completed = false;
196
-    }
190
+	/**
191
+	 * set_completed - toggles $_completed to FALSE
192
+	 */
193
+	public function set_not_completed()
194
+	{
195
+		$this->_completed = false;
196
+	}
197 197
 
198 198
 
199 199
 
200
-    /**
201
-     * @return string
202
-     */
203
-    public function name()
204
-    {
205
-        return $this->_name;
206
-    }
200
+	/**
201
+	 * @return string
202
+	 */
203
+	public function name()
204
+	{
205
+		return $this->_name;
206
+	}
207 207
 
208 208
 
209 209
 
210
-    /**
211
-     * @return string
212
-     */
213
-    public function slug()
214
-    {
215
-        return $this->_slug;
216
-    }
210
+	/**
211
+	 * @return string
212
+	 */
213
+	public function slug()
214
+	{
215
+		return $this->_slug;
216
+	}
217 217
 
218 218
 
219 219
 
220
-    /**
221
-     * submit_button_text
222
-     * the text that appears on the reg step form submit button
223
-     *
224
-     * @return string
225
-     */
226
-    public function submit_button_text()
227
-    {
228
-        return $this->_submit_button_text;
229
-    }
220
+	/**
221
+	 * submit_button_text
222
+	 * the text that appears on the reg step form submit button
223
+	 *
224
+	 * @return string
225
+	 */
226
+	public function submit_button_text()
227
+	{
228
+		return $this->_submit_button_text;
229
+	}
230 230
 
231 231
 
232 232
 
233
-    /**
234
-     * set_submit_button_text
235
-     * sets the text that appears on the reg step form submit button
236
-     *
237
-     * @param string $submit_button_text
238
-     */
239
-    public function set_submit_button_text($submit_button_text = '')
240
-    {
241
-        if (! empty($submit_button_text)) {
242
-            $this->_submit_button_text = $submit_button_text;
243
-        } else if ($this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
244
-            if ($this->checkout->revisit) {
245
-                $this->_submit_button_text = sprintf(
246
-                    __('Update %s', 'event_espresso'),
247
-                    $this->checkout->current_step->name()
248
-                );
249
-            } else {
250
-                $this->_submit_button_text = sprintf(
251
-                    __('Proceed to %s', 'event_espresso'),
252
-                    $this->checkout->next_step->name()
253
-                );
254
-            }
255
-        }
256
-        // filters the submit button text
257
-        $this->_submit_button_text = apply_filters(
258
-            'FHEE__EE_SPCO_Reg_Step__set_submit_button_text___submit_button_text',
259
-            $this->_submit_button_text,
260
-            $this->checkout
261
-        );
262
-    }
233
+	/**
234
+	 * set_submit_button_text
235
+	 * sets the text that appears on the reg step form submit button
236
+	 *
237
+	 * @param string $submit_button_text
238
+	 */
239
+	public function set_submit_button_text($submit_button_text = '')
240
+	{
241
+		if (! empty($submit_button_text)) {
242
+			$this->_submit_button_text = $submit_button_text;
243
+		} else if ($this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
244
+			if ($this->checkout->revisit) {
245
+				$this->_submit_button_text = sprintf(
246
+					__('Update %s', 'event_espresso'),
247
+					$this->checkout->current_step->name()
248
+				);
249
+			} else {
250
+				$this->_submit_button_text = sprintf(
251
+					__('Proceed to %s', 'event_espresso'),
252
+					$this->checkout->next_step->name()
253
+				);
254
+			}
255
+		}
256
+		// filters the submit button text
257
+		$this->_submit_button_text = apply_filters(
258
+			'FHEE__EE_SPCO_Reg_Step__set_submit_button_text___submit_button_text',
259
+			$this->_submit_button_text,
260
+			$this->checkout
261
+		);
262
+	}
263 263
 
264 264
 
265 265
 
266
-    /**
267
-     * @param boolean $is_current_step
268
-     */
269
-    public function set_is_current_step($is_current_step)
270
-    {
271
-        $this->_is_current_step = $is_current_step;
272
-    }
266
+	/**
267
+	 * @param boolean $is_current_step
268
+	 */
269
+	public function set_is_current_step($is_current_step)
270
+	{
271
+		$this->_is_current_step = $is_current_step;
272
+	}
273 273
 
274 274
 
275 275
 
276
-    /**
277
-     * @return boolean
278
-     */
279
-    public function is_current_step()
280
-    {
281
-        return $this->_is_current_step;
282
-    }
276
+	/**
277
+	 * @return boolean
278
+	 */
279
+	public function is_current_step()
280
+	{
281
+		return $this->_is_current_step;
282
+	}
283 283
 
284 284
 
285 285
 
286
-    /**
287
-     * @return boolean
288
-     */
289
-    public function is_final_step()
290
-    {
291
-        return $this instanceof EE_SPCO_Reg_Step_Finalize_Registration ? true : false;
292
-    }
286
+	/**
287
+	 * @return boolean
288
+	 */
289
+	public function is_final_step()
290
+	{
291
+		return $this instanceof EE_SPCO_Reg_Step_Finalize_Registration ? true : false;
292
+	}
293 293
 
294 294
 
295 295
 
296
-    /**
297
-     * @param int $order
298
-     */
299
-    public function set_order($order)
300
-    {
301
-        $this->_order = $order;
302
-    }
303
-
304
-
296
+	/**
297
+	 * @param int $order
298
+	 */
299
+	public function set_order($order)
300
+	{
301
+		$this->_order = $order;
302
+	}
303
+
304
+
305 305
 
306
-    /**
307
-     * @return int
308
-     */
309
-    public function order()
310
-    {
311
-        return $this->_order;
312
-    }
313
-
314
-
315
-
316
-    /**
317
-     * @return string
318
-     */
319
-    public function template()
320
-    {
321
-        return $this->_template;
322
-    }
323
-
324
-
325
-
326
-    /**
327
-     * @return string
328
-     */
329
-    public function success_message()
330
-    {
331
-        return $this->_success_message;
332
-    }
333
-
334
-
335
-
336
-    /**
337
-     * _set_success_message
338
-     *
339
-     * @param string $success_message
340
-     */
341
-    protected function _set_success_message($success_message)
342
-    {
343
-        $this->_success_message = $success_message;
344
-    }
345
-
346
-
347
-
348
-    /**
349
-     * _reset_success_message
350
-     *
351
-     * @return void
352
-     */
353
-    protected function _reset_success_message()
354
-    {
355
-        $this->_success_message = '';
356
-    }
306
+	/**
307
+	 * @return int
308
+	 */
309
+	public function order()
310
+	{
311
+		return $this->_order;
312
+	}
313
+
314
+
315
+
316
+	/**
317
+	 * @return string
318
+	 */
319
+	public function template()
320
+	{
321
+		return $this->_template;
322
+	}
323
+
324
+
325
+
326
+	/**
327
+	 * @return string
328
+	 */
329
+	public function success_message()
330
+	{
331
+		return $this->_success_message;
332
+	}
333
+
334
+
335
+
336
+	/**
337
+	 * _set_success_message
338
+	 *
339
+	 * @param string $success_message
340
+	 */
341
+	protected function _set_success_message($success_message)
342
+	{
343
+		$this->_success_message = $success_message;
344
+	}
345
+
346
+
347
+
348
+	/**
349
+	 * _reset_success_message
350
+	 *
351
+	 * @return void
352
+	 */
353
+	protected function _reset_success_message()
354
+	{
355
+		$this->_success_message = '';
356
+	}
357 357
 
358 358
 
359 359
 
360
-    /**
361
-     * @return string
362
-     */
363
-    public function _instructions()
364
-    {
365
-        return $this->_instructions;
366
-    }
367
-
368
-
369
-
370
-    /**
371
-     * @param string $instructions
372
-     */
373
-    public function set_instructions($instructions)
374
-    {
375
-        $this->_instructions = apply_filters(
376
-            'FHEE__EE_SPCO_Reg_Step__set_instructions__instructions',
377
-            $instructions,
378
-            $this
379
-        );
380
-    }
381
-
382
-
383
-
384
-    /**
385
-     * @param array $valid_data
386
-     */
387
-    public function set_valid_data($valid_data)
388
-    {
389
-        $this->_valid_data = $valid_data;
390
-    }
391
-
392
-
393
-
394
-    /**
395
-     * @return array
396
-     */
397
-    public function valid_data()
398
-    {
399
-        if (empty($this->_valid_data)) {
400
-            $this->_valid_data = $this->reg_form->valid_data();
401
-        }
402
-        return $this->_valid_data;
403
-    }
404
-
405
-
406
-
407
-    /**
408
-     * @return string
409
-     */
410
-    public function reg_form_name()
411
-    {
412
-        if (empty($this->_reg_form_name)) {
413
-            $this->set_reg_form_name('ee-spco-' . $this->slug() . '-reg-step-form');
414
-        }
415
-        return $this->_reg_form_name;
416
-    }
417
-
418
-
419
-
420
-    /**
421
-     * @param string $reg_form_name
422
-     */
423
-    protected function set_reg_form_name($reg_form_name)
424
-    {
425
-        $this->_reg_form_name = $reg_form_name;
426
-    }
427
-
428
-
429
-
430
-    /**
431
-     * reg_step_url
432
-     *
433
-     * @param string $action
434
-     * @return string
435
-     */
436
-    public function reg_step_url($action = '')
437
-    {
438
-        $query_args = array('step' => $this->slug());
439
-        if (! empty($action)) {
440
-            $query_args['action'] = $action;
441
-        }
442
-        // final step has no display
443
-        if ($this instanceof EE_SPCO_Reg_Step_Finalize_Registration && $action === 'display_spco_reg_step') {
444
-            $query_args['action'] = 'process_reg_step';
445
-        }
446
-        if ($this->checkout->revisit) {
447
-            $query_args['revisit'] = true;
448
-        }
449
-        if ($this->checkout->reg_url_link) {
450
-            $query_args['e_reg_url_link'] = $this->checkout->reg_url_link;
451
-        }
452
-        return add_query_arg($query_args, $this->checkout->reg_page_base_url);
453
-    }
454
-
455
-
456
-
457
-    /**
458
-     * creates the default hidden inputs section
459
-     *
460
-     * @return EE_Form_Section_Proper
461
-     * @throws \EE_Error
462
-     */
463
-    public function reg_step_hidden_inputs()
464
-    {
465
-        // hidden inputs for admin registrations
466
-        if ($this->checkout->admin_request) {
467
-            return new EE_Form_Section_Proper(
468
-                array(
469
-                    'layout_strategy' => new EE_Div_Per_Section_Layout(),
470
-                    'html_id'         => 'ee-' . $this->slug() . '-hidden-inputs',
471
-                    'subsections'     => array(
472
-                        'next_step' => new EE_Fixed_Hidden_Input(
473
-                            array(
474
-                                'html_name' => 'next_step',
475
-                                'html_id'   => 'spco-' . $this->slug() . '-next-step',
476
-                                'default'   => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
477
-                                    ? $this->checkout->next_step->slug()
478
-                                    : '',
479
-                            )
480
-                        ),
481
-                    ),
482
-                )
483
-            );
484
-        } else {
485
-            $default_form_action = apply_filters(
486
-                'FHEE__EE_SPCO_Reg_Step__reg_step_hidden_inputs__default_form_action',
487
-                empty($this->checkout->reg_url_link)
488
-                    ? 'process_reg_step'
489
-                    : 'update_reg_step',
490
-                $this
491
-            );
492
-            // hidden inputs for frontend registrations
493
-            return new EE_Form_Section_Proper(
494
-                array(
495
-                    'layout_strategy' => new EE_Div_Per_Section_Layout(),
496
-                    'html_id'         => 'ee-' . $this->slug() . '-hidden-inputs',
497
-                    'subsections'     => array(
498
-                        'action'         => new EE_Fixed_Hidden_Input(
499
-                            array(
500
-                                'html_name' => 'action',
501
-                                'html_id'   => 'spco-' . $this->slug() . '-action',
502
-                                'default'   => $default_form_action,
503
-                            )
504
-                        ),
505
-                        'next_step'      => new EE_Fixed_Hidden_Input(
506
-                            array(
507
-                                'html_name' => 'next_step',
508
-                                'html_id'   => 'spco-' . $this->slug() . '-next-step',
509
-                                'default'   => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
510
-                                    ? $this->checkout->next_step->slug()
511
-                                    : '',
512
-                            )
513
-                        ),
514
-                        'e_reg_url_link' => new EE_Fixed_Hidden_Input(
515
-                            array(
516
-                                'html_name' => 'e_reg_url_link',
517
-                                'html_id'   => 'spco-reg_url_link',
518
-                                'default'   => $this->checkout->reg_url_link,
519
-                            )
520
-                        ),
521
-                        'revisit'        => new EE_Fixed_Hidden_Input(
522
-                            array(
523
-                                'html_name' => 'revisit',
524
-                                'html_id'   => 'spco-revisit',
525
-                                'default'   => $this->checkout->revisit,
526
-                            )
527
-                        ),
528
-                    ),
529
-                )
530
-            );
531
-        }
532
-    }
533
-
534
-
535
-
536
-    /**
537
-     * generate_reg_form_for_actions
538
-     *
539
-     * @param array $actions
540
-     * @return void
541
-     */
542
-    public function generate_reg_form_for_actions($actions = array())
543
-    {
544
-        $actions = array_merge(
545
-            array(
546
-                'generate_reg_form',
547
-                'display_spco_reg_step',
548
-                'process_reg_step',
549
-                'update_reg_step',
550
-            ),
551
-            $actions
552
-        );
553
-        $this->checkout->generate_reg_form = in_array($this->checkout->action, $actions, true) ? true : false;
554
-    }
555
-
556
-
557
-
558
-    /**
559
-     * @return string
560
-     * @throws \EE_Error
561
-     */
562
-    public function display_reg_form()
563
-    {
564
-        $html = '';
565
-        if ($this->reg_form instanceof EE_Form_Section_Proper) {
566
-            $html .= ! $this->checkout->admin_request ? $this->reg_form->form_open($this->reg_step_url()) : '';
567
-            if (EE_Registry::instance()->REQ->ajax) {
568
-                $this->reg_form->localize_validation_rules();
569
-                $this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
570
-            }
571
-            $html .= $this->reg_form->get_html();
572
-            $html .= ! $this->checkout->admin_request ? $this->reg_step_submit_button() : '';
573
-            $html .= ! $this->checkout->admin_request ? $this->reg_form->form_close() : '';
574
-        }
575
-        return $html;
576
-    }
577
-
578
-
579
-
580
-    /**
581
-     * div_class - returns nothing for current step, but a css class of "hidden" for others
582
-     *
583
-     * @return string
584
-     * @throws \EE_Error
585
-     */
586
-    public function reg_step_submit_button()
587
-    {
588
-        if (! $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
589
-            return '';
590
-        }
591
-        ob_start();
592
-        do_action(
593
-            'AHEE__before_spco_whats_next_buttons',
594
-            $this->slug(),
595
-            $this->checkout->next_step->slug(),
596
-            $this->checkout
597
-        );
598
-        $html = ob_get_clean();
599
-        // generate submit button
600
-        $sbmt_btn = new EE_Submit_Input(array(
601
-            'html_name'             => 'spco-go-to-step-' . $this->checkout->next_step->slug(),
602
-            'html_id'               => 'spco-go-to-step-' . $this->checkout->next_step->slug(),
603
-            'html_class'            => 'spco-next-step-btn',
604
-            'other_html_attributes' => ' rel="' . $this->slug() . '"',
605
-            'default'               => $this->submit_button_text(),
606
-        ));
607
-        $sbmt_btn->set_button_css_attributes(true, 'large');
608
-        $sbmt_btn_html = $sbmt_btn->get_html_for_input();
609
-        $html .= EEH_HTML::div(
610
-            apply_filters('FHEE__EE_SPCO_Reg_Step__reg_step_submit_button__sbmt_btn_html', $sbmt_btn_html, $this),
611
-            'spco-' . $this->slug() . '-whats-next-buttons-dv',
612
-            'spco-whats-next-buttons'
613
-        );
614
-        return $html;
615
-    }
616
-
617
-
618
-
619
-    /**
620
-     * div_class - returns nothing for current step, but a css class of "hidden" for others
621
-     *
622
-     * @return string
623
-     */
624
-    public function div_class()
625
-    {
626
-        return $this->is_current_step() ? '' : ' hidden';
627
-    }
628
-
629
-
630
-
631
-    /**
632
-     * div_class - returns  a css class of "hidden" for current step, but nothing for others
633
-     *
634
-     * @return string
635
-     */
636
-    public function edit_lnk_url()
637
-    {
638
-        return add_query_arg(array('step' => $this->slug()), $this->checkout->reg_page_base_url);
639
-    }
640
-
641
-
642
-
643
-    /**
644
-     * div_class - returns  a css class of "hidden" for current step, but nothing for others
645
-     *
646
-     * @return string
647
-     */
648
-    public function edit_link_class()
649
-    {
650
-        return $this->is_current_step() ? ' hidden' : '';
651
-    }
652
-
653
-
654
-
655
-    /**
656
-     * update_checkout with changes that have been made to the cart
657
-     *
658
-     * @return void
659
-     * @throws \EE_Error
660
-     */
661
-    public function update_checkout()
662
-    {
663
-        // grab the cart grand total and reset TXN total
664
-        $this->checkout->transaction->set_total($this->checkout->cart->get_cart_grand_total());
665
-        $this->checkout->stash_transaction_and_checkout();
666
-    }
667
-
668
-
669
-
670
-
671
-
672
-    /**
673
-     *    __sleep
674
-     * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon
675
-     * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the
676
-     * reg form, because if needed, it will be regenerated anyways
677
-     *
678
-     * @return array
679
-     */
680
-    public function __sleep()
681
-    {
682
-        // remove the reg form and the checkout
683
-        return array_diff(array_keys(get_object_vars($this)), array('reg_form', 'checkout'));
684
-    }
360
+	/**
361
+	 * @return string
362
+	 */
363
+	public function _instructions()
364
+	{
365
+		return $this->_instructions;
366
+	}
367
+
368
+
369
+
370
+	/**
371
+	 * @param string $instructions
372
+	 */
373
+	public function set_instructions($instructions)
374
+	{
375
+		$this->_instructions = apply_filters(
376
+			'FHEE__EE_SPCO_Reg_Step__set_instructions__instructions',
377
+			$instructions,
378
+			$this
379
+		);
380
+	}
381
+
382
+
383
+
384
+	/**
385
+	 * @param array $valid_data
386
+	 */
387
+	public function set_valid_data($valid_data)
388
+	{
389
+		$this->_valid_data = $valid_data;
390
+	}
391
+
392
+
393
+
394
+	/**
395
+	 * @return array
396
+	 */
397
+	public function valid_data()
398
+	{
399
+		if (empty($this->_valid_data)) {
400
+			$this->_valid_data = $this->reg_form->valid_data();
401
+		}
402
+		return $this->_valid_data;
403
+	}
404
+
405
+
406
+
407
+	/**
408
+	 * @return string
409
+	 */
410
+	public function reg_form_name()
411
+	{
412
+		if (empty($this->_reg_form_name)) {
413
+			$this->set_reg_form_name('ee-spco-' . $this->slug() . '-reg-step-form');
414
+		}
415
+		return $this->_reg_form_name;
416
+	}
417
+
418
+
419
+
420
+	/**
421
+	 * @param string $reg_form_name
422
+	 */
423
+	protected function set_reg_form_name($reg_form_name)
424
+	{
425
+		$this->_reg_form_name = $reg_form_name;
426
+	}
427
+
428
+
429
+
430
+	/**
431
+	 * reg_step_url
432
+	 *
433
+	 * @param string $action
434
+	 * @return string
435
+	 */
436
+	public function reg_step_url($action = '')
437
+	{
438
+		$query_args = array('step' => $this->slug());
439
+		if (! empty($action)) {
440
+			$query_args['action'] = $action;
441
+		}
442
+		// final step has no display
443
+		if ($this instanceof EE_SPCO_Reg_Step_Finalize_Registration && $action === 'display_spco_reg_step') {
444
+			$query_args['action'] = 'process_reg_step';
445
+		}
446
+		if ($this->checkout->revisit) {
447
+			$query_args['revisit'] = true;
448
+		}
449
+		if ($this->checkout->reg_url_link) {
450
+			$query_args['e_reg_url_link'] = $this->checkout->reg_url_link;
451
+		}
452
+		return add_query_arg($query_args, $this->checkout->reg_page_base_url);
453
+	}
454
+
455
+
456
+
457
+	/**
458
+	 * creates the default hidden inputs section
459
+	 *
460
+	 * @return EE_Form_Section_Proper
461
+	 * @throws \EE_Error
462
+	 */
463
+	public function reg_step_hidden_inputs()
464
+	{
465
+		// hidden inputs for admin registrations
466
+		if ($this->checkout->admin_request) {
467
+			return new EE_Form_Section_Proper(
468
+				array(
469
+					'layout_strategy' => new EE_Div_Per_Section_Layout(),
470
+					'html_id'         => 'ee-' . $this->slug() . '-hidden-inputs',
471
+					'subsections'     => array(
472
+						'next_step' => new EE_Fixed_Hidden_Input(
473
+							array(
474
+								'html_name' => 'next_step',
475
+								'html_id'   => 'spco-' . $this->slug() . '-next-step',
476
+								'default'   => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
477
+									? $this->checkout->next_step->slug()
478
+									: '',
479
+							)
480
+						),
481
+					),
482
+				)
483
+			);
484
+		} else {
485
+			$default_form_action = apply_filters(
486
+				'FHEE__EE_SPCO_Reg_Step__reg_step_hidden_inputs__default_form_action',
487
+				empty($this->checkout->reg_url_link)
488
+					? 'process_reg_step'
489
+					: 'update_reg_step',
490
+				$this
491
+			);
492
+			// hidden inputs for frontend registrations
493
+			return new EE_Form_Section_Proper(
494
+				array(
495
+					'layout_strategy' => new EE_Div_Per_Section_Layout(),
496
+					'html_id'         => 'ee-' . $this->slug() . '-hidden-inputs',
497
+					'subsections'     => array(
498
+						'action'         => new EE_Fixed_Hidden_Input(
499
+							array(
500
+								'html_name' => 'action',
501
+								'html_id'   => 'spco-' . $this->slug() . '-action',
502
+								'default'   => $default_form_action,
503
+							)
504
+						),
505
+						'next_step'      => new EE_Fixed_Hidden_Input(
506
+							array(
507
+								'html_name' => 'next_step',
508
+								'html_id'   => 'spco-' . $this->slug() . '-next-step',
509
+								'default'   => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
510
+									? $this->checkout->next_step->slug()
511
+									: '',
512
+							)
513
+						),
514
+						'e_reg_url_link' => new EE_Fixed_Hidden_Input(
515
+							array(
516
+								'html_name' => 'e_reg_url_link',
517
+								'html_id'   => 'spco-reg_url_link',
518
+								'default'   => $this->checkout->reg_url_link,
519
+							)
520
+						),
521
+						'revisit'        => new EE_Fixed_Hidden_Input(
522
+							array(
523
+								'html_name' => 'revisit',
524
+								'html_id'   => 'spco-revisit',
525
+								'default'   => $this->checkout->revisit,
526
+							)
527
+						),
528
+					),
529
+				)
530
+			);
531
+		}
532
+	}
533
+
534
+
535
+
536
+	/**
537
+	 * generate_reg_form_for_actions
538
+	 *
539
+	 * @param array $actions
540
+	 * @return void
541
+	 */
542
+	public function generate_reg_form_for_actions($actions = array())
543
+	{
544
+		$actions = array_merge(
545
+			array(
546
+				'generate_reg_form',
547
+				'display_spco_reg_step',
548
+				'process_reg_step',
549
+				'update_reg_step',
550
+			),
551
+			$actions
552
+		);
553
+		$this->checkout->generate_reg_form = in_array($this->checkout->action, $actions, true) ? true : false;
554
+	}
555
+
556
+
557
+
558
+	/**
559
+	 * @return string
560
+	 * @throws \EE_Error
561
+	 */
562
+	public function display_reg_form()
563
+	{
564
+		$html = '';
565
+		if ($this->reg_form instanceof EE_Form_Section_Proper) {
566
+			$html .= ! $this->checkout->admin_request ? $this->reg_form->form_open($this->reg_step_url()) : '';
567
+			if (EE_Registry::instance()->REQ->ajax) {
568
+				$this->reg_form->localize_validation_rules();
569
+				$this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
570
+			}
571
+			$html .= $this->reg_form->get_html();
572
+			$html .= ! $this->checkout->admin_request ? $this->reg_step_submit_button() : '';
573
+			$html .= ! $this->checkout->admin_request ? $this->reg_form->form_close() : '';
574
+		}
575
+		return $html;
576
+	}
577
+
578
+
579
+
580
+	/**
581
+	 * div_class - returns nothing for current step, but a css class of "hidden" for others
582
+	 *
583
+	 * @return string
584
+	 * @throws \EE_Error
585
+	 */
586
+	public function reg_step_submit_button()
587
+	{
588
+		if (! $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
589
+			return '';
590
+		}
591
+		ob_start();
592
+		do_action(
593
+			'AHEE__before_spco_whats_next_buttons',
594
+			$this->slug(),
595
+			$this->checkout->next_step->slug(),
596
+			$this->checkout
597
+		);
598
+		$html = ob_get_clean();
599
+		// generate submit button
600
+		$sbmt_btn = new EE_Submit_Input(array(
601
+			'html_name'             => 'spco-go-to-step-' . $this->checkout->next_step->slug(),
602
+			'html_id'               => 'spco-go-to-step-' . $this->checkout->next_step->slug(),
603
+			'html_class'            => 'spco-next-step-btn',
604
+			'other_html_attributes' => ' rel="' . $this->slug() . '"',
605
+			'default'               => $this->submit_button_text(),
606
+		));
607
+		$sbmt_btn->set_button_css_attributes(true, 'large');
608
+		$sbmt_btn_html = $sbmt_btn->get_html_for_input();
609
+		$html .= EEH_HTML::div(
610
+			apply_filters('FHEE__EE_SPCO_Reg_Step__reg_step_submit_button__sbmt_btn_html', $sbmt_btn_html, $this),
611
+			'spco-' . $this->slug() . '-whats-next-buttons-dv',
612
+			'spco-whats-next-buttons'
613
+		);
614
+		return $html;
615
+	}
616
+
617
+
618
+
619
+	/**
620
+	 * div_class - returns nothing for current step, but a css class of "hidden" for others
621
+	 *
622
+	 * @return string
623
+	 */
624
+	public function div_class()
625
+	{
626
+		return $this->is_current_step() ? '' : ' hidden';
627
+	}
628
+
629
+
630
+
631
+	/**
632
+	 * div_class - returns  a css class of "hidden" for current step, but nothing for others
633
+	 *
634
+	 * @return string
635
+	 */
636
+	public function edit_lnk_url()
637
+	{
638
+		return add_query_arg(array('step' => $this->slug()), $this->checkout->reg_page_base_url);
639
+	}
640
+
641
+
642
+
643
+	/**
644
+	 * div_class - returns  a css class of "hidden" for current step, but nothing for others
645
+	 *
646
+	 * @return string
647
+	 */
648
+	public function edit_link_class()
649
+	{
650
+		return $this->is_current_step() ? ' hidden' : '';
651
+	}
652
+
653
+
654
+
655
+	/**
656
+	 * update_checkout with changes that have been made to the cart
657
+	 *
658
+	 * @return void
659
+	 * @throws \EE_Error
660
+	 */
661
+	public function update_checkout()
662
+	{
663
+		// grab the cart grand total and reset TXN total
664
+		$this->checkout->transaction->set_total($this->checkout->cart->get_cart_grand_total());
665
+		$this->checkout->stash_transaction_and_checkout();
666
+	}
667
+
668
+
669
+
670
+
671
+
672
+	/**
673
+	 *    __sleep
674
+	 * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon
675
+	 * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the
676
+	 * reg form, because if needed, it will be regenerated anyways
677
+	 *
678
+	 * @return array
679
+	 */
680
+	public function __sleep()
681
+	{
682
+		// remove the reg form and the checkout
683
+		return array_diff(array_keys(get_object_vars($this)), array('reg_form', 'checkout'));
684
+	}
685 685
 
686 686
 
687 687
 
Please login to merge, or discard this patch.
Spacing   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -1,4 +1,4 @@  discard block
 block discarded – undo
1
-<?php if (! defined('EVENT_ESPRESSO_VERSION')) {
1
+<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2 2
     exit('No direct script access allowed');
3 3
 }
4 4
 
@@ -238,7 +238,7 @@  discard block
 block discarded – undo
238 238
      */
239 239
     public function set_submit_button_text($submit_button_text = '')
240 240
     {
241
-        if (! empty($submit_button_text)) {
241
+        if ( ! empty($submit_button_text)) {
242 242
             $this->_submit_button_text = $submit_button_text;
243 243
         } else if ($this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
244 244
             if ($this->checkout->revisit) {
@@ -410,7 +410,7 @@  discard block
 block discarded – undo
410 410
     public function reg_form_name()
411 411
     {
412 412
         if (empty($this->_reg_form_name)) {
413
-            $this->set_reg_form_name('ee-spco-' . $this->slug() . '-reg-step-form');
413
+            $this->set_reg_form_name('ee-spco-'.$this->slug().'-reg-step-form');
414 414
         }
415 415
         return $this->_reg_form_name;
416 416
     }
@@ -436,7 +436,7 @@  discard block
 block discarded – undo
436 436
     public function reg_step_url($action = '')
437 437
     {
438 438
         $query_args = array('step' => $this->slug());
439
-        if (! empty($action)) {
439
+        if ( ! empty($action)) {
440 440
             $query_args['action'] = $action;
441 441
         }
442 442
         // final step has no display
@@ -467,12 +467,12 @@  discard block
 block discarded – undo
467 467
             return new EE_Form_Section_Proper(
468 468
                 array(
469 469
                     'layout_strategy' => new EE_Div_Per_Section_Layout(),
470
-                    'html_id'         => 'ee-' . $this->slug() . '-hidden-inputs',
470
+                    'html_id'         => 'ee-'.$this->slug().'-hidden-inputs',
471 471
                     'subsections'     => array(
472 472
                         'next_step' => new EE_Fixed_Hidden_Input(
473 473
                             array(
474 474
                                 'html_name' => 'next_step',
475
-                                'html_id'   => 'spco-' . $this->slug() . '-next-step',
475
+                                'html_id'   => 'spco-'.$this->slug().'-next-step',
476 476
                                 'default'   => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
477 477
                                     ? $this->checkout->next_step->slug()
478 478
                                     : '',
@@ -493,19 +493,19 @@  discard block
 block discarded – undo
493 493
             return new EE_Form_Section_Proper(
494 494
                 array(
495 495
                     'layout_strategy' => new EE_Div_Per_Section_Layout(),
496
-                    'html_id'         => 'ee-' . $this->slug() . '-hidden-inputs',
496
+                    'html_id'         => 'ee-'.$this->slug().'-hidden-inputs',
497 497
                     'subsections'     => array(
498 498
                         'action'         => new EE_Fixed_Hidden_Input(
499 499
                             array(
500 500
                                 'html_name' => 'action',
501
-                                'html_id'   => 'spco-' . $this->slug() . '-action',
501
+                                'html_id'   => 'spco-'.$this->slug().'-action',
502 502
                                 'default'   => $default_form_action,
503 503
                             )
504 504
                         ),
505 505
                         'next_step'      => new EE_Fixed_Hidden_Input(
506 506
                             array(
507 507
                                 'html_name' => 'next_step',
508
-                                'html_id'   => 'spco-' . $this->slug() . '-next-step',
508
+                                'html_id'   => 'spco-'.$this->slug().'-next-step',
509 509
                                 'default'   => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
510 510
                                     ? $this->checkout->next_step->slug()
511 511
                                     : '',
@@ -585,7 +585,7 @@  discard block
 block discarded – undo
585 585
      */
586 586
     public function reg_step_submit_button()
587 587
     {
588
-        if (! $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
588
+        if ( ! $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
589 589
             return '';
590 590
         }
591 591
         ob_start();
@@ -598,17 +598,17 @@  discard block
 block discarded – undo
598 598
         $html = ob_get_clean();
599 599
         // generate submit button
600 600
         $sbmt_btn = new EE_Submit_Input(array(
601
-            'html_name'             => 'spco-go-to-step-' . $this->checkout->next_step->slug(),
602
-            'html_id'               => 'spco-go-to-step-' . $this->checkout->next_step->slug(),
601
+            'html_name'             => 'spco-go-to-step-'.$this->checkout->next_step->slug(),
602
+            'html_id'               => 'spco-go-to-step-'.$this->checkout->next_step->slug(),
603 603
             'html_class'            => 'spco-next-step-btn',
604
-            'other_html_attributes' => ' rel="' . $this->slug() . '"',
604
+            'other_html_attributes' => ' rel="'.$this->slug().'"',
605 605
             'default'               => $this->submit_button_text(),
606 606
         ));
607 607
         $sbmt_btn->set_button_css_attributes(true, 'large');
608 608
         $sbmt_btn_html = $sbmt_btn->get_html_for_input();
609 609
         $html .= EEH_HTML::div(
610 610
             apply_filters('FHEE__EE_SPCO_Reg_Step__reg_step_submit_button__sbmt_btn_html', $sbmt_btn_html, $this),
611
-            'spco-' . $this->slug() . '-whats-next-buttons-dv',
611
+            'spco-'.$this->slug().'-whats-next-buttons-dv',
612 612
             'spco-whats-next-buttons'
613 613
         );
614 614
         return $html;
Please login to merge, or discard this patch.
core/services/commands/registration/CreateRegistrationCommand.php 1 patch
Indentation   +157 added lines, -157 removed lines patch added patch discarded remove patch
@@ -13,7 +13,7 @@  discard block
 block discarded – undo
13 13
 use EventEspresso\core\services\commands\CommandRequiresCapCheckInterface;
14 14
 
15 15
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
16
-    exit('No direct script access allowed');
16
+	exit('No direct script access allowed');
17 17
 }
18 18
 
19 19
 
@@ -29,162 +29,162 @@  discard block
 block discarded – undo
29 29
 class CreateRegistrationCommand extends Command implements CommandRequiresCapCheckInterface
30 30
 {
31 31
 
32
-    /**
33
-     * @var EE_Transaction $transaction
34
-     */
35
-    private $transaction;
36
-
37
-    /**
38
-     * @var EE_Ticket $ticket
39
-     */
40
-    private $ticket;
41
-
42
-    /**
43
-     * @var EE_Line_Item $ticket_line_item
44
-     */
45
-    private $ticket_line_item;
46
-
47
-    /**
48
-     * @var int $reg_count
49
-     */
50
-    private $reg_count;
51
-
52
-    /**
53
-     * @var int $reg_group_size
54
-     */
55
-    private $reg_group_size;
56
-
57
-    /**
58
-     * @var string $reg_status
59
-     */
60
-    private $reg_status;
61
-
62
-    /**
63
-     * @var EE_Registration $registration
64
-     */
65
-    protected $registration;
66
-
67
-
68
-
69
-    /**
70
-     * CreateRegistrationCommand constructor.
71
-     *
72
-     * @param EE_Transaction $transaction
73
-     * @param EE_Line_Item   $ticket_line_item
74
-     * @param int             $reg_count
75
-     * @param int             $reg_group_size
76
-     * @param string          $reg_status
77
-     * @throws InvalidEntityException
78
-     */
79
-    public function __construct(
80
-        EE_Transaction $transaction,
81
-        EE_Line_Item $ticket_line_item,
82
-        $reg_count = 1,
83
-        $reg_group_size = 0,
84
-        $reg_status = EEM_Registration::status_id_incomplete
85
-    ) {
86
-        // grab the related ticket object for this line_item
87
-        $this->ticket = $ticket_line_item->ticket();
88
-        if ( ! $this->ticket instanceof EE_Ticket) {
89
-            throw new InvalidEntityException(
90
-                is_object($this->ticket) ? get_class($this->ticket) : gettype($this->ticket),
91
-                'EE_Ticket',
92
-                sprintf(
93
-                    __('Line item %s did not contain a valid ticket', 'event_espresso'),
94
-                    $ticket_line_item->ID()
95
-                )
96
-            );
97
-        }
98
-        $this->transaction = $transaction;
99
-        $this->ticket_line_item = $ticket_line_item;
100
-        $this->reg_count = absint($reg_count);
101
-        $this->reg_group_size = absint($reg_group_size);
102
-        $this->reg_status = $reg_status;
103
-    }
104
-
105
-
106
-
107
-    /**
108
-     * @return \EventEspresso\core\domain\services\capabilities\CapCheckInterface
109
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
110
-     */
111
-    public function getCapCheck()
112
-    {
113
-        if ( ! $this->cap_check instanceof CapCheckInterface) {
114
-            return new CapCheck('ee_edit_registrations', 'create_new_registration');
115
-        }
116
-        return $this->cap_check;
117
-    }
118
-
119
-
120
-
121
-    /**
122
-     * @return EE_Transaction
123
-     */
124
-    public function transaction()
125
-    {
126
-        return $this->transaction;
127
-    }
128
-
129
-
130
-
131
-    /**
132
-     * @return EE_Ticket
133
-     */
134
-    public function ticket()
135
-    {
136
-        return $this->ticket;
137
-    }
138
-
139
-
140
-
141
-    /**
142
-     * @return EE_Line_Item
143
-     */
144
-    public function ticketLineItem()
145
-    {
146
-        return $this->ticket_line_item;
147
-    }
148
-
149
-
150
-
151
-    /**
152
-     * @return int
153
-     */
154
-    public function regCount()
155
-    {
156
-        return $this->reg_count;
157
-    }
158
-
159
-
160
-
161
-    /**
162
-     * @return int
163
-     */
164
-    public function regGroupSize()
165
-    {
166
-        return $this->reg_group_size;
167
-    }
168
-
169
-
170
-
171
-    /**
172
-     * @return string
173
-     */
174
-    public function regStatus()
175
-    {
176
-        return $this->reg_status;
177
-    }
178
-
179
-
180
-
181
-    /**
182
-     * @return EE_Registration
183
-     */
184
-    public function registration()
185
-    {
186
-        return $this->registration;
187
-    }
32
+	/**
33
+	 * @var EE_Transaction $transaction
34
+	 */
35
+	private $transaction;
36
+
37
+	/**
38
+	 * @var EE_Ticket $ticket
39
+	 */
40
+	private $ticket;
41
+
42
+	/**
43
+	 * @var EE_Line_Item $ticket_line_item
44
+	 */
45
+	private $ticket_line_item;
46
+
47
+	/**
48
+	 * @var int $reg_count
49
+	 */
50
+	private $reg_count;
51
+
52
+	/**
53
+	 * @var int $reg_group_size
54
+	 */
55
+	private $reg_group_size;
56
+
57
+	/**
58
+	 * @var string $reg_status
59
+	 */
60
+	private $reg_status;
61
+
62
+	/**
63
+	 * @var EE_Registration $registration
64
+	 */
65
+	protected $registration;
66
+
67
+
68
+
69
+	/**
70
+	 * CreateRegistrationCommand constructor.
71
+	 *
72
+	 * @param EE_Transaction $transaction
73
+	 * @param EE_Line_Item   $ticket_line_item
74
+	 * @param int             $reg_count
75
+	 * @param int             $reg_group_size
76
+	 * @param string          $reg_status
77
+	 * @throws InvalidEntityException
78
+	 */
79
+	public function __construct(
80
+		EE_Transaction $transaction,
81
+		EE_Line_Item $ticket_line_item,
82
+		$reg_count = 1,
83
+		$reg_group_size = 0,
84
+		$reg_status = EEM_Registration::status_id_incomplete
85
+	) {
86
+		// grab the related ticket object for this line_item
87
+		$this->ticket = $ticket_line_item->ticket();
88
+		if ( ! $this->ticket instanceof EE_Ticket) {
89
+			throw new InvalidEntityException(
90
+				is_object($this->ticket) ? get_class($this->ticket) : gettype($this->ticket),
91
+				'EE_Ticket',
92
+				sprintf(
93
+					__('Line item %s did not contain a valid ticket', 'event_espresso'),
94
+					$ticket_line_item->ID()
95
+				)
96
+			);
97
+		}
98
+		$this->transaction = $transaction;
99
+		$this->ticket_line_item = $ticket_line_item;
100
+		$this->reg_count = absint($reg_count);
101
+		$this->reg_group_size = absint($reg_group_size);
102
+		$this->reg_status = $reg_status;
103
+	}
104
+
105
+
106
+
107
+	/**
108
+	 * @return \EventEspresso\core\domain\services\capabilities\CapCheckInterface
109
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
110
+	 */
111
+	public function getCapCheck()
112
+	{
113
+		if ( ! $this->cap_check instanceof CapCheckInterface) {
114
+			return new CapCheck('ee_edit_registrations', 'create_new_registration');
115
+		}
116
+		return $this->cap_check;
117
+	}
118
+
119
+
120
+
121
+	/**
122
+	 * @return EE_Transaction
123
+	 */
124
+	public function transaction()
125
+	{
126
+		return $this->transaction;
127
+	}
128
+
129
+
130
+
131
+	/**
132
+	 * @return EE_Ticket
133
+	 */
134
+	public function ticket()
135
+	{
136
+		return $this->ticket;
137
+	}
138
+
139
+
140
+
141
+	/**
142
+	 * @return EE_Line_Item
143
+	 */
144
+	public function ticketLineItem()
145
+	{
146
+		return $this->ticket_line_item;
147
+	}
148
+
149
+
150
+
151
+	/**
152
+	 * @return int
153
+	 */
154
+	public function regCount()
155
+	{
156
+		return $this->reg_count;
157
+	}
158
+
159
+
160
+
161
+	/**
162
+	 * @return int
163
+	 */
164
+	public function regGroupSize()
165
+	{
166
+		return $this->reg_group_size;
167
+	}
168
+
169
+
170
+
171
+	/**
172
+	 * @return string
173
+	 */
174
+	public function regStatus()
175
+	{
176
+		return $this->reg_status;
177
+	}
178
+
179
+
180
+
181
+	/**
182
+	 * @return EE_Registration
183
+	 */
184
+	public function registration()
185
+	{
186
+		return $this->registration;
187
+	}
188 188
 
189 189
 
190 190
 
Please login to merge, or discard this patch.
core/domain/entities/RegUrlLink.php 2 patches
Indentation   +96 added lines, -96 removed lines patch added patch discarded remove patch
@@ -7,7 +7,7 @@  discard block
 block discarded – undo
7 7
 use InvalidArgumentException;
8 8
 
9 9
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
10
-    exit('No direct script access allowed');
10
+	exit('No direct script access allowed');
11 11
 }
12 12
 
13 13
 
@@ -23,103 +23,103 @@  discard block
 block discarded – undo
23 23
 class RegUrlLink
24 24
 {
25 25
 
26
-    /*
26
+	/*
27 27
      * @var string $reg_url_link
28 28
      */
29
-    private $reg_url_link;
30
-
31
-
32
-
33
-    /**
34
-     * @param string $reg_url_link
35
-     * @return RegUrlLink
36
-     * @throws InvalidArgumentException
37
-     */
38
-    public static function fromRegUrlLinkString($reg_url_link)
39
-    {
40
-        if (empty($reg_url_link) || ! is_string($reg_url_link)) {
41
-            throw new InvalidArgumentException(
42
-                __(
43
-                    'You must supply a valid non-empty string to generate a reg_url_link.',
44
-                    'event_espresso'
45
-                )
46
-            );
47
-        }
48
-        return new RegUrlLink(1, '', $reg_url_link);
49
-    }
50
-
51
-
52
-
53
-    /**
54
-     * @param EE_Registration $registration
55
-     * @return RegUrlLink
56
-     * @throws EntityNotFoundException
57
-     * @throws EE_Error
58
-     * @throws InvalidArgumentException
59
-     */
60
-    public static function fromRegistration(EE_Registration $registration)
61
-    {
62
-        return new RegUrlLink(
63
-            $registration->count(),
64
-            $registration->ticket_line_item()
65
-        );
66
-    }
67
-
68
-
69
-
70
-    /**
71
-     * CreateRegUrlLinkCommand constructor.
72
-     *
73
-     * @param int    $reg_count
74
-     * @param mixed  $base_code
75
-     * @param string $reg_url_link
76
-     * @throws InvalidArgumentException
77
-     */
78
-    public function __construct(
79
-        $reg_count = 1,
80
-        $base_code = '',
81
-        $reg_url_link = ''
82
-    ) {
83
-        if ( ! empty($reg_url_link) && is_string($reg_url_link)) {
84
-            $this->reg_url_link = apply_filters(
85
-                'FHEE__\EventEspresso\core\domain\entities\RegUrlLink__construct__reg_url_link',
86
-                $reg_url_link,
87
-                $reg_count,
88
-                $base_code,
89
-                $reg_url_link
90
-            );
91
-            return;
92
-        }
93
-        $reg_count = max(1, absint($reg_count));
94
-        $base_code = $base_code instanceof \EE_Line_Item ? $base_code->code() : $base_code;
95
-        if (empty($base_code) || ! is_string($base_code)) {
96
-            throw new InvalidArgumentException(
97
-                __(
98
-                    'You must supply a valid EE_Line_Item or a non-empty string to generate a reg_url_link.',
99
-                    'event_espresso'
100
-                )
101
-            );
102
-        }
103
-        $this->reg_url_link = (string) apply_filters(
104
-            'FHEE__\EventEspresso\core\domain\entities\RegUrlLink__construct__reg_url_link',
105
-            $reg_count . '-' . md5($base_code . microtime()),
106
-            $reg_count,
107
-            $base_code,
108
-            $reg_url_link
109
-        );
110
-    }
111
-
112
-
113
-
114
-    /**
115
-     * Return the object as a string
116
-     *
117
-     * @return string
118
-     */
119
-    public function __toString()
120
-    {
121
-        return $this->reg_url_link;
122
-    }
29
+	private $reg_url_link;
30
+
31
+
32
+
33
+	/**
34
+	 * @param string $reg_url_link
35
+	 * @return RegUrlLink
36
+	 * @throws InvalidArgumentException
37
+	 */
38
+	public static function fromRegUrlLinkString($reg_url_link)
39
+	{
40
+		if (empty($reg_url_link) || ! is_string($reg_url_link)) {
41
+			throw new InvalidArgumentException(
42
+				__(
43
+					'You must supply a valid non-empty string to generate a reg_url_link.',
44
+					'event_espresso'
45
+				)
46
+			);
47
+		}
48
+		return new RegUrlLink(1, '', $reg_url_link);
49
+	}
50
+
51
+
52
+
53
+	/**
54
+	 * @param EE_Registration $registration
55
+	 * @return RegUrlLink
56
+	 * @throws EntityNotFoundException
57
+	 * @throws EE_Error
58
+	 * @throws InvalidArgumentException
59
+	 */
60
+	public static function fromRegistration(EE_Registration $registration)
61
+	{
62
+		return new RegUrlLink(
63
+			$registration->count(),
64
+			$registration->ticket_line_item()
65
+		);
66
+	}
67
+
68
+
69
+
70
+	/**
71
+	 * CreateRegUrlLinkCommand constructor.
72
+	 *
73
+	 * @param int    $reg_count
74
+	 * @param mixed  $base_code
75
+	 * @param string $reg_url_link
76
+	 * @throws InvalidArgumentException
77
+	 */
78
+	public function __construct(
79
+		$reg_count = 1,
80
+		$base_code = '',
81
+		$reg_url_link = ''
82
+	) {
83
+		if ( ! empty($reg_url_link) && is_string($reg_url_link)) {
84
+			$this->reg_url_link = apply_filters(
85
+				'FHEE__\EventEspresso\core\domain\entities\RegUrlLink__construct__reg_url_link',
86
+				$reg_url_link,
87
+				$reg_count,
88
+				$base_code,
89
+				$reg_url_link
90
+			);
91
+			return;
92
+		}
93
+		$reg_count = max(1, absint($reg_count));
94
+		$base_code = $base_code instanceof \EE_Line_Item ? $base_code->code() : $base_code;
95
+		if (empty($base_code) || ! is_string($base_code)) {
96
+			throw new InvalidArgumentException(
97
+				__(
98
+					'You must supply a valid EE_Line_Item or a non-empty string to generate a reg_url_link.',
99
+					'event_espresso'
100
+				)
101
+			);
102
+		}
103
+		$this->reg_url_link = (string) apply_filters(
104
+			'FHEE__\EventEspresso\core\domain\entities\RegUrlLink__construct__reg_url_link',
105
+			$reg_count . '-' . md5($base_code . microtime()),
106
+			$reg_count,
107
+			$base_code,
108
+			$reg_url_link
109
+		);
110
+	}
111
+
112
+
113
+
114
+	/**
115
+	 * Return the object as a string
116
+	 *
117
+	 * @return string
118
+	 */
119
+	public function __toString()
120
+	{
121
+		return $this->reg_url_link;
122
+	}
123 123
 }
124 124
 // End of file RegUrlLink.php
125 125
 // Location: /RegUrlLink.php
126 126
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -102,7 +102,7 @@
 block discarded – undo
102 102
         }
103 103
         $this->reg_url_link = (string) apply_filters(
104 104
             'FHEE__\EventEspresso\core\domain\entities\RegUrlLink__construct__reg_url_link',
105
-            $reg_count . '-' . md5($base_code . microtime()),
105
+            $reg_count.'-'.md5($base_code.microtime()),
106 106
             $reg_count,
107 107
             $base_code,
108 108
             $reg_url_link
Please login to merge, or discard this patch.
core/libraries/form_sections/base/EE_Form_Section_Base.form.php 2 patches
Indentation   +464 added lines, -464 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@  discard block
 block discarded – undo
2 2
 use EventEspresso\core\libraries\form_sections\strategies\filter\FormHtmlFilter;
3 3
 
4 4
 if (! defined('EVENT_ESPRESSO_VERSION')) {
5
-    exit('No direct script access allowed');
5
+	exit('No direct script access allowed');
6 6
 }
7 7
 
8 8
 
@@ -19,480 +19,480 @@  discard block
 block discarded – undo
19 19
 abstract class EE_Form_Section_Base
20 20
 {
21 21
 
22
-    /**
23
-     * the URL the form is submitted to
24
-     *
25
-     * @var string
26
-     */
27
-    protected $_action;
28
-
29
-    /**
30
-     * POST (default) or GET
31
-     *
32
-     * @var string
33
-     */
34
-    protected $_method;
35
-
36
-    /**
37
-     * html_id and html_name are derived from this by default
38
-     *
39
-     * @var string
40
-     */
41
-    protected $_name;
42
-
43
-    /**
44
-     * $_html_id
45
-     * @var string
46
-     */
47
-    protected $_html_id;
48
-
49
-    /**
50
-     * $_html_class
51
-     * @var string
52
-     */
53
-    protected $_html_class;
54
-
55
-    /**
56
-     * $_html_style
57
-     * @var string
58
-     */
59
-    protected $_html_style;
60
-
61
-    /**
62
-     * $_other_html_attributes
63
-     * @var string
64
-     */
65
-    protected $_other_html_attributes;
66
-
67
-    /**
68
-     * The form section of which this form section is a part
69
-     *
70
-     * @var EE_Form_Section_Proper
71
-     */
72
-    protected $_parent_section;
73
-
74
-    /**
75
-     * flag indicating that _construct_finalize has been called.
76
-     * If it hasn't been called and we try to use functions which require it, we call it
77
-     * with no parameters. But normally, _construct_finalize should be called by the instantiating class
78
-     *
79
-     * @var boolean
80
-     */
81
-    protected $_construction_finalized;
82
-
83
-    /**
84
-     * Strategy for parsing the form HTML upon display
85
-     *
86
-     * @var FormHtmlFilter
87
-     */
88
-    protected $_form_html_filter;
89
-
90
-
91
-
92
-    /**
93
-     * @param array $options_array {
94
-     * @type        $name          string the name for this form section, if you want to explicitly define it
95
-     *                             }
96
-     */
97
-    public function __construct($options_array = array())
98
-    {
99
-        // used by display strategies
100
-        // assign incoming values to properties
101
-        foreach ($options_array as $key => $value) {
102
-            $key = '_' . $key;
103
-            if (property_exists($this, $key) && empty($this->{$key})) {
104
-                $this->{$key} = $value;
105
-            }
106
-        }
107
-        // set parser which allows the form section's rendered HTML to be filtered
108
-        if (isset($options_array['form_html_filter']) && $options_array['form_html_filter'] instanceof FormHtmlFilter) {
109
-            $this->_form_html_filter = $options_array['form_html_filter'];
110
-        }
111
-    }
112
-
113
-
114
-
115
-    /**
116
-     * @param $parent_form_section
117
-     * @param $name
118
-     * @throws \EE_Error
119
-     */
120
-    protected function _construct_finalize($parent_form_section, $name)
121
-    {
122
-        $this->_construction_finalized = true;
123
-        $this->_parent_section = $parent_form_section;
124
-        if ($name !== null) {
125
-            $this->_name = $name;
126
-        }
127
-    }
128
-
129
-
130
-
131
-    /**
132
-     * make sure construction finalized was called, otherwise children might not be ready
133
-     *
134
-     * @return void
135
-     * @throws \EE_Error
136
-     */
137
-    public function ensure_construct_finalized_called()
138
-    {
139
-        if (! $this->_construction_finalized) {
140
-            $this->_construct_finalize($this->_parent_section, $this->_name);
141
-        }
142
-    }
143
-
144
-
145
-
146
-    /**
147
-     * @return string
148
-     */
149
-    public function action()
150
-    {
151
-        return $this->_action;
152
-    }
153
-
154
-
155
-
156
-    /**
157
-     * @param string $action
158
-     */
159
-    public function set_action($action)
160
-    {
161
-        $this->_action = $action;
162
-    }
163
-
164
-
165
-
166
-    /**
167
-     * @return string
168
-     */
169
-    public function method()
170
-    {
171
-        return ! empty($this->_method) ? $this->_method : 'POST';
172
-    }
173
-
174
-
175
-
176
-    /**
177
-     * @param string $method
178
-     */
179
-    public function set_method($method)
180
-    {
181
-        switch ($method) {
182
-            case 'get' :
183
-            case 'GET' :
184
-                $this->_method = 'GET';
185
-                break;
186
-            default :
187
-                $this->_method = 'POST';
188
-        }
189
-    }
190
-
191
-
192
-
193
-    /**
194
-     * Sets the html_id to its default value, if none was specified in the constructor.
195
-     * Calculation involves using the name and the parent's html id
196
-     * return void
197
-     *
198
-     * @throws \EE_Error
199
-     */
200
-    protected function _set_default_html_id_if_empty()
201
-    {
202
-        if (! $this->_html_id) {
203
-            if ($this->_parent_section && $this->_parent_section instanceof EE_Form_Section_Proper) {
204
-                $this->_html_id = $this->_parent_section->html_id()
205
-                                  . '-'
206
-                                  . $this->_prep_name_for_html_id($this->name());
207
-            } else {
208
-                $this->_html_id = $this->_prep_name_for_html_id($this->name());
209
-            }
210
-        }
211
-    }
212
-
213
-
214
-
215
-    /**
216
-     * _prep_name_for_html_id
217
-     *
218
-     * @param $name
219
-     * @return string
220
-     */
221
-    private function _prep_name_for_html_id($name)
222
-    {
223
-        return sanitize_key(str_replace(array('&nbsp;', ' ', '_'), '-', $name));
224
-    }
22
+	/**
23
+	 * the URL the form is submitted to
24
+	 *
25
+	 * @var string
26
+	 */
27
+	protected $_action;
28
+
29
+	/**
30
+	 * POST (default) or GET
31
+	 *
32
+	 * @var string
33
+	 */
34
+	protected $_method;
35
+
36
+	/**
37
+	 * html_id and html_name are derived from this by default
38
+	 *
39
+	 * @var string
40
+	 */
41
+	protected $_name;
42
+
43
+	/**
44
+	 * $_html_id
45
+	 * @var string
46
+	 */
47
+	protected $_html_id;
48
+
49
+	/**
50
+	 * $_html_class
51
+	 * @var string
52
+	 */
53
+	protected $_html_class;
54
+
55
+	/**
56
+	 * $_html_style
57
+	 * @var string
58
+	 */
59
+	protected $_html_style;
60
+
61
+	/**
62
+	 * $_other_html_attributes
63
+	 * @var string
64
+	 */
65
+	protected $_other_html_attributes;
66
+
67
+	/**
68
+	 * The form section of which this form section is a part
69
+	 *
70
+	 * @var EE_Form_Section_Proper
71
+	 */
72
+	protected $_parent_section;
73
+
74
+	/**
75
+	 * flag indicating that _construct_finalize has been called.
76
+	 * If it hasn't been called and we try to use functions which require it, we call it
77
+	 * with no parameters. But normally, _construct_finalize should be called by the instantiating class
78
+	 *
79
+	 * @var boolean
80
+	 */
81
+	protected $_construction_finalized;
82
+
83
+	/**
84
+	 * Strategy for parsing the form HTML upon display
85
+	 *
86
+	 * @var FormHtmlFilter
87
+	 */
88
+	protected $_form_html_filter;
89
+
90
+
91
+
92
+	/**
93
+	 * @param array $options_array {
94
+	 * @type        $name          string the name for this form section, if you want to explicitly define it
95
+	 *                             }
96
+	 */
97
+	public function __construct($options_array = array())
98
+	{
99
+		// used by display strategies
100
+		// assign incoming values to properties
101
+		foreach ($options_array as $key => $value) {
102
+			$key = '_' . $key;
103
+			if (property_exists($this, $key) && empty($this->{$key})) {
104
+				$this->{$key} = $value;
105
+			}
106
+		}
107
+		// set parser which allows the form section's rendered HTML to be filtered
108
+		if (isset($options_array['form_html_filter']) && $options_array['form_html_filter'] instanceof FormHtmlFilter) {
109
+			$this->_form_html_filter = $options_array['form_html_filter'];
110
+		}
111
+	}
112
+
113
+
114
+
115
+	/**
116
+	 * @param $parent_form_section
117
+	 * @param $name
118
+	 * @throws \EE_Error
119
+	 */
120
+	protected function _construct_finalize($parent_form_section, $name)
121
+	{
122
+		$this->_construction_finalized = true;
123
+		$this->_parent_section = $parent_form_section;
124
+		if ($name !== null) {
125
+			$this->_name = $name;
126
+		}
127
+	}
128
+
129
+
130
+
131
+	/**
132
+	 * make sure construction finalized was called, otherwise children might not be ready
133
+	 *
134
+	 * @return void
135
+	 * @throws \EE_Error
136
+	 */
137
+	public function ensure_construct_finalized_called()
138
+	{
139
+		if (! $this->_construction_finalized) {
140
+			$this->_construct_finalize($this->_parent_section, $this->_name);
141
+		}
142
+	}
143
+
144
+
145
+
146
+	/**
147
+	 * @return string
148
+	 */
149
+	public function action()
150
+	{
151
+		return $this->_action;
152
+	}
153
+
154
+
155
+
156
+	/**
157
+	 * @param string $action
158
+	 */
159
+	public function set_action($action)
160
+	{
161
+		$this->_action = $action;
162
+	}
163
+
164
+
165
+
166
+	/**
167
+	 * @return string
168
+	 */
169
+	public function method()
170
+	{
171
+		return ! empty($this->_method) ? $this->_method : 'POST';
172
+	}
173
+
174
+
175
+
176
+	/**
177
+	 * @param string $method
178
+	 */
179
+	public function set_method($method)
180
+	{
181
+		switch ($method) {
182
+			case 'get' :
183
+			case 'GET' :
184
+				$this->_method = 'GET';
185
+				break;
186
+			default :
187
+				$this->_method = 'POST';
188
+		}
189
+	}
190
+
191
+
192
+
193
+	/**
194
+	 * Sets the html_id to its default value, if none was specified in the constructor.
195
+	 * Calculation involves using the name and the parent's html id
196
+	 * return void
197
+	 *
198
+	 * @throws \EE_Error
199
+	 */
200
+	protected function _set_default_html_id_if_empty()
201
+	{
202
+		if (! $this->_html_id) {
203
+			if ($this->_parent_section && $this->_parent_section instanceof EE_Form_Section_Proper) {
204
+				$this->_html_id = $this->_parent_section->html_id()
205
+								  . '-'
206
+								  . $this->_prep_name_for_html_id($this->name());
207
+			} else {
208
+				$this->_html_id = $this->_prep_name_for_html_id($this->name());
209
+			}
210
+		}
211
+	}
212
+
213
+
214
+
215
+	/**
216
+	 * _prep_name_for_html_id
217
+	 *
218
+	 * @param $name
219
+	 * @return string
220
+	 */
221
+	private function _prep_name_for_html_id($name)
222
+	{
223
+		return sanitize_key(str_replace(array('&nbsp;', ' ', '_'), '-', $name));
224
+	}
225 225
 
226 226
 
227 227
 
228
-    /**
229
-     * Returns the HTML, JS, and CSS necessary to display this form section on a page.
230
-     * Note however, it's recommended that you instead call enqueue_js on the "wp_enqueue_scripts" action,
231
-     * and call get_html when you want to output the html. Calling get_html_and_js after
232
-     * "wp_enqueue_scripts" has already fired seems to work for now, but is contrary
233
-     * to the instructions on https://developer.wordpress.org/reference/functions/wp_enqueue_script/
234
-     * and so might stop working anytime.
235
-     *
236
-     * @return string
237
-     */
238
-    public function get_html_and_js()
239
-    {
240
-        return $this->get_html();
241
-    }
228
+	/**
229
+	 * Returns the HTML, JS, and CSS necessary to display this form section on a page.
230
+	 * Note however, it's recommended that you instead call enqueue_js on the "wp_enqueue_scripts" action,
231
+	 * and call get_html when you want to output the html. Calling get_html_and_js after
232
+	 * "wp_enqueue_scripts" has already fired seems to work for now, but is contrary
233
+	 * to the instructions on https://developer.wordpress.org/reference/functions/wp_enqueue_script/
234
+	 * and so might stop working anytime.
235
+	 *
236
+	 * @return string
237
+	 */
238
+	public function get_html_and_js()
239
+	{
240
+		return $this->get_html();
241
+	}
242 242
 
243 243
 
244 244
 
245
-    /**
246
-     * Gets the HTML for displaying this form section
247
-     *
248
-     * @return string
249
-     */
250
-    public abstract function get_html();
245
+	/**
246
+	 * Gets the HTML for displaying this form section
247
+	 *
248
+	 * @return string
249
+	 */
250
+	public abstract function get_html();
251 251
 
252 252
 
253 253
 
254
-    /**
255
-     * @param bool $add_pound_sign
256
-     * @return string
257
-     */
258
-    public function html_id($add_pound_sign = false)
259
-    {
260
-        $this->_set_default_html_id_if_empty();
261
-        return $add_pound_sign ? '#' . $this->_html_id : $this->_html_id;
262
-    }
254
+	/**
255
+	 * @param bool $add_pound_sign
256
+	 * @return string
257
+	 */
258
+	public function html_id($add_pound_sign = false)
259
+	{
260
+		$this->_set_default_html_id_if_empty();
261
+		return $add_pound_sign ? '#' . $this->_html_id : $this->_html_id;
262
+	}
263 263
 
264 264
 
265
-
266
-    /**
267
-     * @return string
268
-     */
269
-    public function html_class()
270
-    {
271
-        return $this->_html_class;
272
-    }
273
-
274
-
275
-
276
-    /**
277
-     * @return string
278
-     */
279
-    public function html_style()
280
-    {
281
-        return $this->_html_style;
282
-    }
283
-
284
-
285
-
286
-    /**
287
-     * @param mixed $html_class
288
-     */
289
-    public function set_html_class($html_class)
290
-    {
291
-        $this->_html_class = $html_class;
292
-    }
293
-
294
-
295
-
296
-    /**
297
-     * @param mixed $html_id
298
-     */
299
-    public function set_html_id($html_id)
300
-    {
301
-        $this->_html_id = $html_id;
302
-    }
303
-
304
-
305
-
306
-    /**
307
-     * @param mixed $html_style
308
-     */
309
-    public function set_html_style($html_style)
310
-    {
311
-        $this->_html_style = $html_style;
312
-    }
313
-
314
-
315
-
316
-    /**
317
-     * @param string $other_html_attributes
318
-     */
319
-    public function set_other_html_attributes($other_html_attributes)
320
-    {
321
-        $this->_other_html_attributes = $other_html_attributes;
322
-    }
323
-
324
-
325
-
326
-    /**
327
-     * @return string
328
-     */
329
-    public function other_html_attributes()
330
-    {
331
-        return $this->_other_html_attributes;
332
-    }
333
-
334
-
335
-
336
-    /**
337
-     * Gets the name of the form section. This is not the same as the HTML name.
338
-     *
339
-     * @throws EE_Error
340
-     * @return string
341
-     */
342
-    public function name()
343
-    {
344
-        if (! $this->_construction_finalized) {
345
-            throw new EE_Error(sprintf(__('You cannot use the form section\s name until _construct_finalize has been called on it (when we set the name). It was called on a form section of type \'s\'',
346
-                'event_espresso'), get_class($this)));
347
-        }
348
-        return $this->_name;
349
-    }
350
-
351
-
352
-
353
-    /**
354
-     * Gets the parent section
355
-     *
356
-     * @return EE_Form_Section_Proper
357
-     */
358
-    public function parent_section()
359
-    {
360
-        return $this->_parent_section;
361
-    }
362
-
363
-
364
-
365
-    /**
366
-     * returns HTML for generating the opening form HTML tag (<form>)
367
-     *
368
-     * @param string $action           the URL the form is submitted to
369
-     * @param string $method           POST (default) or GET
370
-     * @param string $other_attributes anything else added to the form open tag, MUST BE VALID HTML
371
-     * @return string
372
-     */
373
-    public function form_open($action = '', $method = '', $other_attributes = '')
374
-    {
375
-        if (! empty($action)) {
376
-            $this->set_action($action);
377
-        }
378
-        if (! empty($method)) {
379
-            $this->set_method($method);
380
-        }
381
-        $html = EEH_HTML::nl(1, 'form') . '<form';
382
-        $html .= $this->html_id() !== '' ? ' id="' . $this->get_html_id_for_form($this->html_id()) . '"' : '';
383
-        $html .= ' action="' . $this->action() . '"';
384
-        $html .= ' method="' . $this->method() . '"';
385
-        $html .= $other_attributes . '>';
386
-        return $html;
387
-    }
388
-
389
-
390
-
391
-    /**
392
-     * ensures that html id for form either ends in "-form" or "-frm"
393
-     * so that id doesn't conflict/collide with other elements
394
-     *
395
-     * @param string $html_id
396
-     * @return string
397
-     */
398
-    protected function get_html_id_for_form($html_id)
399
-    {
400
-        $strlen = strlen($html_id);
401
-        $html_id = strpos($html_id, '-form') === $strlen-5 || strpos($html_id, '-frm') === $strlen - 4
402
-            ? $html_id
403
-            : $html_id . '-frm';
404
-        return $html_id;
405
-    }
406
-
407
-
408
-
409
-    /**
410
-     * returns HTML for generating the closing form HTML tag (</form>)
411
-     *
412
-     * @return string
413
-     */
414
-    public function form_close()
415
-    {
416
-        return EEH_HTML::nl(-1, 'form')
417
-               . '</form>'
418
-               . EEH_HTML::nl()
419
-               . '<!-- end of ee-'
420
-               . $this->html_id()
421
-               . '-form -->'
422
-               . EEH_HTML::nl();
423
-    }
424
-
425
-
426
-
427
-    /**
428
-     * enqueues JS (and CSS) for the form (ie immediately call wp_enqueue_script and
429
-     * wp_enqueue_style; the scripts could have optionally been registered earlier)
430
-     * Default does nothing, but child classes can override
431
-     *
432
-     * @return void
433
-     */
434
-    public function enqueue_js()
435
-    {
436
-        //defaults to enqueue NO js or css
437
-    }
438
-
439
-
440
-
441
-    /**
442
-     * Adds any extra data needed by js. Eventually we'll call wp_localize_script
443
-     * with it, and it will be on each form section's 'other_data' property.
444
-     * By default nothing is added, but child classes can extend this method to add something.
445
-     * Eg, if you have an input that will cause a modal dialog to appear,
446
-     * here you could add an entry like 'modal_dialog_inputs' to this array
447
-     * to map between the input's html ID and the modal dialogue's ID, so that
448
-     * your JS code will know where to find the modal dialog when the input is pressed.
449
-     * Eg $form_other_js_data['modal_dialog_inputs']['some-input-id']='modal-dialog-id';
450
-     *
451
-     * @param array $form_other_js_data
452
-     * @return array
453
-     */
454
-    public function get_other_js_data($form_other_js_data = array())
455
-    {
456
-        return $form_other_js_data;
457
-    }
458
-
459
-
460
-
461
-    /**
462
-     * This isn't just the name of an input, it's a path pointing to an input. The
463
-     * path is similar to a folder path: slash (/) means to descend into a subsection,
464
-     * dot-dot-slash (../) means to ascend into the parent section.
465
-     * After a series of slashes and dot-dot-slashes, there should be the name of an input,
466
-     * which will be returned.
467
-     * Eg, if you want the related input to be conditional on a sibling input name 'foobar'
468
-     * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name
469
-     * 'baz', use '../baz'. If you want it to be conditional on a cousin input,
470
-     * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'.
471
-     * Etc
472
-     *
473
-     * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false
474
-     * @return EE_Form_Section_Base
475
-     */
476
-    public function find_section_from_path($form_section_path)
477
-    {
478
-        if (strpos($form_section_path, '/') === 0) {
479
-            $form_section_path = substr($form_section_path, strlen('/'));
480
-        }
481
-        if (empty($form_section_path)) {
482
-            return $this;
483
-        }
484
-        if (strpos($form_section_path, '../') === 0) {
485
-            $parent = $this->parent_section();
486
-            $form_section_path = substr($form_section_path, strlen('../'));
487
-            if ($parent instanceof EE_Form_Section_Base) {
488
-                return $parent->find_section_from_path($form_section_path);
489
-            } elseif (empty($form_section_path)) {
490
-                return $this;
491
-            }
492
-        }
493
-        //couldn't find it using simple parent following
494
-        return null;
495
-    }
265
+
266
+	/**
267
+	 * @return string
268
+	 */
269
+	public function html_class()
270
+	{
271
+		return $this->_html_class;
272
+	}
273
+
274
+
275
+
276
+	/**
277
+	 * @return string
278
+	 */
279
+	public function html_style()
280
+	{
281
+		return $this->_html_style;
282
+	}
283
+
284
+
285
+
286
+	/**
287
+	 * @param mixed $html_class
288
+	 */
289
+	public function set_html_class($html_class)
290
+	{
291
+		$this->_html_class = $html_class;
292
+	}
293
+
294
+
295
+
296
+	/**
297
+	 * @param mixed $html_id
298
+	 */
299
+	public function set_html_id($html_id)
300
+	{
301
+		$this->_html_id = $html_id;
302
+	}
303
+
304
+
305
+
306
+	/**
307
+	 * @param mixed $html_style
308
+	 */
309
+	public function set_html_style($html_style)
310
+	{
311
+		$this->_html_style = $html_style;
312
+	}
313
+
314
+
315
+
316
+	/**
317
+	 * @param string $other_html_attributes
318
+	 */
319
+	public function set_other_html_attributes($other_html_attributes)
320
+	{
321
+		$this->_other_html_attributes = $other_html_attributes;
322
+	}
323
+
324
+
325
+
326
+	/**
327
+	 * @return string
328
+	 */
329
+	public function other_html_attributes()
330
+	{
331
+		return $this->_other_html_attributes;
332
+	}
333
+
334
+
335
+
336
+	/**
337
+	 * Gets the name of the form section. This is not the same as the HTML name.
338
+	 *
339
+	 * @throws EE_Error
340
+	 * @return string
341
+	 */
342
+	public function name()
343
+	{
344
+		if (! $this->_construction_finalized) {
345
+			throw new EE_Error(sprintf(__('You cannot use the form section\s name until _construct_finalize has been called on it (when we set the name). It was called on a form section of type \'s\'',
346
+				'event_espresso'), get_class($this)));
347
+		}
348
+		return $this->_name;
349
+	}
350
+
351
+
352
+
353
+	/**
354
+	 * Gets the parent section
355
+	 *
356
+	 * @return EE_Form_Section_Proper
357
+	 */
358
+	public function parent_section()
359
+	{
360
+		return $this->_parent_section;
361
+	}
362
+
363
+
364
+
365
+	/**
366
+	 * returns HTML for generating the opening form HTML tag (<form>)
367
+	 *
368
+	 * @param string $action           the URL the form is submitted to
369
+	 * @param string $method           POST (default) or GET
370
+	 * @param string $other_attributes anything else added to the form open tag, MUST BE VALID HTML
371
+	 * @return string
372
+	 */
373
+	public function form_open($action = '', $method = '', $other_attributes = '')
374
+	{
375
+		if (! empty($action)) {
376
+			$this->set_action($action);
377
+		}
378
+		if (! empty($method)) {
379
+			$this->set_method($method);
380
+		}
381
+		$html = EEH_HTML::nl(1, 'form') . '<form';
382
+		$html .= $this->html_id() !== '' ? ' id="' . $this->get_html_id_for_form($this->html_id()) . '"' : '';
383
+		$html .= ' action="' . $this->action() . '"';
384
+		$html .= ' method="' . $this->method() . '"';
385
+		$html .= $other_attributes . '>';
386
+		return $html;
387
+	}
388
+
389
+
390
+
391
+	/**
392
+	 * ensures that html id for form either ends in "-form" or "-frm"
393
+	 * so that id doesn't conflict/collide with other elements
394
+	 *
395
+	 * @param string $html_id
396
+	 * @return string
397
+	 */
398
+	protected function get_html_id_for_form($html_id)
399
+	{
400
+		$strlen = strlen($html_id);
401
+		$html_id = strpos($html_id, '-form') === $strlen-5 || strpos($html_id, '-frm') === $strlen - 4
402
+			? $html_id
403
+			: $html_id . '-frm';
404
+		return $html_id;
405
+	}
406
+
407
+
408
+
409
+	/**
410
+	 * returns HTML for generating the closing form HTML tag (</form>)
411
+	 *
412
+	 * @return string
413
+	 */
414
+	public function form_close()
415
+	{
416
+		return EEH_HTML::nl(-1, 'form')
417
+			   . '</form>'
418
+			   . EEH_HTML::nl()
419
+			   . '<!-- end of ee-'
420
+			   . $this->html_id()
421
+			   . '-form -->'
422
+			   . EEH_HTML::nl();
423
+	}
424
+
425
+
426
+
427
+	/**
428
+	 * enqueues JS (and CSS) for the form (ie immediately call wp_enqueue_script and
429
+	 * wp_enqueue_style; the scripts could have optionally been registered earlier)
430
+	 * Default does nothing, but child classes can override
431
+	 *
432
+	 * @return void
433
+	 */
434
+	public function enqueue_js()
435
+	{
436
+		//defaults to enqueue NO js or css
437
+	}
438
+
439
+
440
+
441
+	/**
442
+	 * Adds any extra data needed by js. Eventually we'll call wp_localize_script
443
+	 * with it, and it will be on each form section's 'other_data' property.
444
+	 * By default nothing is added, but child classes can extend this method to add something.
445
+	 * Eg, if you have an input that will cause a modal dialog to appear,
446
+	 * here you could add an entry like 'modal_dialog_inputs' to this array
447
+	 * to map between the input's html ID and the modal dialogue's ID, so that
448
+	 * your JS code will know where to find the modal dialog when the input is pressed.
449
+	 * Eg $form_other_js_data['modal_dialog_inputs']['some-input-id']='modal-dialog-id';
450
+	 *
451
+	 * @param array $form_other_js_data
452
+	 * @return array
453
+	 */
454
+	public function get_other_js_data($form_other_js_data = array())
455
+	{
456
+		return $form_other_js_data;
457
+	}
458
+
459
+
460
+
461
+	/**
462
+	 * This isn't just the name of an input, it's a path pointing to an input. The
463
+	 * path is similar to a folder path: slash (/) means to descend into a subsection,
464
+	 * dot-dot-slash (../) means to ascend into the parent section.
465
+	 * After a series of slashes and dot-dot-slashes, there should be the name of an input,
466
+	 * which will be returned.
467
+	 * Eg, if you want the related input to be conditional on a sibling input name 'foobar'
468
+	 * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name
469
+	 * 'baz', use '../baz'. If you want it to be conditional on a cousin input,
470
+	 * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'.
471
+	 * Etc
472
+	 *
473
+	 * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false
474
+	 * @return EE_Form_Section_Base
475
+	 */
476
+	public function find_section_from_path($form_section_path)
477
+	{
478
+		if (strpos($form_section_path, '/') === 0) {
479
+			$form_section_path = substr($form_section_path, strlen('/'));
480
+		}
481
+		if (empty($form_section_path)) {
482
+			return $this;
483
+		}
484
+		if (strpos($form_section_path, '../') === 0) {
485
+			$parent = $this->parent_section();
486
+			$form_section_path = substr($form_section_path, strlen('../'));
487
+			if ($parent instanceof EE_Form_Section_Base) {
488
+				return $parent->find_section_from_path($form_section_path);
489
+			} elseif (empty($form_section_path)) {
490
+				return $this;
491
+			}
492
+		}
493
+		//couldn't find it using simple parent following
494
+		return null;
495
+	}
496 496
 
497 497
 
498 498
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 use EventEspresso\core\libraries\form_sections\strategies\filter\FormHtmlFilter;
3 3
 
4
-if (! defined('EVENT_ESPRESSO_VERSION')) {
4
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
5 5
     exit('No direct script access allowed');
6 6
 }
7 7
 
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
         // used by display strategies
100 100
         // assign incoming values to properties
101 101
         foreach ($options_array as $key => $value) {
102
-            $key = '_' . $key;
102
+            $key = '_'.$key;
103 103
             if (property_exists($this, $key) && empty($this->{$key})) {
104 104
                 $this->{$key} = $value;
105 105
             }
@@ -136,7 +136,7 @@  discard block
 block discarded – undo
136 136
      */
137 137
     public function ensure_construct_finalized_called()
138 138
     {
139
-        if (! $this->_construction_finalized) {
139
+        if ( ! $this->_construction_finalized) {
140 140
             $this->_construct_finalize($this->_parent_section, $this->_name);
141 141
         }
142 142
     }
@@ -199,7 +199,7 @@  discard block
 block discarded – undo
199 199
      */
200 200
     protected function _set_default_html_id_if_empty()
201 201
     {
202
-        if (! $this->_html_id) {
202
+        if ( ! $this->_html_id) {
203 203
             if ($this->_parent_section && $this->_parent_section instanceof EE_Form_Section_Proper) {
204 204
                 $this->_html_id = $this->_parent_section->html_id()
205 205
                                   . '-'
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
     public function html_id($add_pound_sign = false)
259 259
     {
260 260
         $this->_set_default_html_id_if_empty();
261
-        return $add_pound_sign ? '#' . $this->_html_id : $this->_html_id;
261
+        return $add_pound_sign ? '#'.$this->_html_id : $this->_html_id;
262 262
     }
263 263
 
264 264
 
@@ -341,7 +341,7 @@  discard block
 block discarded – undo
341 341
      */
342 342
     public function name()
343 343
     {
344
-        if (! $this->_construction_finalized) {
344
+        if ( ! $this->_construction_finalized) {
345 345
             throw new EE_Error(sprintf(__('You cannot use the form section\s name until _construct_finalize has been called on it (when we set the name). It was called on a form section of type \'s\'',
346 346
                 'event_espresso'), get_class($this)));
347 347
         }
@@ -372,17 +372,17 @@  discard block
 block discarded – undo
372 372
      */
373 373
     public function form_open($action = '', $method = '', $other_attributes = '')
374 374
     {
375
-        if (! empty($action)) {
375
+        if ( ! empty($action)) {
376 376
             $this->set_action($action);
377 377
         }
378
-        if (! empty($method)) {
378
+        if ( ! empty($method)) {
379 379
             $this->set_method($method);
380 380
         }
381
-        $html = EEH_HTML::nl(1, 'form') . '<form';
382
-        $html .= $this->html_id() !== '' ? ' id="' . $this->get_html_id_for_form($this->html_id()) . '"' : '';
383
-        $html .= ' action="' . $this->action() . '"';
384
-        $html .= ' method="' . $this->method() . '"';
385
-        $html .= $other_attributes . '>';
381
+        $html = EEH_HTML::nl(1, 'form').'<form';
382
+        $html .= $this->html_id() !== '' ? ' id="'.$this->get_html_id_for_form($this->html_id()).'"' : '';
383
+        $html .= ' action="'.$this->action().'"';
384
+        $html .= ' method="'.$this->method().'"';
385
+        $html .= $other_attributes.'>';
386 386
         return $html;
387 387
     }
388 388
 
@@ -398,9 +398,9 @@  discard block
 block discarded – undo
398 398
     protected function get_html_id_for_form($html_id)
399 399
     {
400 400
         $strlen = strlen($html_id);
401
-        $html_id = strpos($html_id, '-form') === $strlen-5 || strpos($html_id, '-frm') === $strlen - 4
401
+        $html_id = strpos($html_id, '-form') === $strlen - 5 || strpos($html_id, '-frm') === $strlen - 4
402 402
             ? $html_id
403
-            : $html_id . '-frm';
403
+            : $html_id.'-frm';
404 404
         return $html_id;
405 405
     }
406 406
 
Please login to merge, or discard this patch.
core/db_classes/EE_Base_Class.class.php 3 patches
Doc Comments   +10 added lines, -9 removed lines patch added patch discarded remove patch
@@ -609,7 +609,7 @@  discard block
 block discarded – undo
609 609
      *
610 610
      * @param \EE_Datetime_Field $datetime_field
611 611
      * @param bool               $pretty
612
-     * @param null $date_or_time
612
+     * @param string|null $date_or_time
613 613
      * @return void
614 614
      * @throws \EE_Error
615 615
      */
@@ -946,7 +946,7 @@  discard block
 block discarded – undo
946 946
      *
947 947
      * @param null  $field_to_order_by  What field is being used as the reference point.
948 948
      * @param array $query_params       Any additional conditions on the query.
949
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
949
+     * @param string  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
950 950
      *                                  you can indicate just the columns you want returned
951 951
      * @return array|EE_Base_Class
952 952
      * @throws \EE_Error
@@ -971,7 +971,7 @@  discard block
 block discarded – undo
971 971
      *
972 972
      * @param null  $field_to_order_by  What field is being used as the reference point.
973 973
      * @param array $query_params       Any additional conditions on the query.
974
-     * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
974
+     * @param string  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
975 975
      *                                  you can indicate just the column you want returned
976 976
      * @return array|EE_Base_Class
977 977
      * @throws \EE_Error
@@ -1044,7 +1044,7 @@  discard block
 block discarded – undo
1044 1044
      * This method simply returns the RAW unprocessed value for the given property in this class
1045 1045
      *
1046 1046
      * @param  string $field_name A valid fieldname
1047
-     * @return mixed              Whatever the raw value stored on the property is.
1047
+     * @return integer|null              Whatever the raw value stored on the property is.
1048 1048
      * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1049 1049
      */
1050 1050
     public function get_raw($field_name)
@@ -1321,7 +1321,7 @@  discard block
 block discarded – undo
1321 1321
      * sets the time on a datetime property
1322 1322
      *
1323 1323
      * @access protected
1324
-     * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1324
+     * @param string $time      a valid time string for php datetime functions (or DateTime object)
1325 1325
      * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1326 1326
      * @throws \EE_Error
1327 1327
      */
@@ -1336,7 +1336,7 @@  discard block
 block discarded – undo
1336 1336
      * sets the date on a datetime property
1337 1337
      *
1338 1338
      * @access protected
1339
-     * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1339
+     * @param string $date      a valid date string for php datetime functions ( or DateTime object)
1340 1340
      * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1341 1341
      * @throws \EE_Error
1342 1342
      */
@@ -1399,6 +1399,7 @@  discard block
 block discarded – undo
1399 1399
      * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1400 1400
      * @param string               $prepend    You can include something to prepend on the timestamp
1401 1401
      * @param string               $append     You can include something to append on the timestamp
1402
+     * @param string $args
1402 1403
      * @throws EE_Error
1403 1404
      * @return string timestamp
1404 1405
      */
@@ -1790,7 +1791,7 @@  discard block
 block discarded – undo
1790 1791
      *
1791 1792
      * @param  array  $props_n_values   incoming array of properties and their values
1792 1793
      * @param  string $classname        the classname of the child class
1793
-     * @param null    $timezone
1794
+     * @param string|null    $timezone
1794 1795
      * @param array   $date_formats     incoming date_formats in an array where the first value is the
1795 1796
      *                                  date_format and the second value is the time format
1796 1797
      * @return mixed (EE_Base_Class|bool)
@@ -1868,7 +1869,7 @@  discard block
 block discarded – undo
1868 1869
      * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1869 1870
      *
1870 1871
      * @param string $model_classname
1871
-     * @param null   $timezone
1872
+     * @param string|null   $timezone
1872 1873
      * @return EEM_Base
1873 1874
      */
1874 1875
     protected static function _get_model_instance_with_name($model_classname, $timezone = null)
@@ -2367,7 +2368,7 @@  discard block
 block discarded – undo
2367 2368
      *
2368 2369
      * @param string $meta_key
2369 2370
      * @param mixed  $meta_value
2370
-     * @param mixed  $previous_value
2371
+     * @param boolean  $previous_value
2371 2372
      * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2372 2373
      * @throws \EE_Error
2373 2374
      * NOTE: if the values haven't changed, returns 0
Please login to merge, or discard this patch.
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -150,8 +150,8 @@  discard block
 block discarded – undo
150 150
             list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
151 151
         } else {
152 152
             //set default formats for date and time
153
-            $this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
154
-            $this->_tm_frmt = (string)get_option('time_format', 'g:i a');
153
+            $this->_dt_frmt = (string) get_option('date_format', 'Y-m-d');
154
+            $this->_tm_frmt = (string) get_option('time_format', 'g:i a');
155 155
         }
156 156
         //if db model is instantiating
157 157
         if ($bydb) {
@@ -472,7 +472,7 @@  discard block
 block discarded – undo
472 472
      */
473 473
     public function get_format($full = true)
474 474
     {
475
-        return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
475
+        return $full ? $this->_dt_frmt.' '.$this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
476 476
     }
477 477
 
478 478
 
@@ -580,7 +580,7 @@  discard block
 block discarded – undo
580 580
         //verify the field exists
581 581
         $this->get_model()->field_settings_for($fieldname);
582 582
         $cache_type = $pretty ? 'pretty' : 'standard';
583
-        $cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
583
+        $cache_type .= ! empty($extra_cache_ref) ? '_'.$extra_cache_ref : '';
584 584
         if (isset($this->_cached_properties[$fieldname][$cache_type])) {
585 585
             return $this->_cached_properties[$fieldname][$cache_type];
586 586
         }
@@ -795,7 +795,7 @@  discard block
 block discarded – undo
795 795
         $current_cache_id = ''
796 796
     ) {
797 797
         // verify that incoming object is of the correct type
798
-        $obj_class = 'EE_' . $relationName;
798
+        $obj_class = 'EE_'.$relationName;
799 799
         if ($newly_saved_object instanceof $obj_class) {
800 800
             /* @type EE_Base_Class $newly_saved_object */
801 801
             // now get the type of relation
@@ -1277,7 +1277,7 @@  discard block
 block discarded – undo
1277 1277
      */
1278 1278
     public function get_i18n_datetime($field_name, $format = '')
1279 1279
     {
1280
-        $format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1280
+        $format = empty($format) ? $this->_dt_frmt.' '.$this->_tm_frmt : $format;
1281 1281
         return date_i18n(
1282 1282
             $format,
1283 1283
             EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
@@ -1415,8 +1415,8 @@  discard block
 block discarded – undo
1415 1415
         }
1416 1416
         $original_timezone = $this->_timezone;
1417 1417
         $this->set_timezone($timezone);
1418
-        $fn = (array)$field_name;
1419
-        $args = array_merge($fn, (array)$args);
1418
+        $fn = (array) $field_name;
1419
+        $args = array_merge($fn, (array) $args);
1420 1420
         if ( ! method_exists($this, $callback)) {
1421 1421
             throw new EE_Error(
1422 1422
                 sprintf(
@@ -1428,8 +1428,8 @@  discard block
 block discarded – undo
1428 1428
                 )
1429 1429
             );
1430 1430
         }
1431
-        $args = (array)$args;
1432
-        $return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1431
+        $args = (array) $args;
1432
+        $return = $prepend.call_user_func_array(array($this, $callback), $args).$append;
1433 1433
         $this->set_timezone($original_timezone);
1434 1434
         return $return;
1435 1435
     }
@@ -1566,14 +1566,14 @@  discard block
 block discarded – undo
1566 1566
          * @param array         $set_cols_n_values
1567 1567
          * @param EE_Base_Class $model_object
1568 1568
          */
1569
-        $set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1569
+        $set_cols_n_values = (array) apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1570 1570
             $this);
1571 1571
         //set attributes as provided in $set_cols_n_values
1572 1572
         foreach ($set_cols_n_values as $column => $value) {
1573 1573
             $this->set($column, $value);
1574 1574
         }
1575 1575
         // no changes ? then don't do anything
1576
-        if (! $this->_has_changes && $this->ID() && $this->get_model()->get_primary_key_field()->is_auto_increment()) {
1576
+        if ( ! $this->_has_changes && $this->ID() && $this->get_model()->get_primary_key_field()->is_auto_increment()) {
1577 1577
             return 0;
1578 1578
         }
1579 1579
         /**
@@ -1625,8 +1625,8 @@  discard block
 block discarded – undo
1625 1625
                                 __('Using a model object %1$s that is NOT in the entity map, can lead to unexpected errors. You should either: %4$s 1. Put it in the entity mapper by calling %2$s %4$s 2. Discard this model object and use what is in the entity mapper %4$s 3. Fetch from the database using %3$s',
1626 1626
                                     'event_espresso'),
1627 1627
                                 get_class($this),
1628
-                                get_class($this->get_model()) . '::instance()->add_to_entity_map()',
1629
-                                get_class($this->get_model()) . '::instance()->get_one_by_ID()',
1628
+                                get_class($this->get_model()).'::instance()->add_to_entity_map()',
1629
+                                get_class($this->get_model()).'::instance()->get_one_by_ID()',
1630 1630
                                 '<br />'
1631 1631
                             )
1632 1632
                         );
@@ -1894,7 +1894,7 @@  discard block
 block discarded – undo
1894 1894
         if (strpos($model_name, "EE_") === 0) {
1895 1895
             $model_classname = str_replace("EE_", "EEM_", $model_name);
1896 1896
         } else {
1897
-            $model_classname = "EEM_" . $model_name;
1897
+            $model_classname = "EEM_".$model_name;
1898 1898
         }
1899 1899
         return $model_classname;
1900 1900
     }
@@ -2278,7 +2278,7 @@  discard block
 block discarded – undo
2278 2278
      */
2279 2279
     protected function _property_exists($properties)
2280 2280
     {
2281
-        foreach ((array)$properties as $property_name) {
2281
+        foreach ((array) $properties as $property_name) {
2282 2282
             //first make sure this property exists
2283 2283
             if ( ! $this->_fields[$property_name]) {
2284 2284
                 throw new EE_Error(
@@ -2608,8 +2608,8 @@  discard block
 block discarded – undo
2608 2608
                         __('Trying to refresh a model object with ID "%1$s" that\'s not in the entity map? First off: you should put it in the entity map by calling %2$s. Second off, if you want what\'s in the database right now, you should just call %3$s yourself and discard this model object.',
2609 2609
                             'event_espresso'),
2610 2610
                         $this->ID(),
2611
-                        get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2612
-                        get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2611
+                        get_class($this->get_model()).'::instance()->add_to_entity_map()',
2612
+                        get_class($this->get_model()).'::instance()->refresh_entity_map()'
2613 2613
                     )
2614 2614
                 );
2615 2615
             }
@@ -2668,7 +2668,7 @@  discard block
 block discarded – undo
2668 2668
     {
2669 2669
         foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
2670 2670
             if ($relation_obj instanceof EE_Belongs_To_Relation) {
2671
-                $classname = 'EE_' . $this->get_model()->get_this_model_name();
2671
+                $classname = 'EE_'.$this->get_model()->get_this_model_name();
2672 2672
                 if (
2673 2673
                     $this->get_one_from_cache($relation_name) instanceof $classname
2674 2674
                     && $this->get_one_from_cache($relation_name)->ID()
Please login to merge, or discard this patch.
Indentation   +2681 added lines, -2681 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 do_action('AHEE_log', __FILE__, ' FILE LOADED', '');
5 5
 
@@ -25,2686 +25,2686 @@  discard block
 block discarded – undo
25 25
 abstract class EE_Base_Class
26 26
 {
27 27
 
28
-    /**
29
-     * This is an array of the original properties and values provided during construction
30
-     * of this model object. (keys are model field names, values are their values).
31
-     * This list is important to remember so that when we are merging data from the db, we know
32
-     * which values to override and which to not override.
33
-     *
34
-     * @var array
35
-     */
36
-    protected $_props_n_values_provided_in_constructor;
37
-
38
-    /**
39
-     * Timezone
40
-     * This gets set by the "set_timezone()" method so that we know what timezone incoming strings|timestamps are in.
41
-     * This can also be used before a get to set what timezone you want strings coming out of the object to be in.  NOT
42
-     * all EE_Base_Class child classes use this property but any that use a EE_Datetime_Field data type will have
43
-     * access to it.
44
-     *
45
-     * @var string
46
-     */
47
-    protected $_timezone;
48
-
49
-
50
-
51
-    /**
52
-     * date format
53
-     * pattern or format for displaying dates
54
-     *
55
-     * @var string $_dt_frmt
56
-     */
57
-    protected $_dt_frmt;
58
-
59
-
60
-
61
-    /**
62
-     * time format
63
-     * pattern or format for displaying time
64
-     *
65
-     * @var string $_tm_frmt
66
-     */
67
-    protected $_tm_frmt;
68
-
69
-
70
-
71
-    /**
72
-     * This property is for holding a cached array of object properties indexed by property name as the key.
73
-     * The purpose of this is for setting a cache on properties that may have calculated values after a
74
-     * prepare_for_get.  That way the cache can be checked first and the calculated property returned instead of having
75
-     * to recalculate. Used by _set_cached_property() and _get_cached_property() methods.
76
-     *
77
-     * @var array
78
-     */
79
-    protected $_cached_properties = array();
80
-
81
-    /**
82
-     * An array containing keys of the related model, and values are either an array of related mode objects or a
83
-     * single
84
-     * related model object. see the model's _model_relations. The keys should match those specified. And if the
85
-     * relation is of type EE_Belongs_To (or one of its children), then there should only be ONE related model object,
86
-     * all others have an array)
87
-     *
88
-     * @var array
89
-     */
90
-    protected $_model_relations = array();
91
-
92
-    /**
93
-     * Array where keys are field names (see the model's _fields property) and values are their values. To see what
94
-     * their types should be, look at what that field object returns on its prepare_for_get and prepare_for_set methods)
95
-     *
96
-     * @var array
97
-     */
98
-    protected $_fields = array();
99
-
100
-    /**
101
-     * @var boolean indicating whether or not this model object is intended to ever be saved
102
-     * For example, we might create model objects intended to only be used for the duration
103
-     * of this request and to be thrown away, and if they were accidentally saved
104
-     * it would be a bug.
105
-     */
106
-    protected $_allow_persist = true;
107
-
108
-    /**
109
-     * @var boolean indicating whether or not this model object's properties have changed since construction
110
-     */
111
-    protected $_has_changes = false;
112
-
113
-
114
-
115
-    /**
116
-     * basic constructor for Event Espresso classes, performs any necessary initialization, and verifies it's children
117
-     * play nice
118
-     *
119
-     * @param array   $fieldValues                             where each key is a field (ie, array key in the 2nd
120
-     *                                                         layer of the model's _fields array, (eg, EVT_ID,
121
-     *                                                         TXN_amount, QST_name, etc) and values are their values
122
-     * @param boolean $bydb                                    a flag for setting if the class is instantiated by the
123
-     *                                                         corresponding db model or not.
124
-     * @param string  $timezone                                indicate what timezone you want any datetime fields to
125
-     *                                                         be in when instantiating a EE_Base_Class object.
126
-     * @param array   $date_formats                            An array of date formats to set on construct where first
127
-     *                                                         value is the date_format and second value is the time
128
-     *                                                         format.
129
-     * @throws EE_Error
130
-     */
131
-    protected function __construct($fieldValues = array(), $bydb = false, $timezone = '', $date_formats = array())
132
-    {
133
-        $className = get_class($this);
134
-        do_action("AHEE__{$className}__construct", $this, $fieldValues);
135
-        $model = $this->get_model();
136
-        $model_fields = $model->field_settings(false);
137
-        // ensure $fieldValues is an array
138
-        $fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
139
-        // EEH_Debug_Tools::printr( $fieldValues, '$fieldValues  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
140
-        // verify client code has not passed any invalid field names
141
-        foreach ($fieldValues as $field_name => $field_value) {
142
-            if ( ! isset($model_fields[$field_name])) {
143
-                throw new EE_Error(sprintf(__("Invalid field (%s) passed to constructor of %s. Allowed fields are :%s",
144
-                    "event_espresso"), $field_name, get_class($this), implode(", ", array_keys($model_fields))));
145
-            }
146
-        }
147
-        // EEH_Debug_Tools::printr( $model_fields, '$model_fields  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
148
-        $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
149
-        if ( ! empty($date_formats) && is_array($date_formats)) {
150
-            list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
151
-        } else {
152
-            //set default formats for date and time
153
-            $this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
154
-            $this->_tm_frmt = (string)get_option('time_format', 'g:i a');
155
-        }
156
-        //if db model is instantiating
157
-        if ($bydb) {
158
-            //client code has indicated these field values are from the database
159
-            foreach ($model_fields as $fieldName => $field) {
160
-                $this->set_from_db($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null);
161
-            }
162
-        } else {
163
-            //we're constructing a brand
164
-            //new instance of the model object. Generally, this means we'll need to do more field validation
165
-            foreach ($model_fields as $fieldName => $field) {
166
-                $this->set($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null, true);
167
-            }
168
-        }
169
-        //remember what values were passed to this constructor
170
-        $this->_props_n_values_provided_in_constructor = $fieldValues;
171
-        //remember in entity mapper
172
-        if ( ! $bydb && $model->has_primary_key_field() && $this->ID()) {
173
-            $model->add_to_entity_map($this);
174
-        }
175
-        //setup all the relations
176
-        foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
177
-            if ($relation_obj instanceof EE_Belongs_To_Relation) {
178
-                $this->_model_relations[$relation_name] = null;
179
-            } else {
180
-                $this->_model_relations[$relation_name] = array();
181
-            }
182
-        }
183
-        /**
184
-         * Action done at the end of each model object construction
185
-         *
186
-         * @param EE_Base_Class $this the model object just created
187
-         */
188
-        do_action('AHEE__EE_Base_Class__construct__finished', $this);
189
-    }
190
-
191
-
192
-
193
-    /**
194
-     * Gets whether or not this model object is allowed to persist/be saved to the database.
195
-     *
196
-     * @return boolean
197
-     */
198
-    public function allow_persist()
199
-    {
200
-        return $this->_allow_persist;
201
-    }
202
-
203
-
204
-
205
-    /**
206
-     * Sets whether or not this model object should be allowed to be saved to the DB.
207
-     * Normally once this is set to FALSE you wouldn't set it back to TRUE, unless
208
-     * you got new information that somehow made you change your mind.
209
-     *
210
-     * @param boolean $allow_persist
211
-     * @return boolean
212
-     */
213
-    public function set_allow_persist($allow_persist)
214
-    {
215
-        return $this->_allow_persist = $allow_persist;
216
-    }
217
-
218
-
219
-
220
-    /**
221
-     * Gets the field's original value when this object was constructed during this request.
222
-     * This can be helpful when determining if a model object has changed or not
223
-     *
224
-     * @param string $field_name
225
-     * @return mixed|null
226
-     * @throws \EE_Error
227
-     */
228
-    public function get_original($field_name)
229
-    {
230
-        if (isset($this->_props_n_values_provided_in_constructor[$field_name])
231
-            && $field_settings = $this->get_model()->field_settings_for($field_name)
232
-        ) {
233
-            return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[$field_name]);
234
-        } else {
235
-            return null;
236
-        }
237
-    }
238
-
239
-
240
-
241
-    /**
242
-     * @param EE_Base_Class $obj
243
-     * @return string
244
-     */
245
-    public function get_class($obj)
246
-    {
247
-        return get_class($obj);
248
-    }
249
-
250
-
251
-
252
-    /**
253
-     * Overrides parent because parent expects old models.
254
-     * This also doesn't do any validation, and won't work for serialized arrays
255
-     *
256
-     * @param    string $field_name
257
-     * @param    mixed  $field_value
258
-     * @param bool      $use_default
259
-     * @throws \EE_Error
260
-     */
261
-    public function set($field_name, $field_value, $use_default = false)
262
-    {
263
-        // if not using default and nothing has changed, and object has already been setup (has ID),
264
-        // then don't do anything
265
-        if (
266
-            ! $use_default
267
-            && $this->_fields[$field_name] === $field_value
268
-            && $this->ID()
269
-        ) {
270
-            return;
271
-        }
272
-        $this->_has_changes = true;
273
-        $field_obj = $this->get_model()->field_settings_for($field_name);
274
-        if ($field_obj instanceof EE_Model_Field_Base) {
275
-            //			if ( method_exists( $field_obj, 'set_timezone' )) {
276
-            if ($field_obj instanceof EE_Datetime_Field) {
277
-                $field_obj->set_timezone($this->_timezone);
278
-                $field_obj->set_date_format($this->_dt_frmt);
279
-                $field_obj->set_time_format($this->_tm_frmt);
280
-            }
281
-            $holder_of_value = $field_obj->prepare_for_set($field_value);
282
-            //should the value be null?
283
-            if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
284
-                $this->_fields[$field_name] = $field_obj->get_default_value();
285
-                /**
286
-                 * To save having to refactor all the models, if a default value is used for a
287
-                 * EE_Datetime_Field, and that value is not null nor is it a DateTime
288
-                 * object.  Then let's do a set again to ensure that it becomes a DateTime
289
-                 * object.
290
-                 *
291
-                 * @since 4.6.10+
292
-                 */
293
-                if (
294
-                    $field_obj instanceof EE_Datetime_Field
295
-                    && $this->_fields[$field_name] !== null
296
-                    && ! $this->_fields[$field_name] instanceof DateTime
297
-                ) {
298
-                    empty($this->_fields[$field_name])
299
-                        ? $this->set($field_name, time())
300
-                        : $this->set($field_name, $this->_fields[$field_name]);
301
-                }
302
-            } else {
303
-                $this->_fields[$field_name] = $holder_of_value;
304
-            }
305
-            //if we're not in the constructor...
306
-            //now check if what we set was a primary key
307
-            if (
308
-                //note: props_n_values_provided_in_constructor is only set at the END of the constructor
309
-                $this->_props_n_values_provided_in_constructor
310
-                && $field_value
311
-                && $field_name === self::_get_primary_key_name(get_class($this))
312
-            ) {
313
-                //if so, we want all this object's fields to be filled either with
314
-                //what we've explicitly set on this model
315
-                //or what we have in the db
316
-                // echo "setting primary key!";
317
-                $fields_on_model = self::_get_model(get_class($this))->field_settings();
318
-                $obj_in_db = self::_get_model(get_class($this))->get_one_by_ID($field_value);
319
-                foreach ($fields_on_model as $field_obj) {
320
-                    if ( ! array_key_exists($field_obj->get_name(), $this->_props_n_values_provided_in_constructor)
321
-                         && $field_obj->get_name() !== $field_name
322
-                    ) {
323
-                        $this->set($field_obj->get_name(), $obj_in_db->get($field_obj->get_name()));
324
-                    }
325
-                }
326
-                //oh this model object has an ID? well make sure its in the entity mapper
327
-                $this->get_model()->add_to_entity_map($this);
328
-            }
329
-            //let's unset any cache for this field_name from the $_cached_properties property.
330
-            $this->_clear_cached_property($field_name);
331
-        } else {
332
-            throw new EE_Error(sprintf(__("A valid EE_Model_Field_Base could not be found for the given field name: %s",
333
-                "event_espresso"), $field_name));
334
-        }
335
-    }
336
-
337
-
338
-
339
-    /**
340
-     * This sets the field value on the db column if it exists for the given $column_name or
341
-     * saves it to EE_Extra_Meta if the given $column_name does not match a db column.
342
-     *
343
-     * @see EE_message::get_column_value for related documentation on the necessity of this method.
344
-     * @param string $field_name  Must be the exact column name.
345
-     * @param mixed  $field_value The value to set.
346
-     * @return int|bool @see EE_Base_Class::update_extra_meta() for return docs.
347
-     * @throws \EE_Error
348
-     */
349
-    public function set_field_or_extra_meta($field_name, $field_value)
350
-    {
351
-        if ($this->get_model()->has_field($field_name)) {
352
-            $this->set($field_name, $field_value);
353
-            return true;
354
-        } else {
355
-            //ensure this object is saved first so that extra meta can be properly related.
356
-            $this->save();
357
-            return $this->update_extra_meta($field_name, $field_value);
358
-        }
359
-    }
360
-
361
-
362
-
363
-    /**
364
-     * This retrieves the value of the db column set on this class or if that's not present
365
-     * it will attempt to retrieve from extra_meta if found.
366
-     * Example Usage:
367
-     * Via EE_Message child class:
368
-     * Due to the dynamic nature of the EE_messages system, EE_messengers will always have a "to",
369
-     * "from", "subject", and "content" field (as represented in the EE_Message schema), however they may
370
-     * also have additional main fields specific to the messenger.  The system accommodates those extra
371
-     * fields through the EE_Extra_Meta table.  This method allows for EE_messengers to retrieve the
372
-     * value for those extra fields dynamically via the EE_message object.
373
-     *
374
-     * @param  string $field_name expecting the fully qualified field name.
375
-     * @return mixed|null  value for the field if found.  null if not found.
376
-     * @throws \EE_Error
377
-     */
378
-    public function get_field_or_extra_meta($field_name)
379
-    {
380
-        if ($this->get_model()->has_field($field_name)) {
381
-            $column_value = $this->get($field_name);
382
-        } else {
383
-            //This isn't a column in the main table, let's see if it is in the extra meta.
384
-            $column_value = $this->get_extra_meta($field_name, true, null);
385
-        }
386
-        return $column_value;
387
-    }
388
-
389
-
390
-
391
-    /**
392
-     * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
393
-     * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
394
-     * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
395
-     * available to all child classes that may be using the EE_Datetime_Field for a field data type.
396
-     *
397
-     * @access public
398
-     * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
399
-     * @return void
400
-     * @throws \EE_Error
401
-     */
402
-    public function set_timezone($timezone = '')
403
-    {
404
-        $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
405
-        //make sure we clear all cached properties because they won't be relevant now
406
-        $this->_clear_cached_properties();
407
-        //make sure we update field settings and the date for all EE_Datetime_Fields
408
-        $model_fields = $this->get_model()->field_settings(false);
409
-        foreach ($model_fields as $field_name => $field_obj) {
410
-            if ($field_obj instanceof EE_Datetime_Field) {
411
-                $field_obj->set_timezone($this->_timezone);
412
-                if (isset($this->_fields[$field_name]) && $this->_fields[$field_name] instanceof DateTime) {
413
-                    $this->_fields[$field_name]->setTimezone(new DateTimeZone($this->_timezone));
414
-                }
415
-            }
416
-        }
417
-    }
418
-
419
-
420
-
421
-    /**
422
-     * This just returns whatever is set for the current timezone.
423
-     *
424
-     * @access public
425
-     * @return string timezone string
426
-     */
427
-    public function get_timezone()
428
-    {
429
-        return $this->_timezone;
430
-    }
431
-
432
-
433
-
434
-    /**
435
-     * This sets the internal date format to what is sent in to be used as the new default for the class
436
-     * internally instead of wp set date format options
437
-     *
438
-     * @since 4.6
439
-     * @param string $format should be a format recognizable by PHP date() functions.
440
-     */
441
-    public function set_date_format($format)
442
-    {
443
-        $this->_dt_frmt = $format;
444
-        //clear cached_properties because they won't be relevant now.
445
-        $this->_clear_cached_properties();
446
-    }
447
-
448
-
449
-
450
-    /**
451
-     * This sets the internal time format string to what is sent in to be used as the new default for the
452
-     * class internally instead of wp set time format options.
453
-     *
454
-     * @since 4.6
455
-     * @param string $format should be a format recognizable by PHP date() functions.
456
-     */
457
-    public function set_time_format($format)
458
-    {
459
-        $this->_tm_frmt = $format;
460
-        //clear cached_properties because they won't be relevant now.
461
-        $this->_clear_cached_properties();
462
-    }
463
-
464
-
465
-
466
-    /**
467
-     * This returns the current internal set format for the date and time formats.
468
-     *
469
-     * @param bool $full           if true (default), then return the full format.  Otherwise will return an array
470
-     *                             where the first value is the date format and the second value is the time format.
471
-     * @return mixed string|array
472
-     */
473
-    public function get_format($full = true)
474
-    {
475
-        return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
476
-    }
477
-
478
-
479
-
480
-    /**
481
-     * cache
482
-     * stores the passed model object on the current model object.
483
-     * In certain circumstances, we can use this cached model object instead of querying for another one entirely.
484
-     *
485
-     * @param string        $relationName    one of the keys in the _model_relations array on the model. Eg
486
-     *                                       'Registration' associated with this model object
487
-     * @param EE_Base_Class $object_to_cache that has a relation to this model object. (Eg, if this is a Transaction,
488
-     *                                       that could be a payment or a registration)
489
-     * @param null          $cache_id        a string or number that will be used as the key for any Belongs_To_Many
490
-     *                                       items which will be stored in an array on this object
491
-     * @throws EE_Error
492
-     * @return mixed    index into cache, or just TRUE if the relation is of type Belongs_To (because there's only one
493
-     *                  related thing, no array)
494
-     */
495
-    public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
496
-    {
497
-        // its entirely possible that there IS no related object yet in which case there is nothing to cache.
498
-        if ( ! $object_to_cache instanceof EE_Base_Class) {
499
-            return false;
500
-        }
501
-        // also get "how" the object is related, or throw an error
502
-        if ( ! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
503
-            throw new EE_Error(sprintf(__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
504
-                $relationName, get_class($this)));
505
-        }
506
-        // how many things are related ?
507
-        if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
508
-            // if it's a "belongs to" relationship, then there's only one related model object  eg, if this is a registration, there's only 1 attendee for it
509
-            // so for these model objects just set it to be cached
510
-            $this->_model_relations[$relationName] = $object_to_cache;
511
-            $return = true;
512
-        } else {
513
-            // otherwise, this is the "many" side of a one to many relationship, so we'll add the object to the array of related objects for that type.
514
-            // eg: if this is an event, there are many registrations for that event, so we cache the registrations in an array
515
-            if ( ! is_array($this->_model_relations[$relationName])) {
516
-                // if for some reason, the cached item is a model object, then stick that in the array, otherwise start with an empty array
517
-                $this->_model_relations[$relationName] = $this->_model_relations[$relationName] instanceof EE_Base_Class
518
-                    ? array($this->_model_relations[$relationName]) : array();
519
-            }
520
-            // first check for a cache_id which is normally empty
521
-            if ( ! empty($cache_id)) {
522
-                // if the cache_id exists, then it means we are purposely trying to cache this with a known key that can then be used to retrieve the object later on
523
-                $this->_model_relations[$relationName][$cache_id] = $object_to_cache;
524
-                $return = $cache_id;
525
-            } elseif ($object_to_cache->ID()) {
526
-                // OR the cached object originally came from the db, so let's just use it's PK for an ID
527
-                $this->_model_relations[$relationName][$object_to_cache->ID()] = $object_to_cache;
528
-                $return = $object_to_cache->ID();
529
-            } else {
530
-                // OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
531
-                $this->_model_relations[$relationName][] = $object_to_cache;
532
-                // move the internal pointer to the end of the array
533
-                end($this->_model_relations[$relationName]);
534
-                // and grab the key so that we can return it
535
-                $return = key($this->_model_relations[$relationName]);
536
-            }
537
-        }
538
-        return $return;
539
-    }
540
-
541
-
542
-
543
-    /**
544
-     * For adding an item to the cached_properties property.
545
-     *
546
-     * @access protected
547
-     * @param string      $fieldname the property item the corresponding value is for.
548
-     * @param mixed       $value     The value we are caching.
549
-     * @param string|null $cache_type
550
-     * @return void
551
-     * @throws \EE_Error
552
-     */
553
-    protected function _set_cached_property($fieldname, $value, $cache_type = null)
554
-    {
555
-        //first make sure this property exists
556
-        $this->get_model()->field_settings_for($fieldname);
557
-        $cache_type = empty($cache_type) ? 'standard' : $cache_type;
558
-        $this->_cached_properties[$fieldname][$cache_type] = $value;
559
-    }
560
-
561
-
562
-
563
-    /**
564
-     * This returns the value cached property if it exists OR the actual property value if the cache doesn't exist.
565
-     * This also SETS the cache if we return the actual property!
566
-     *
567
-     * @param string $fieldname        the name of the property we're trying to retrieve
568
-     * @param bool   $pretty
569
-     * @param string $extra_cache_ref  This allows the user to specify an extra cache ref for the given property
570
-     *                                 (in cases where the same property may be used for different outputs
571
-     *                                 - i.e. datetime, money etc.)
572
-     *                                 It can also accept certain pre-defined "schema" strings
573
-     *                                 to define how to output the property.
574
-     *                                 see the field's prepare_for_pretty_echoing for what strings can be used
575
-     * @return mixed                   whatever the value for the property is we're retrieving
576
-     * @throws \EE_Error
577
-     */
578
-    protected function _get_cached_property($fieldname, $pretty = false, $extra_cache_ref = null)
579
-    {
580
-        //verify the field exists
581
-        $this->get_model()->field_settings_for($fieldname);
582
-        $cache_type = $pretty ? 'pretty' : 'standard';
583
-        $cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
584
-        if (isset($this->_cached_properties[$fieldname][$cache_type])) {
585
-            return $this->_cached_properties[$fieldname][$cache_type];
586
-        }
587
-        $value = $this->_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
588
-        $this->_set_cached_property($fieldname, $value, $cache_type);
589
-        return $value;
590
-    }
591
-
592
-
593
-
594
-    /**
595
-     * If the cache didn't fetch the needed item, this fetches it.
596
-     * @param string $fieldname
597
-     * @param bool $pretty
598
-     * @param string $extra_cache_ref
599
-     * @return mixed
600
-     */
601
-    protected function _get_fresh_property($fieldname, $pretty = false, $extra_cache_ref = null)
602
-    {
603
-        $field_obj = $this->get_model()->field_settings_for($fieldname);
604
-        // If this is an EE_Datetime_Field we need to make sure timezone, formats, and output are correct
605
-        if ($field_obj instanceof EE_Datetime_Field) {
606
-            $this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
607
-        }
608
-        if ( ! isset($this->_fields[$fieldname])) {
609
-            $this->_fields[$fieldname] = null;
610
-        }
611
-        $value = $pretty
612
-            ? $field_obj->prepare_for_pretty_echoing($this->_fields[$fieldname], $extra_cache_ref)
613
-            : $field_obj->prepare_for_get($this->_fields[$fieldname]);
614
-        return $value;
615
-    }
616
-
617
-
618
-
619
-    /**
620
-     * set timezone, formats, and output for EE_Datetime_Field objects
621
-     *
622
-     * @param \EE_Datetime_Field $datetime_field
623
-     * @param bool               $pretty
624
-     * @param null $date_or_time
625
-     * @return void
626
-     * @throws \EE_Error
627
-     */
628
-    protected function _prepare_datetime_field(
629
-        EE_Datetime_Field $datetime_field,
630
-        $pretty = false,
631
-        $date_or_time = null
632
-    ) {
633
-        $datetime_field->set_timezone($this->_timezone);
634
-        $datetime_field->set_date_format($this->_dt_frmt, $pretty);
635
-        $datetime_field->set_time_format($this->_tm_frmt, $pretty);
636
-        //set the output returned
637
-        switch ($date_or_time) {
638
-            case 'D' :
639
-                $datetime_field->set_date_time_output('date');
640
-                break;
641
-            case 'T' :
642
-                $datetime_field->set_date_time_output('time');
643
-                break;
644
-            default :
645
-                $datetime_field->set_date_time_output();
646
-        }
647
-    }
648
-
649
-
650
-
651
-    /**
652
-     * This just takes care of clearing out the cached_properties
653
-     *
654
-     * @return void
655
-     */
656
-    protected function _clear_cached_properties()
657
-    {
658
-        $this->_cached_properties = array();
659
-    }
660
-
661
-
662
-
663
-    /**
664
-     * This just clears out ONE property if it exists in the cache
665
-     *
666
-     * @param  string $property_name the property to remove if it exists (from the _cached_properties array)
667
-     * @return void
668
-     */
669
-    protected function _clear_cached_property($property_name)
670
-    {
671
-        if (isset($this->_cached_properties[$property_name])) {
672
-            unset($this->_cached_properties[$property_name]);
673
-        }
674
-    }
675
-
676
-
677
-
678
-    /**
679
-     * Ensures that this related thing is a model object.
680
-     *
681
-     * @param mixed  $object_or_id EE_base_Class/int/string either a related model object, or its ID
682
-     * @param string $model_name   name of the related thing, eg 'Attendee',
683
-     * @return EE_Base_Class
684
-     * @throws \EE_Error
685
-     */
686
-    protected function ensure_related_thing_is_model_obj($object_or_id, $model_name)
687
-    {
688
-        $other_model_instance = self::_get_model_instance_with_name(
689
-            self::_get_model_classname($model_name),
690
-            $this->_timezone
691
-        );
692
-        return $other_model_instance->ensure_is_obj($object_or_id);
693
-    }
694
-
695
-
696
-
697
-    /**
698
-     * Forgets the cached model of the given relation Name. So the next time we request it,
699
-     * we will fetch it again from the database. (Handy if you know it's changed somehow).
700
-     * If a specific object is supplied, and the relationship to it is either a HasMany or HABTM,
701
-     * then only remove that one object from our cached array. Otherwise, clear the entire list
702
-     *
703
-     * @param string $relationName                         one of the keys in the _model_relations array on the model.
704
-     *                                                     Eg 'Registration'
705
-     * @param mixed  $object_to_remove_or_index_into_array or an index into the array of cached things, or NULL
706
-     *                                                     if you intend to use $clear_all = TRUE, or the relation only
707
-     *                                                     has 1 object anyways (ie, it's a BelongsToRelation)
708
-     * @param bool   $clear_all                            This flags clearing the entire cache relation property if
709
-     *                                                     this is HasMany or HABTM.
710
-     * @throws EE_Error
711
-     * @return EE_Base_Class | boolean from which was cleared from the cache, or true if we requested to remove a
712
-     *                       relation from all
713
-     */
714
-    public function clear_cache($relationName, $object_to_remove_or_index_into_array = null, $clear_all = false)
715
-    {
716
-        $relationship_to_model = $this->get_model()->related_settings_for($relationName);
717
-        $index_in_cache = '';
718
-        if ( ! $relationship_to_model) {
719
-            throw new EE_Error(
720
-                sprintf(
721
-                    __("There is no relationship to %s on a %s. Cannot clear that cache", 'event_espresso'),
722
-                    $relationName,
723
-                    get_class($this)
724
-                )
725
-            );
726
-        }
727
-        if ($clear_all) {
728
-            $obj_removed = true;
729
-            $this->_model_relations[$relationName] = null;
730
-        } elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
731
-            $obj_removed = $this->_model_relations[$relationName];
732
-            $this->_model_relations[$relationName] = null;
733
-        } else {
734
-            if ($object_to_remove_or_index_into_array instanceof EE_Base_Class
735
-                && $object_to_remove_or_index_into_array->ID()
736
-            ) {
737
-                $index_in_cache = $object_to_remove_or_index_into_array->ID();
738
-                if (is_array($this->_model_relations[$relationName])
739
-                    && ! isset($this->_model_relations[$relationName][$index_in_cache])
740
-                ) {
741
-                    $index_found_at = null;
742
-                    //find this object in the array even though it has a different key
743
-                    foreach ($this->_model_relations[$relationName] as $index => $obj) {
744
-                        if (
745
-                            $obj instanceof EE_Base_Class
746
-                            && (
747
-                                $obj == $object_to_remove_or_index_into_array
748
-                                || $obj->ID() === $object_to_remove_or_index_into_array->ID()
749
-                            )
750
-                        ) {
751
-                            $index_found_at = $index;
752
-                            break;
753
-                        }
754
-                    }
755
-                    if ($index_found_at) {
756
-                        $index_in_cache = $index_found_at;
757
-                    } else {
758
-                        //it wasn't found. huh. well obviously it doesn't need to be removed from teh cache
759
-                        //if it wasn't in it to begin with. So we're done
760
-                        return $object_to_remove_or_index_into_array;
761
-                    }
762
-                }
763
-            } elseif ($object_to_remove_or_index_into_array instanceof EE_Base_Class) {
764
-                //so they provided a model object, but it's not yet saved to the DB... so let's go hunting for it!
765
-                foreach ($this->get_all_from_cache($relationName) as $index => $potentially_obj_we_want) {
766
-                    if ($potentially_obj_we_want == $object_to_remove_or_index_into_array) {
767
-                        $index_in_cache = $index;
768
-                    }
769
-                }
770
-            } else {
771
-                $index_in_cache = $object_to_remove_or_index_into_array;
772
-            }
773
-            //supposedly we've found it. But it could just be that the client code
774
-            //provided a bad index/object
775
-            if (
776
-            isset(
777
-                $this->_model_relations[$relationName],
778
-                $this->_model_relations[$relationName][$index_in_cache]
779
-            )
780
-            ) {
781
-                $obj_removed = $this->_model_relations[$relationName][$index_in_cache];
782
-                unset($this->_model_relations[$relationName][$index_in_cache]);
783
-            } else {
784
-                //that thing was never cached anyways.
785
-                $obj_removed = null;
786
-            }
787
-        }
788
-        return $obj_removed;
789
-    }
790
-
791
-
792
-
793
-    /**
794
-     * update_cache_after_object_save
795
-     * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has
796
-     * obtained after being saved to the db
797
-     *
798
-     * @param string         $relationName       - the type of object that is cached
799
-     * @param \EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
800
-     * @param string         $current_cache_id   - the ID that was used when originally caching the object
801
-     * @return boolean TRUE on success, FALSE on fail
802
-     * @throws \EE_Error
803
-     */
804
-    public function update_cache_after_object_save(
805
-        $relationName,
806
-        EE_Base_Class $newly_saved_object,
807
-        $current_cache_id = ''
808
-    ) {
809
-        // verify that incoming object is of the correct type
810
-        $obj_class = 'EE_' . $relationName;
811
-        if ($newly_saved_object instanceof $obj_class) {
812
-            /* @type EE_Base_Class $newly_saved_object */
813
-            // now get the type of relation
814
-            $relationship_to_model = $this->get_model()->related_settings_for($relationName);
815
-            // if this is a 1:1 relationship
816
-            if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
817
-                // then just replace the cached object with the newly saved object
818
-                $this->_model_relations[$relationName] = $newly_saved_object;
819
-                return true;
820
-                // or if it's some kind of sordid feral polyamorous relationship...
821
-            } elseif (is_array($this->_model_relations[$relationName])
822
-                      && isset($this->_model_relations[$relationName][$current_cache_id])
823
-            ) {
824
-                // then remove the current cached item
825
-                unset($this->_model_relations[$relationName][$current_cache_id]);
826
-                // and cache the newly saved object using it's new ID
827
-                $this->_model_relations[$relationName][$newly_saved_object->ID()] = $newly_saved_object;
828
-                return true;
829
-            }
830
-        }
831
-        return false;
832
-    }
833
-
834
-
835
-
836
-    /**
837
-     * Fetches a single EE_Base_Class on that relation. (If the relation is of type
838
-     * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
839
-     *
840
-     * @param string $relationName
841
-     * @return EE_Base_Class
842
-     */
843
-    public function get_one_from_cache($relationName)
844
-    {
845
-        $cached_array_or_object = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName]
846
-            : null;
847
-        if (is_array($cached_array_or_object)) {
848
-            return array_shift($cached_array_or_object);
849
-        } else {
850
-            return $cached_array_or_object;
851
-        }
852
-    }
853
-
854
-
855
-
856
-    /**
857
-     * Fetches a single EE_Base_Class on that relation. (If the relation is of type
858
-     * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
859
-     *
860
-     * @param string $relationName
861
-     * @throws \EE_Error
862
-     * @return EE_Base_Class[] NOT necessarily indexed by primary keys
863
-     */
864
-    public function get_all_from_cache($relationName)
865
-    {
866
-        $objects = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName] : array();
867
-        // if the result is not an array, but exists, make it an array
868
-        $objects = is_array($objects) ? $objects : array($objects);
869
-        //bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
870
-        //basically, if this model object was stored in the session, and these cached model objects
871
-        //already have IDs, let's make sure they're in their model's entity mapper
872
-        //otherwise we will have duplicates next time we call
873
-        // EE_Registry::instance()->load_model( $relationName )->get_one_by_ID( $result->ID() );
874
-        $model = EE_Registry::instance()->load_model($relationName);
875
-        foreach ($objects as $model_object) {
876
-            if ($model instanceof EEM_Base && $model_object instanceof EE_Base_Class) {
877
-                //ensure its in the map if it has an ID; otherwise it will be added to the map when its saved
878
-                if ($model_object->ID()) {
879
-                    $model->add_to_entity_map($model_object);
880
-                }
881
-            } else {
882
-                throw new EE_Error(
883
-                    sprintf(
884
-                        __(
885
-                            'Error retrieving related model objects. Either $1%s is not a model or $2%s is not a model object',
886
-                            'event_espresso'
887
-                        ),
888
-                        $relationName,
889
-                        gettype($model_object)
890
-                    )
891
-                );
892
-            }
893
-        }
894
-        return $objects;
895
-    }
896
-
897
-
898
-
899
-    /**
900
-     * Returns the next x number of EE_Base_Class objects in sequence from this object as found in the database
901
-     * matching the given query conditions.
902
-     *
903
-     * @param null  $field_to_order_by  What field is being used as the reference point.
904
-     * @param int   $limit              How many objects to return.
905
-     * @param array $query_params       Any additional conditions on the query.
906
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
907
-     *                                  you can indicate just the columns you want returned
908
-     * @return array|EE_Base_Class[]
909
-     * @throws \EE_Error
910
-     */
911
-    public function next_x($field_to_order_by = null, $limit = 1, $query_params = array(), $columns_to_select = null)
912
-    {
913
-        $field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
914
-            ? $this->get_model()->get_primary_key_field()->get_name()
915
-            : $field_to_order_by;
916
-        $current_value = ! empty($field) ? $this->get($field) : null;
917
-        if (empty($field) || empty($current_value)) {
918
-            return array();
919
-        }
920
-        return $this->get_model()->next_x($current_value, $field, $limit, $query_params, $columns_to_select);
921
-    }
922
-
923
-
924
-
925
-    /**
926
-     * Returns the previous x number of EE_Base_Class objects in sequence from this object as found in the database
927
-     * matching the given query conditions.
928
-     *
929
-     * @param null  $field_to_order_by  What field is being used as the reference point.
930
-     * @param int   $limit              How many objects to return.
931
-     * @param array $query_params       Any additional conditions on the query.
932
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
933
-     *                                  you can indicate just the columns you want returned
934
-     * @return array|EE_Base_Class[]
935
-     * @throws \EE_Error
936
-     */
937
-    public function previous_x(
938
-        $field_to_order_by = null,
939
-        $limit = 1,
940
-        $query_params = array(),
941
-        $columns_to_select = null
942
-    ) {
943
-        $field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
944
-            ? $this->get_model()->get_primary_key_field()->get_name()
945
-            : $field_to_order_by;
946
-        $current_value = ! empty($field) ? $this->get($field) : null;
947
-        if (empty($field) || empty($current_value)) {
948
-            return array();
949
-        }
950
-        return $this->get_model()->previous_x($current_value, $field, $limit, $query_params, $columns_to_select);
951
-    }
952
-
953
-
954
-
955
-    /**
956
-     * Returns the next EE_Base_Class object in sequence from this object as found in the database
957
-     * matching the given query conditions.
958
-     *
959
-     * @param null  $field_to_order_by  What field is being used as the reference point.
960
-     * @param array $query_params       Any additional conditions on the query.
961
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
962
-     *                                  you can indicate just the columns you want returned
963
-     * @return array|EE_Base_Class
964
-     * @throws \EE_Error
965
-     */
966
-    public function next($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
967
-    {
968
-        $field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
969
-            ? $this->get_model()->get_primary_key_field()->get_name()
970
-            : $field_to_order_by;
971
-        $current_value = ! empty($field) ? $this->get($field) : null;
972
-        if (empty($field) || empty($current_value)) {
973
-            return array();
974
-        }
975
-        return $this->get_model()->next($current_value, $field, $query_params, $columns_to_select);
976
-    }
977
-
978
-
979
-
980
-    /**
981
-     * Returns the previous EE_Base_Class object in sequence from this object as found in the database
982
-     * matching the given query conditions.
983
-     *
984
-     * @param null  $field_to_order_by  What field is being used as the reference point.
985
-     * @param array $query_params       Any additional conditions on the query.
986
-     * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
987
-     *                                  you can indicate just the column you want returned
988
-     * @return array|EE_Base_Class
989
-     * @throws \EE_Error
990
-     */
991
-    public function previous($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
992
-    {
993
-        $field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
994
-            ? $this->get_model()->get_primary_key_field()->get_name()
995
-            : $field_to_order_by;
996
-        $current_value = ! empty($field) ? $this->get($field) : null;
997
-        if (empty($field) || empty($current_value)) {
998
-            return array();
999
-        }
1000
-        return $this->get_model()->previous($current_value, $field, $query_params, $columns_to_select);
1001
-    }
1002
-
1003
-
1004
-
1005
-    /**
1006
-     * Overrides parent because parent expects old models.
1007
-     * This also doesn't do any validation, and won't work for serialized arrays
1008
-     *
1009
-     * @param string $field_name
1010
-     * @param mixed  $field_value_from_db
1011
-     * @throws \EE_Error
1012
-     */
1013
-    public function set_from_db($field_name, $field_value_from_db)
1014
-    {
1015
-        $field_obj = $this->get_model()->field_settings_for($field_name);
1016
-        if ($field_obj instanceof EE_Model_Field_Base) {
1017
-            //you would think the DB has no NULLs for non-null label fields right? wrong!
1018
-            //eg, a CPT model object could have an entry in the posts table, but no
1019
-            //entry in the meta table. Meaning that all its columns in the meta table
1020
-            //are null! yikes! so when we find one like that, use defaults for its meta columns
1021
-            if ($field_value_from_db === null) {
1022
-                if ($field_obj->is_nullable()) {
1023
-                    //if the field allows nulls, then let it be null
1024
-                    $field_value = null;
1025
-                } else {
1026
-                    $field_value = $field_obj->get_default_value();
1027
-                }
1028
-            } else {
1029
-                $field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1030
-            }
1031
-            $this->_fields[$field_name] = $field_value;
1032
-            $this->_clear_cached_property($field_name);
1033
-        }
1034
-    }
1035
-
1036
-
1037
-
1038
-    /**
1039
-     * verifies that the specified field is of the correct type
1040
-     *
1041
-     * @param string $field_name
1042
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1043
-     *                                (in cases where the same property may be used for different outputs
1044
-     *                                - i.e. datetime, money etc.)
1045
-     * @return mixed
1046
-     * @throws \EE_Error
1047
-     */
1048
-    public function get($field_name, $extra_cache_ref = null)
1049
-    {
1050
-        return $this->_get_cached_property($field_name, false, $extra_cache_ref);
1051
-    }
1052
-
1053
-
1054
-
1055
-    /**
1056
-     * This method simply returns the RAW unprocessed value for the given property in this class
1057
-     *
1058
-     * @param  string $field_name A valid fieldname
1059
-     * @return mixed              Whatever the raw value stored on the property is.
1060
-     * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1061
-     */
1062
-    public function get_raw($field_name)
1063
-    {
1064
-        $field_settings = $this->get_model()->field_settings_for($field_name);
1065
-        return $field_settings instanceof EE_Datetime_Field && $this->_fields[$field_name] instanceof DateTime
1066
-            ? $this->_fields[$field_name]->format('U')
1067
-            : $this->_fields[$field_name];
1068
-    }
1069
-
1070
-
1071
-
1072
-    /**
1073
-     * This is used to return the internal DateTime object used for a field that is a
1074
-     * EE_Datetime_Field.
1075
-     *
1076
-     * @param string $field_name               The field name retrieving the DateTime object.
1077
-     * @return mixed null | false | DateTime  If the requested field is NOT a EE_Datetime_Field then
1078
-     * @throws \EE_Error
1079
-     *                                         an error is set and false returned.  If the field IS an
1080
-     *                                         EE_Datetime_Field and but the field value is null, then
1081
-     *                                         just null is returned (because that indicates that likely
1082
-     *                                         this field is nullable).
1083
-     */
1084
-    public function get_DateTime_object($field_name)
1085
-    {
1086
-        $field_settings = $this->get_model()->field_settings_for($field_name);
1087
-        if ( ! $field_settings instanceof EE_Datetime_Field) {
1088
-            EE_Error::add_error(
1089
-                sprintf(
1090
-                    __(
1091
-                        'The field %s is not an EE_Datetime_Field field.  There is no DateTime object stored on this field type.',
1092
-                        'event_espresso'
1093
-                    ),
1094
-                    $field_name
1095
-                ),
1096
-                __FILE__,
1097
-                __FUNCTION__,
1098
-                __LINE__
1099
-            );
1100
-            return false;
1101
-        }
1102
-        return $this->_fields[$field_name];
1103
-    }
1104
-
1105
-
1106
-
1107
-    /**
1108
-     * To be used in template to immediately echo out the value, and format it for output.
1109
-     * Eg, should call stripslashes and whatnot before echoing
1110
-     *
1111
-     * @param string $field_name      the name of the field as it appears in the DB
1112
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1113
-     *                                (in cases where the same property may be used for different outputs
1114
-     *                                - i.e. datetime, money etc.)
1115
-     * @return void
1116
-     * @throws \EE_Error
1117
-     */
1118
-    public function e($field_name, $extra_cache_ref = null)
1119
-    {
1120
-        echo $this->get_pretty($field_name, $extra_cache_ref);
1121
-    }
1122
-
1123
-
1124
-
1125
-    /**
1126
-     * Exactly like e(), echoes out the field, but sets its schema to 'form_input', so that it
1127
-     * can be easily used as the value of form input.
1128
-     *
1129
-     * @param string $field_name
1130
-     * @return void
1131
-     * @throws \EE_Error
1132
-     */
1133
-    public function f($field_name)
1134
-    {
1135
-        $this->e($field_name, 'form_input');
1136
-    }
1137
-
1138
-
1139
-
1140
-    /**
1141
-     * Gets a pretty view of the field's value. $extra_cache_ref can specify different formats for this.
1142
-     * The $extra_cache_ref will be passed to the model field's prepare_for_pretty_echoing, so consult the field's class
1143
-     * to see what options are available.
1144
-     * @param string $field_name
1145
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1146
-     *                                (in cases where the same property may be used for different outputs
1147
-     *                                - i.e. datetime, money etc.)
1148
-     * @return mixed
1149
-     * @throws \EE_Error
1150
-     */
1151
-    public function get_pretty($field_name, $extra_cache_ref = null)
1152
-    {
1153
-        return $this->_get_cached_property($field_name, true, $extra_cache_ref);
1154
-    }
1155
-
1156
-
1157
-
1158
-    /**
1159
-     * This simply returns the datetime for the given field name
1160
-     * Note: this protected function is called by the wrapper get_date or get_time or get_datetime functions
1161
-     * (and the equivalent e_date, e_time, e_datetime).
1162
-     *
1163
-     * @access   protected
1164
-     * @param string   $field_name   Field on the instantiated EE_Base_Class child object
1165
-     * @param string   $dt_frmt      valid datetime format used for date
1166
-     *                               (if '' then we just use the default on the field,
1167
-     *                               if NULL we use the last-used format)
1168
-     * @param string   $tm_frmt      Same as above except this is for time format
1169
-     * @param string   $date_or_time if NULL then both are returned, otherwise "D" = only date and "T" = only time.
1170
-     * @param  boolean $echo         Whether the dtt is echoing using pretty echoing or just returned using vanilla get
1171
-     * @return string|bool|EE_Error string on success, FALSE on fail, or EE_Error Exception is thrown
1172
-     *                               if field is not a valid dtt field, or void if echoing
1173
-     * @throws \EE_Error
1174
-     */
1175
-    protected function _get_datetime($field_name, $dt_frmt = '', $tm_frmt = '', $date_or_time = '', $echo = false)
1176
-    {
1177
-        // clear cached property
1178
-        $this->_clear_cached_property($field_name);
1179
-        //reset format properties because they are used in get()
1180
-        $this->_dt_frmt = $dt_frmt !== '' ? $dt_frmt : $this->_dt_frmt;
1181
-        $this->_tm_frmt = $tm_frmt !== '' ? $tm_frmt : $this->_tm_frmt;
1182
-        if ($echo) {
1183
-            $this->e($field_name, $date_or_time);
1184
-            return '';
1185
-        }
1186
-        return $this->get($field_name, $date_or_time);
1187
-    }
1188
-
1189
-
1190
-
1191
-    /**
1192
-     * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the date
1193
-     * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1194
-     * other echoes the pretty value for dtt)
1195
-     *
1196
-     * @param  string $field_name name of model object datetime field holding the value
1197
-     * @param  string $format     format for the date returned (if NULL we use default in dt_frmt property)
1198
-     * @return string            datetime value formatted
1199
-     * @throws \EE_Error
1200
-     */
1201
-    public function get_date($field_name, $format = '')
1202
-    {
1203
-        return $this->_get_datetime($field_name, $format, null, 'D');
1204
-    }
1205
-
1206
-
1207
-
1208
-    /**
1209
-     * @param      $field_name
1210
-     * @param string $format
1211
-     * @throws \EE_Error
1212
-     */
1213
-    public function e_date($field_name, $format = '')
1214
-    {
1215
-        $this->_get_datetime($field_name, $format, null, 'D', true);
1216
-    }
1217
-
1218
-
1219
-
1220
-    /**
1221
-     * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the time
1222
-     * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1223
-     * other echoes the pretty value for dtt)
1224
-     *
1225
-     * @param  string $field_name name of model object datetime field holding the value
1226
-     * @param  string $format     format for the time returned ( if NULL we use default in tm_frmt property)
1227
-     * @return string             datetime value formatted
1228
-     * @throws \EE_Error
1229
-     */
1230
-    public function get_time($field_name, $format = '')
1231
-    {
1232
-        return $this->_get_datetime($field_name, null, $format, 'T');
1233
-    }
1234
-
1235
-
1236
-
1237
-    /**
1238
-     * @param      $field_name
1239
-     * @param string $format
1240
-     * @throws \EE_Error
1241
-     */
1242
-    public function e_time($field_name, $format = '')
1243
-    {
1244
-        $this->_get_datetime($field_name, null, $format, 'T', true);
1245
-    }
1246
-
1247
-
1248
-
1249
-    /**
1250
-     * below are wrapper functions for the various datetime outputs that can be obtained for returning the date AND
1251
-     * time portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1252
-     * other echoes the pretty value for dtt)
1253
-     *
1254
-     * @param  string $field_name name of model object datetime field holding the value
1255
-     * @param  string $dt_frmt    format for the date returned (if NULL we use default in dt_frmt property)
1256
-     * @param  string $tm_frmt    format for the time returned (if NULL we use default in tm_frmt property)
1257
-     * @return string             datetime value formatted
1258
-     * @throws \EE_Error
1259
-     */
1260
-    public function get_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1261
-    {
1262
-        return $this->_get_datetime($field_name, $dt_frmt, $tm_frmt);
1263
-    }
1264
-
1265
-
1266
-
1267
-    /**
1268
-     * @param string $field_name
1269
-     * @param string $dt_frmt
1270
-     * @param string $tm_frmt
1271
-     * @throws \EE_Error
1272
-     */
1273
-    public function e_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1274
-    {
1275
-        $this->_get_datetime($field_name, $dt_frmt, $tm_frmt, null, true);
1276
-    }
1277
-
1278
-
1279
-
1280
-    /**
1281
-     * Get the i8ln value for a date using the WordPress @see date_i18n function.
1282
-     *
1283
-     * @param string $field_name The EE_Datetime_Field reference for the date being retrieved.
1284
-     * @param string $format     PHP valid date/time string format.  If none is provided then the internal set format
1285
-     *                           on the object will be used.
1286
-     * @return string Date and time string in set locale or false if no field exists for the given
1287
-     * @throws \EE_Error
1288
-     *                           field name.
1289
-     */
1290
-    public function get_i18n_datetime($field_name, $format = '')
1291
-    {
1292
-        $format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1293
-        return date_i18n(
1294
-            $format,
1295
-            EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
1296
-        );
1297
-    }
1298
-
1299
-
1300
-
1301
-    /**
1302
-     * This method validates whether the given field name is a valid field on the model object as well as it is of a
1303
-     * type EE_Datetime_Field.  On success there will be returned the field settings.  On fail an EE_Error exception is
1304
-     * thrown.
1305
-     *
1306
-     * @param  string $field_name The field name being checked
1307
-     * @throws EE_Error
1308
-     * @return EE_Datetime_Field
1309
-     */
1310
-    protected function _get_dtt_field_settings($field_name)
1311
-    {
1312
-        $field = $this->get_model()->field_settings_for($field_name);
1313
-        //check if field is dtt
1314
-        if ($field instanceof EE_Datetime_Field) {
1315
-            return $field;
1316
-        } else {
1317
-            throw new EE_Error(sprintf(__('The field name "%s" has been requested for the EE_Base_Class datetime functions and it is not a valid EE_Datetime_Field.  Please check the spelling of the field and make sure it has been setup as a EE_Datetime_Field in the %s model constructor',
1318
-                'event_espresso'), $field_name, self::_get_model_classname(get_class($this))));
1319
-        }
1320
-    }
1321
-
1322
-
1323
-
1324
-
1325
-    /**
1326
-     * NOTE ABOUT BELOW:
1327
-     * These convenience date and time setters are for setting date and time independently.  In other words you might
1328
-     * want to change the time on a datetime_field but leave the date the same (or vice versa). IF on the other hand
1329
-     * you want to set both date and time at the same time, you can just use the models default set($fieldname,$value)
1330
-     * method and make sure you send the entire datetime value for setting.
1331
-     */
1332
-    /**
1333
-     * sets the time on a datetime property
1334
-     *
1335
-     * @access protected
1336
-     * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1337
-     * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1338
-     * @throws \EE_Error
1339
-     */
1340
-    protected function _set_time_for($time, $fieldname)
1341
-    {
1342
-        $this->_set_date_time('T', $time, $fieldname);
1343
-    }
1344
-
1345
-
1346
-
1347
-    /**
1348
-     * sets the date on a datetime property
1349
-     *
1350
-     * @access protected
1351
-     * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1352
-     * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1353
-     * @throws \EE_Error
1354
-     */
1355
-    protected function _set_date_for($date, $fieldname)
1356
-    {
1357
-        $this->_set_date_time('D', $date, $fieldname);
1358
-    }
1359
-
1360
-
1361
-
1362
-    /**
1363
-     * This takes care of setting a date or time independently on a given model object property. This method also
1364
-     * verifies that the given fieldname matches a model object property and is for a EE_Datetime_Field field
1365
-     *
1366
-     * @access protected
1367
-     * @param string          $what           "T" for time, 'B' for both, 'D' for Date.
1368
-     * @param string|DateTime $datetime_value A valid Date or Time string (or DateTime object)
1369
-     * @param string          $fieldname      the name of the field the date OR time is being set on (must match a
1370
-     *                                        EE_Datetime_Field property)
1371
-     * @throws \EE_Error
1372
-     */
1373
-    protected function _set_date_time($what = 'T', $datetime_value, $fieldname)
1374
-    {
1375
-        $field = $this->_get_dtt_field_settings($fieldname);
1376
-        $field->set_timezone($this->_timezone);
1377
-        $field->set_date_format($this->_dt_frmt);
1378
-        $field->set_time_format($this->_tm_frmt);
1379
-        switch ($what) {
1380
-            case 'T' :
1381
-                $this->_fields[$fieldname] = $field->prepare_for_set_with_new_time(
1382
-                    $datetime_value,
1383
-                    $this->_fields[$fieldname]
1384
-                );
1385
-                break;
1386
-            case 'D' :
1387
-                $this->_fields[$fieldname] = $field->prepare_for_set_with_new_date(
1388
-                    $datetime_value,
1389
-                    $this->_fields[$fieldname]
1390
-                );
1391
-                break;
1392
-            case 'B' :
1393
-                $this->_fields[$fieldname] = $field->prepare_for_set($datetime_value);
1394
-                break;
1395
-        }
1396
-        $this->_clear_cached_property($fieldname);
1397
-    }
1398
-
1399
-
1400
-
1401
-    /**
1402
-     * This will return a timestamp for the website timezone but ONLY when the current website timezone is different
1403
-     * than the timezone set for the website. NOTE, this currently only works well with methods that return values.  If
1404
-     * you use it with methods that echo values the $_timestamp property may not get reset to its original value and
1405
-     * that could lead to some unexpected results!
1406
-     *
1407
-     * @access public
1408
-     * @param string               $field_name This is the name of the field on the object that contains the date/time
1409
-     *                                         value being returned.
1410
-     * @param string               $callback   must match a valid method in this class (defaults to get_datetime)
1411
-     * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1412
-     * @param string               $prepend    You can include something to prepend on the timestamp
1413
-     * @param string               $append     You can include something to append on the timestamp
1414
-     * @throws EE_Error
1415
-     * @return string timestamp
1416
-     */
1417
-    public function display_in_my_timezone(
1418
-        $field_name,
1419
-        $callback = 'get_datetime',
1420
-        $args = null,
1421
-        $prepend = '',
1422
-        $append = ''
1423
-    ) {
1424
-        $timezone = EEH_DTT_Helper::get_timezone();
1425
-        if ($timezone === $this->_timezone) {
1426
-            return '';
1427
-        }
1428
-        $original_timezone = $this->_timezone;
1429
-        $this->set_timezone($timezone);
1430
-        $fn = (array)$field_name;
1431
-        $args = array_merge($fn, (array)$args);
1432
-        if ( ! method_exists($this, $callback)) {
1433
-            throw new EE_Error(
1434
-                sprintf(
1435
-                    __(
1436
-                        'The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling',
1437
-                        'event_espresso'
1438
-                    ),
1439
-                    $callback
1440
-                )
1441
-            );
1442
-        }
1443
-        $args = (array)$args;
1444
-        $return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1445
-        $this->set_timezone($original_timezone);
1446
-        return $return;
1447
-    }
1448
-
1449
-
1450
-
1451
-    /**
1452
-     * Deletes this model object.
1453
-     * This calls the `EE_Base_Class::_delete` method.  Child classes wishing to change default behaviour should
1454
-     * override
1455
-     * `EE_Base_Class::_delete` NOT this class.
1456
-     *
1457
-     * @return boolean | int
1458
-     * @throws \EE_Error
1459
-     */
1460
-    public function delete()
1461
-    {
1462
-        /**
1463
-         * Called just before the `EE_Base_Class::_delete` method call.
1464
-         * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1465
-         * should be aware that `_delete` may not always result in a permanent delete.  For example, `EE_Soft_Delete_Base_Class::_delete`
1466
-         * soft deletes (trash) the object and does not permanently delete it.
1467
-         *
1468
-         * @param EE_Base_Class $model_object about to be 'deleted'
1469
-         */
1470
-        do_action('AHEE__EE_Base_Class__delete__before', $this);
1471
-        $result = $this->_delete();
1472
-        /**
1473
-         * Called just after the `EE_Base_Class::_delete` method call.
1474
-         * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1475
-         * should be aware that `_delete` may not always result in a permanent delete.  For example `EE_Soft_Base_Class::_delete`
1476
-         * soft deletes (trash) the object and does not permanently delete it.
1477
-         *
1478
-         * @param EE_Base_Class $model_object that was just 'deleted'
1479
-         * @param boolean       $result
1480
-         */
1481
-        do_action('AHEE__EE_Base_Class__delete__end', $this, $result);
1482
-        return $result;
1483
-    }
1484
-
1485
-
1486
-
1487
-    /**
1488
-     * Calls the specific delete method for the instantiated class.
1489
-     * This method is called by the public `EE_Base_Class::delete` method.  Any child classes desiring to override
1490
-     * default functionality for "delete" (which is to call `permanently_delete`) should override this method NOT
1491
-     * `EE_Base_Class::delete`
1492
-     *
1493
-     * @return bool|int
1494
-     * @throws \EE_Error
1495
-     */
1496
-    protected function _delete()
1497
-    {
1498
-        return $this->delete_permanently();
1499
-    }
1500
-
1501
-
1502
-
1503
-    /**
1504
-     * Deletes this model object permanently from db (but keep in mind related models my block the delete and return an
1505
-     * error)
1506
-     *
1507
-     * @return bool | int
1508
-     * @throws \EE_Error
1509
-     */
1510
-    public function delete_permanently()
1511
-    {
1512
-        /**
1513
-         * Called just before HARD deleting a model object
1514
-         *
1515
-         * @param EE_Base_Class $model_object about to be 'deleted'
1516
-         */
1517
-        do_action('AHEE__EE_Base_Class__delete_permanently__before', $this);
1518
-        $model = $this->get_model();
1519
-        $result = $model->delete_permanently_by_ID($this->ID());
1520
-        $this->refresh_cache_of_related_objects();
1521
-        /**
1522
-         * Called just after HARD deleting a model object
1523
-         *
1524
-         * @param EE_Base_Class $model_object that was just 'deleted'
1525
-         * @param boolean       $result
1526
-         */
1527
-        do_action('AHEE__EE_Base_Class__delete_permanently__end', $this, $result);
1528
-        return $result;
1529
-    }
1530
-
1531
-
1532
-
1533
-    /**
1534
-     * When this model object is deleted, it may still be cached on related model objects. This clears the cache of
1535
-     * related model objects
1536
-     *
1537
-     * @throws \EE_Error
1538
-     */
1539
-    public function refresh_cache_of_related_objects()
1540
-    {
1541
-        foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
1542
-            if ( ! empty($this->_model_relations[$relation_name])) {
1543
-                $related_objects = $this->_model_relations[$relation_name];
1544
-                if ($relation_obj instanceof EE_Belongs_To_Relation) {
1545
-                    //this relation only stores a single model object, not an array
1546
-                    //but let's make it consistent
1547
-                    $related_objects = array($related_objects);
1548
-                }
1549
-                foreach ($related_objects as $related_object) {
1550
-                    //only refresh their cache if they're in memory
1551
-                    if ($related_object instanceof EE_Base_Class) {
1552
-                        $related_object->clear_cache($this->get_model()->get_this_model_name(), $this);
1553
-                    }
1554
-                }
1555
-            }
1556
-        }
1557
-    }
1558
-
1559
-
1560
-
1561
-    /**
1562
-     *        Saves this object to the database. An array may be supplied to set some values on this
1563
-     * object just before saving.
1564
-     *
1565
-     * @access public
1566
-     * @param array $set_cols_n_values keys are field names, values are their new values,
1567
-     *                                 if provided during the save() method (often client code will change the fields'
1568
-     *                                 values before calling save)
1569
-     * @throws \EE_Error
1570
-     * @return int , 1 on a successful update, the ID of the new entry on insert; 0 on failure or if the model object
1571
-     *                                 isn't allowed to persist (as determined by EE_Base_Class::allow_persist())
1572
-     */
1573
-    public function save($set_cols_n_values = array())
1574
-    {
1575
-        /**
1576
-         * Filters the fields we're about to save on the model object
1577
-         *
1578
-         * @param array         $set_cols_n_values
1579
-         * @param EE_Base_Class $model_object
1580
-         */
1581
-        $set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1582
-            $this);
1583
-        //set attributes as provided in $set_cols_n_values
1584
-        foreach ($set_cols_n_values as $column => $value) {
1585
-            $this->set($column, $value);
1586
-        }
1587
-        // no changes ? then don't do anything
1588
-        if (! $this->_has_changes && $this->ID() && $this->get_model()->get_primary_key_field()->is_auto_increment()) {
1589
-            return 0;
1590
-        }
1591
-        /**
1592
-         * Saving a model object.
1593
-         * Before we perform a save, this action is fired.
1594
-         *
1595
-         * @param EE_Base_Class $model_object the model object about to be saved.
1596
-         */
1597
-        do_action('AHEE__EE_Base_Class__save__begin', $this);
1598
-        if ( ! $this->allow_persist()) {
1599
-            return 0;
1600
-        }
1601
-        //now get current attribute values
1602
-        $save_cols_n_values = $this->_fields;
1603
-        //if the object already has an ID, update it. Otherwise, insert it
1604
-        //also: change the assumption about values passed to the model NOT being prepare dby the model object. They have been
1605
-        $old_assumption_concerning_value_preparation = $this->get_model()
1606
-                                                            ->get_assumption_concerning_values_already_prepared_by_model_object();
1607
-        $this->get_model()->assume_values_already_prepared_by_model_object(true);
1608
-        //does this model have an autoincrement PK?
1609
-        if ($this->get_model()->has_primary_key_field()) {
1610
-            if ($this->get_model()->get_primary_key_field()->is_auto_increment()) {
1611
-                //ok check if it's set, if so: update; if not, insert
1612
-                if ( ! empty($save_cols_n_values[self::_get_primary_key_name(get_class($this))])) {
1613
-                    $results = $this->get_model()->update_by_ID($save_cols_n_values, $this->ID());
1614
-                } else {
1615
-                    unset($save_cols_n_values[self::_get_primary_key_name(get_class($this))]);
1616
-                    $results = $this->get_model()->insert($save_cols_n_values);
1617
-                    if ($results) {
1618
-                        //if successful, set the primary key
1619
-                        //but don't use the normal SET method, because it will check if
1620
-                        //an item with the same ID exists in the mapper & db, then
1621
-                        //will find it in the db (because we just added it) and THAT object
1622
-                        //will get added to the mapper before we can add this one!
1623
-                        //but if we just avoid using the SET method, all that headache can be avoided
1624
-                        $pk_field_name = self::_get_primary_key_name(get_class($this));
1625
-                        $this->_fields[$pk_field_name] = $results;
1626
-                        $this->_clear_cached_property($pk_field_name);
1627
-                        $this->get_model()->add_to_entity_map($this);
1628
-                        $this->_update_cached_related_model_objs_fks();
1629
-                    }
1630
-                }
1631
-            } else {//PK is NOT auto-increment
1632
-                //so check if one like it already exists in the db
1633
-                if ($this->get_model()->exists_by_ID($this->ID())) {
1634
-                    if (WP_DEBUG && ! $this->in_entity_map()) {
1635
-                        throw new EE_Error(
1636
-                            sprintf(
1637
-                                __('Using a model object %1$s that is NOT in the entity map, can lead to unexpected errors. You should either: %4$s 1. Put it in the entity mapper by calling %2$s %4$s 2. Discard this model object and use what is in the entity mapper %4$s 3. Fetch from the database using %3$s',
1638
-                                    'event_espresso'),
1639
-                                get_class($this),
1640
-                                get_class($this->get_model()) . '::instance()->add_to_entity_map()',
1641
-                                get_class($this->get_model()) . '::instance()->get_one_by_ID()',
1642
-                                '<br />'
1643
-                            )
1644
-                        );
1645
-                    }
1646
-                    $results = $this->get_model()->update_by_ID($save_cols_n_values, $this->ID());
1647
-                } else {
1648
-                    $results = $this->get_model()->insert($save_cols_n_values);
1649
-                    $this->_update_cached_related_model_objs_fks();
1650
-                }
1651
-            }
1652
-        } else {//there is NO primary key
1653
-            $already_in_db = false;
1654
-            foreach ($this->get_model()->unique_indexes() as $index) {
1655
-                $uniqueness_where_params = array_intersect_key($save_cols_n_values, $index->fields());
1656
-                if ($this->get_model()->exists(array($uniqueness_where_params))) {
1657
-                    $already_in_db = true;
1658
-                }
1659
-            }
1660
-            if ($already_in_db) {
1661
-                $combined_pk_fields_n_values = array_intersect_key($save_cols_n_values,
1662
-                    $this->get_model()->get_combined_primary_key_fields());
1663
-                $results = $this->get_model()->update($save_cols_n_values, $combined_pk_fields_n_values);
1664
-            } else {
1665
-                $results = $this->get_model()->insert($save_cols_n_values);
1666
-            }
1667
-        }
1668
-        //restore the old assumption about values being prepared by the model object
1669
-        $this->get_model()
1670
-             ->assume_values_already_prepared_by_model_object($old_assumption_concerning_value_preparation);
1671
-        /**
1672
-         * After saving the model object this action is called
1673
-         *
1674
-         * @param EE_Base_Class $model_object which was just saved
1675
-         * @param boolean|int   $results      if it were updated, TRUE or FALSE; if it were newly inserted
1676
-         *                                    the new ID (or 0 if an error occurred and it wasn't updated)
1677
-         */
1678
-        do_action('AHEE__EE_Base_Class__save__end', $this, $results);
1679
-        $this->_has_changes = false;
1680
-        return $results;
1681
-    }
1682
-
1683
-
1684
-
1685
-    /**
1686
-     * Updates the foreign key on related models objects pointing to this to have this model object's ID
1687
-     * as their foreign key.  If the cached related model objects already exist in the db, saves them (so that the DB
1688
-     * is consistent) Especially useful in case we JUST added this model object ot the database and we want to let its
1689
-     * cached relations with foreign keys to it know about that change. Eg: we've created a transaction but haven't
1690
-     * saved it to the db. We also create a registration and don't save it to the DB, but we DO cache it on the
1691
-     * transaction. Now, when we save the transaction, the registration's TXN_ID will be automatically updated, whether
1692
-     * or not they exist in the DB (if they do, their DB records will be automatically updated)
1693
-     *
1694
-     * @return void
1695
-     * @throws \EE_Error
1696
-     */
1697
-    protected function _update_cached_related_model_objs_fks()
1698
-    {
1699
-        foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
1700
-            if ($relation_obj instanceof EE_Has_Many_Relation) {
1701
-                foreach ($this->get_all_from_cache($relation_name) as $related_model_obj_in_cache) {
1702
-                    $fk_to_this = $related_model_obj_in_cache->get_model()->get_foreign_key_to(
1703
-                        $this->get_model()->get_this_model_name()
1704
-                    );
1705
-                    $related_model_obj_in_cache->set($fk_to_this->get_name(), $this->ID());
1706
-                    if ($related_model_obj_in_cache->ID()) {
1707
-                        $related_model_obj_in_cache->save();
1708
-                    }
1709
-                }
1710
-            }
1711
-        }
1712
-    }
1713
-
1714
-
1715
-
1716
-    /**
1717
-     * Saves this model object and its NEW cached relations to the database.
1718
-     * (Meaning, for now, IT DOES NOT WORK if the cached items already exist in the DB.
1719
-     * In order for that to work, we would need to mark model objects as dirty/clean...
1720
-     * because otherwise, there's a potential for infinite looping of saving
1721
-     * Saves the cached related model objects, and ensures the relation between them
1722
-     * and this object and properly setup
1723
-     *
1724
-     * @return int ID of new model object on save; 0 on failure+
1725
-     * @throws \EE_Error
1726
-     */
1727
-    public function save_new_cached_related_model_objs()
1728
-    {
1729
-        //make sure this has been saved
1730
-        if ( ! $this->ID()) {
1731
-            $id = $this->save();
1732
-        } else {
1733
-            $id = $this->ID();
1734
-        }
1735
-        //now save all the NEW cached model objects  (ie they don't exist in the DB)
1736
-        foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1737
-            if ($this->_model_relations[$relationName]) {
1738
-                //is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
1739
-                //or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
1740
-                if ($relationObj instanceof EE_Belongs_To_Relation) {
1741
-                    //add a relation to that relation type (which saves the appropriate thing in the process)
1742
-                    //but ONLY if it DOES NOT exist in the DB
1743
-                    /* @var $related_model_obj EE_Base_Class */
1744
-                    $related_model_obj = $this->_model_relations[$relationName];
1745
-                    //					if( ! $related_model_obj->ID()){
1746
-                    $this->_add_relation_to($related_model_obj, $relationName);
1747
-                    $related_model_obj->save_new_cached_related_model_objs();
1748
-                    //					}
1749
-                } else {
1750
-                    foreach ($this->_model_relations[$relationName] as $related_model_obj) {
1751
-                        //add a relation to that relation type (which saves the appropriate thing in the process)
1752
-                        //but ONLY if it DOES NOT exist in the DB
1753
-                        //						if( ! $related_model_obj->ID()){
1754
-                        $this->_add_relation_to($related_model_obj, $relationName);
1755
-                        $related_model_obj->save_new_cached_related_model_objs();
1756
-                        //						}
1757
-                    }
1758
-                }
1759
-            }
1760
-        }
1761
-        return $id;
1762
-    }
1763
-
1764
-
1765
-
1766
-    /**
1767
-     * for getting a model while instantiated.
1768
-     *
1769
-     * @return \EEM_Base | \EEM_CPT_Base
1770
-     */
1771
-    public function get_model()
1772
-    {
1773
-        $modelName = self::_get_model_classname(get_class($this));
1774
-        return self::_get_model_instance_with_name($modelName, $this->_timezone);
1775
-    }
1776
-
1777
-
1778
-
1779
-    /**
1780
-     * @param $props_n_values
1781
-     * @param $classname
1782
-     * @return mixed bool|EE_Base_Class|EEM_CPT_Base
1783
-     * @throws \EE_Error
1784
-     */
1785
-    protected static function _get_object_from_entity_mapper($props_n_values, $classname)
1786
-    {
1787
-        //TODO: will not work for Term_Relationships because they have no PK!
1788
-        $primary_id_ref = self::_get_primary_key_name($classname);
1789
-        if (array_key_exists($primary_id_ref, $props_n_values) && ! empty($props_n_values[$primary_id_ref])) {
1790
-            $id = $props_n_values[$primary_id_ref];
1791
-            return self::_get_model($classname)->get_from_entity_map($id);
1792
-        }
1793
-        return false;
1794
-    }
1795
-
1796
-
1797
-
1798
-    /**
1799
-     * This is called by child static "new_instance" method and we'll check to see if there is an existing db entry for
1800
-     * the primary key (if present in incoming values). If there is a key in the incoming array that matches the
1801
-     * primary key for the model AND it is not null, then we check the db. If there's a an object we return it.  If not
1802
-     * we return false.
1803
-     *
1804
-     * @param  array  $props_n_values   incoming array of properties and their values
1805
-     * @param  string $classname        the classname of the child class
1806
-     * @param null    $timezone
1807
-     * @param array   $date_formats     incoming date_formats in an array where the first value is the
1808
-     *                                  date_format and the second value is the time format
1809
-     * @return mixed (EE_Base_Class|bool)
1810
-     * @throws \EE_Error
1811
-     */
1812
-    protected static function _check_for_object($props_n_values, $classname, $timezone = null, $date_formats = array())
1813
-    {
1814
-        $existing = null;
1815
-        if (self::_get_model($classname)->has_primary_key_field()) {
1816
-            $primary_id_ref = self::_get_primary_key_name($classname);
1817
-            if (array_key_exists($primary_id_ref, $props_n_values)
1818
-                && ! empty($props_n_values[$primary_id_ref])
1819
-            ) {
1820
-                $existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1821
-                    $props_n_values[$primary_id_ref]
1822
-                );
1823
-            }
1824
-        } elseif (self::_get_model($classname, $timezone)->has_all_combined_primary_key_fields($props_n_values)) {
1825
-            //no primary key on this model, but there's still a matching item in the DB
1826
-            $existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1827
-                self::_get_model($classname, $timezone)->get_index_primary_key_string($props_n_values)
1828
-            );
1829
-        }
1830
-        if ($existing) {
1831
-            //set date formats if present before setting values
1832
-            if ( ! empty($date_formats) && is_array($date_formats)) {
1833
-                $existing->set_date_format($date_formats[0]);
1834
-                $existing->set_time_format($date_formats[1]);
1835
-            } else {
1836
-                //set default formats for date and time
1837
-                $existing->set_date_format(get_option('date_format'));
1838
-                $existing->set_time_format(get_option('time_format'));
1839
-            }
1840
-            foreach ($props_n_values as $property => $field_value) {
1841
-                $existing->set($property, $field_value);
1842
-            }
1843
-            return $existing;
1844
-        } else {
1845
-            return false;
1846
-        }
1847
-    }
1848
-
1849
-
1850
-
1851
-    /**
1852
-     * Gets the EEM_*_Model for this class
1853
-     *
1854
-     * @access public now, as this is more convenient
1855
-     * @param      $classname
1856
-     * @param null $timezone
1857
-     * @throws EE_Error
1858
-     * @return EEM_Base
1859
-     */
1860
-    protected static function _get_model($classname, $timezone = null)
1861
-    {
1862
-        //find model for this class
1863
-        if ( ! $classname) {
1864
-            throw new EE_Error(
1865
-                sprintf(
1866
-                    __(
1867
-                        "What were you thinking calling _get_model(%s)?? You need to specify the class name",
1868
-                        "event_espresso"
1869
-                    ),
1870
-                    $classname
1871
-                )
1872
-            );
1873
-        }
1874
-        $modelName = self::_get_model_classname($classname);
1875
-        return self::_get_model_instance_with_name($modelName, $timezone);
1876
-    }
1877
-
1878
-
1879
-
1880
-    /**
1881
-     * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1882
-     *
1883
-     * @param string $model_classname
1884
-     * @param null   $timezone
1885
-     * @return EEM_Base
1886
-     */
1887
-    protected static function _get_model_instance_with_name($model_classname, $timezone = null)
1888
-    {
1889
-        $model_classname = str_replace('EEM_', '', $model_classname);
1890
-        $model = EE_Registry::instance()->load_model($model_classname);
1891
-        $model->set_timezone($timezone);
1892
-        return $model;
1893
-    }
1894
-
1895
-
1896
-
1897
-    /**
1898
-     * If a model name is provided (eg Registration), gets the model classname for that model.
1899
-     * Also works if a model class's classname is provided (eg EE_Registration).
1900
-     *
1901
-     * @param null $model_name
1902
-     * @return string like EEM_Attendee
1903
-     */
1904
-    private static function _get_model_classname($model_name = null)
1905
-    {
1906
-        if (strpos($model_name, "EE_") === 0) {
1907
-            $model_classname = str_replace("EE_", "EEM_", $model_name);
1908
-        } else {
1909
-            $model_classname = "EEM_" . $model_name;
1910
-        }
1911
-        return $model_classname;
1912
-    }
1913
-
1914
-
1915
-
1916
-    /**
1917
-     * returns the name of the primary key attribute
1918
-     *
1919
-     * @param null $classname
1920
-     * @throws EE_Error
1921
-     * @return string
1922
-     */
1923
-    protected static function _get_primary_key_name($classname = null)
1924
-    {
1925
-        if ( ! $classname) {
1926
-            throw new EE_Error(
1927
-                sprintf(
1928
-                    __("What were you thinking calling _get_primary_key_name(%s)", "event_espresso"),
1929
-                    $classname
1930
-                )
1931
-            );
1932
-        }
1933
-        return self::_get_model($classname)->get_primary_key_field()->get_name();
1934
-    }
1935
-
1936
-
1937
-
1938
-    /**
1939
-     * Gets the value of the primary key.
1940
-     * If the object hasn't yet been saved, it should be whatever the model field's default was
1941
-     * (eg, if this were the EE_Event class, look at the primary key field on EEM_Event and see what its default value
1942
-     * is. Usually defaults for integer primary keys are 0; string primary keys are usually NULL).
1943
-     *
1944
-     * @return mixed, if the primary key is of type INT it'll be an int. Otherwise it could be a string
1945
-     * @throws \EE_Error
1946
-     */
1947
-    public function ID()
1948
-    {
1949
-        //now that we know the name of the variable, use a variable variable to get its value and return its
1950
-        if ($this->get_model()->has_primary_key_field()) {
1951
-            return $this->_fields[self::_get_primary_key_name(get_class($this))];
1952
-        } else {
1953
-            return $this->get_model()->get_index_primary_key_string($this->_fields);
1954
-        }
1955
-    }
1956
-
1957
-
1958
-
1959
-    /**
1960
-     * Adds a relationship to the specified EE_Base_Class object, given the relationship's name. Eg, if the current
1961
-     * model is related to a group of events, the $relationName should be 'Event', and should be a key in the EE
1962
-     * Model's $_model_relations array. If this model object doesn't exist in the DB, just caches the related thing
1963
-     *
1964
-     * @param mixed  $otherObjectModelObjectOrID       EE_Base_Class or the ID of the other object
1965
-     * @param string $relationName                     eg 'Events','Question',etc.
1966
-     *                                                 an attendee to a group, you also want to specify which role they
1967
-     *                                                 will have in that group. So you would use this parameter to
1968
-     *                                                 specify array('role-column-name'=>'role-id')
1969
-     * @param array  $extra_join_model_fields_n_values You can optionally include an array of key=>value pairs that
1970
-     *                                                 allow you to further constrict the relation to being added.
1971
-     *                                                 However, keep in mind that the columns (keys) given must match a
1972
-     *                                                 column on the JOIN table and currently only the HABTM models
1973
-     *                                                 accept these additional conditions.  Also remember that if an
1974
-     *                                                 exact match isn't found for these extra cols/val pairs, then a
1975
-     *                                                 NEW row is created in the join table.
1976
-     * @param null   $cache_id
1977
-     * @throws EE_Error
1978
-     * @return EE_Base_Class the object the relation was added to
1979
-     */
1980
-    public function _add_relation_to(
1981
-        $otherObjectModelObjectOrID,
1982
-        $relationName,
1983
-        $extra_join_model_fields_n_values = array(),
1984
-        $cache_id = null
1985
-    ) {
1986
-        //if this thing exists in the DB, save the relation to the DB
1987
-        if ($this->ID()) {
1988
-            $otherObject = $this->get_model()
1989
-                                ->add_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
1990
-                                    $extra_join_model_fields_n_values);
1991
-            //clear cache so future get_many_related and get_first_related() return new results.
1992
-            $this->clear_cache($relationName, $otherObject, true);
1993
-            if ($otherObject instanceof EE_Base_Class) {
1994
-                $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
1995
-            }
1996
-        } else {
1997
-            //this thing doesn't exist in the DB,  so just cache it
1998
-            if ( ! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
1999
-                throw new EE_Error(sprintf(
2000
-                    __('Before a model object is saved to the database, calls to _add_relation_to must be passed an actual object, not just an ID. You provided %s as the model object to a %s',
2001
-                        'event_espresso'),
2002
-                    $otherObjectModelObjectOrID,
2003
-                    get_class($this)
2004
-                ));
2005
-            } else {
2006
-                $otherObject = $otherObjectModelObjectOrID;
2007
-            }
2008
-            $this->cache($relationName, $otherObjectModelObjectOrID, $cache_id);
2009
-        }
2010
-        if ($otherObject instanceof EE_Base_Class) {
2011
-            //fix the reciprocal relation too
2012
-            if ($otherObject->ID()) {
2013
-                //its saved so assumed relations exist in the DB, so we can just
2014
-                //clear the cache so future queries use the updated info in the DB
2015
-                $otherObject->clear_cache($this->get_model()->get_this_model_name(), null, true);
2016
-            } else {
2017
-                //it's not saved, so it caches relations like this
2018
-                $otherObject->cache($this->get_model()->get_this_model_name(), $this);
2019
-            }
2020
-        }
2021
-        return $otherObject;
2022
-    }
2023
-
2024
-
2025
-
2026
-    /**
2027
-     * Removes a relationship to the specified EE_Base_Class object, given the relationships' name. Eg, if the current
2028
-     * model is related to a group of events, the $relationName should be 'Events', and should be a key in the EE
2029
-     * Model's $_model_relations array. If this model object doesn't exist in the DB, just removes the related thing
2030
-     * from the cache
2031
-     *
2032
-     * @param mixed  $otherObjectModelObjectOrID
2033
-     *                EE_Base_Class or the ID of the other object, OR an array key into the cache if this isn't saved
2034
-     *                to the DB yet
2035
-     * @param string $relationName
2036
-     * @param array  $where_query
2037
-     *                You can optionally include an array of key=>value pairs that allow you to further constrict the
2038
-     *                relation to being added. However, keep in mind that the columns (keys) given must match a column
2039
-     *                on the JOIN table and currently only the HABTM models accept these additional conditions. Also
2040
-     *                remember that if an exact match isn't found for these extra cols/val pairs, then a NEW row is
2041
-     *                created in the join table.
2042
-     * @return EE_Base_Class the relation was removed from
2043
-     * @throws \EE_Error
2044
-     */
2045
-    public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = array())
2046
-    {
2047
-        if ($this->ID()) {
2048
-            //if this exists in the DB, save the relation change to the DB too
2049
-            $otherObject = $this->get_model()
2050
-                                ->remove_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2051
-                                    $where_query);
2052
-            $this->clear_cache($relationName, $otherObject);
2053
-        } else {
2054
-            //this doesn't exist in the DB, just remove it from the cache
2055
-            $otherObject = $this->clear_cache($relationName, $otherObjectModelObjectOrID);
2056
-        }
2057
-        if ($otherObject instanceof EE_Base_Class) {
2058
-            $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2059
-        }
2060
-        return $otherObject;
2061
-    }
2062
-
2063
-
2064
-
2065
-    /**
2066
-     * Removes ALL the related things for the $relationName.
2067
-     *
2068
-     * @param string $relationName
2069
-     * @param array  $where_query_params like EEM_Base::get_all's $query_params[0] (where conditions)
2070
-     * @return EE_Base_Class
2071
-     * @throws \EE_Error
2072
-     */
2073
-    public function _remove_relations($relationName, $where_query_params = array())
2074
-    {
2075
-        if ($this->ID()) {
2076
-            //if this exists in the DB, save the relation change to the DB too
2077
-            $otherObjects = $this->get_model()->remove_relations($this, $relationName, $where_query_params);
2078
-            $this->clear_cache($relationName, null, true);
2079
-        } else {
2080
-            //this doesn't exist in the DB, just remove it from the cache
2081
-            $otherObjects = $this->clear_cache($relationName, null, true);
2082
-        }
2083
-        if (is_array($otherObjects)) {
2084
-            foreach ($otherObjects as $otherObject) {
2085
-                $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2086
-            }
2087
-        }
2088
-        return $otherObjects;
2089
-    }
2090
-
2091
-
2092
-
2093
-    /**
2094
-     * Gets all the related model objects of the specified type. Eg, if the current class if
2095
-     * EE_Event, you could call $this->get_many_related('Registration') to get an array of all the
2096
-     * EE_Registration objects which related to this event. Note: by default, we remove the "default query params"
2097
-     * because we want to get even deleted items etc.
2098
-     *
2099
-     * @param string $relationName key in the model's _model_relations array
2100
-     * @param array  $query_params like EEM_Base::get_all
2101
-     * @return EE_Base_Class[] Results not necessarily indexed by IDs, because some results might not have primary keys
2102
-     * @throws \EE_Error
2103
-     *                             or might not be saved yet. Consider using EEM_Base::get_IDs() on these results if
2104
-     *                             you want IDs
2105
-     */
2106
-    public function get_many_related($relationName, $query_params = array())
2107
-    {
2108
-        if ($this->ID()) {
2109
-            //this exists in the DB, so get the related things from either the cache or the DB
2110
-            //if there are query parameters, forget about caching the related model objects.
2111
-            if ($query_params) {
2112
-                $related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2113
-            } else {
2114
-                //did we already cache the result of this query?
2115
-                $cached_results = $this->get_all_from_cache($relationName);
2116
-                if ( ! $cached_results) {
2117
-                    $related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2118
-                    //if no query parameters were passed, then we got all the related model objects
2119
-                    //for that relation. We can cache them then.
2120
-                    foreach ($related_model_objects as $related_model_object) {
2121
-                        $this->cache($relationName, $related_model_object);
2122
-                    }
2123
-                } else {
2124
-                    $related_model_objects = $cached_results;
2125
-                }
2126
-            }
2127
-        } else {
2128
-            //this doesn't exist in the DB, so just get the related things from the cache
2129
-            $related_model_objects = $this->get_all_from_cache($relationName);
2130
-        }
2131
-        return $related_model_objects;
2132
-    }
2133
-
2134
-
2135
-
2136
-    /**
2137
-     * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default,
2138
-     * unless otherwise specified in the $query_params
2139
-     *
2140
-     * @param string $relation_name  model_name like 'Event', or 'Registration'
2141
-     * @param array  $query_params   like EEM_Base::get_all's
2142
-     * @param string $field_to_count name of field to count by. By default, uses primary key
2143
-     * @param bool   $distinct       if we want to only count the distinct values for the column then you can trigger
2144
-     *                               that by the setting $distinct to TRUE;
2145
-     * @return int
2146
-     */
2147
-    public function count_related($relation_name, $query_params = array(), $field_to_count = null, $distinct = false)
2148
-    {
2149
-        return $this->get_model()->count_related($this, $relation_name, $query_params, $field_to_count, $distinct);
2150
-    }
2151
-
2152
-
2153
-
2154
-    /**
2155
-     * Instead of getting the related model objects, simply sums up the values of the specified field.
2156
-     * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params
2157
-     *
2158
-     * @param string $relation_name model_name like 'Event', or 'Registration'
2159
-     * @param array  $query_params  like EEM_Base::get_all's
2160
-     * @param string $field_to_sum  name of field to count by.
2161
-     *                              By default, uses primary key (which doesn't make much sense, so you should probably
2162
-     *                              change it)
2163
-     * @return int
2164
-     */
2165
-    public function sum_related($relation_name, $query_params = array(), $field_to_sum = null)
2166
-    {
2167
-        return $this->get_model()->sum_related($this, $relation_name, $query_params, $field_to_sum);
2168
-    }
2169
-
2170
-
2171
-
2172
-    /**
2173
-     * Gets the first (ie, one) related model object of the specified type.
2174
-     *
2175
-     * @param string $relationName key in the model's _model_relations array
2176
-     * @param array  $query_params like EEM_Base::get_all
2177
-     * @return EE_Base_Class (not an array, a single object)
2178
-     * @throws \EE_Error
2179
-     */
2180
-    public function get_first_related($relationName, $query_params = array())
2181
-    {
2182
-        if ($this->ID()) {//this exists in the DB, get from the cache OR the DB
2183
-            //if they've provided some query parameters, don't bother trying to cache the result
2184
-            //also make sure we're not caching the result of get_first_related
2185
-            //on a relation which should have an array of objects (because the cache might have an array of objects)
2186
-            if ($query_params
2187
-                || ! $this->get_model()->related_settings_for($relationName)
2188
-                     instanceof
2189
-                     EE_Belongs_To_Relation
2190
-            ) {
2191
-                $related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2192
-            } else {
2193
-                //first, check if we've already cached the result of this query
2194
-                $cached_result = $this->get_one_from_cache($relationName);
2195
-                if ( ! $cached_result) {
2196
-                    $related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2197
-                    $this->cache($relationName, $related_model_object);
2198
-                } else {
2199
-                    $related_model_object = $cached_result;
2200
-                }
2201
-            }
2202
-        } else {
2203
-            $related_model_object = null;
2204
-            //this doesn't exist in the Db, but maybe the relation is of type belongs to, and so the related thing might
2205
-            if ($this->get_model()->related_settings_for($relationName) instanceof EE_Belongs_To_Relation) {
2206
-                $related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2207
-            }
2208
-            //this doesn't exist in the DB and apparently the thing it belongs to doesn't either, just get what's cached on this object
2209
-            if ( ! $related_model_object) {
2210
-                $related_model_object = $this->get_one_from_cache($relationName);
2211
-            }
2212
-        }
2213
-        return $related_model_object;
2214
-    }
2215
-
2216
-
2217
-
2218
-    /**
2219
-     * Does a delete on all related objects of type $relationName and removes
2220
-     * the current model object's relation to them. If they can't be deleted (because
2221
-     * of blocking related model objects) does nothing. If the related model objects are
2222
-     * soft-deletable, they will be soft-deleted regardless of related blocking model objects.
2223
-     * If this model object doesn't exist yet in the DB, just removes its related things
2224
-     *
2225
-     * @param string $relationName
2226
-     * @param array  $query_params like EEM_Base::get_all's
2227
-     * @return int how many deleted
2228
-     * @throws \EE_Error
2229
-     */
2230
-    public function delete_related($relationName, $query_params = array())
2231
-    {
2232
-        if ($this->ID()) {
2233
-            $count = $this->get_model()->delete_related($this, $relationName, $query_params);
2234
-        } else {
2235
-            $count = count($this->get_all_from_cache($relationName));
2236
-            $this->clear_cache($relationName, null, true);
2237
-        }
2238
-        return $count;
2239
-    }
2240
-
2241
-
2242
-
2243
-    /**
2244
-     * Does a hard delete (ie, removes the DB row) on all related objects of type $relationName and removes
2245
-     * the current model object's relation to them. If they can't be deleted (because
2246
-     * of blocking related model objects) just does a soft delete on it instead, if possible.
2247
-     * If the related thing isn't a soft-deletable model object, this function is identical
2248
-     * to delete_related(). If this model object doesn't exist in the DB, just remove its related things
2249
-     *
2250
-     * @param string $relationName
2251
-     * @param array  $query_params like EEM_Base::get_all's
2252
-     * @return int how many deleted (including those soft deleted)
2253
-     * @throws \EE_Error
2254
-     */
2255
-    public function delete_related_permanently($relationName, $query_params = array())
2256
-    {
2257
-        if ($this->ID()) {
2258
-            $count = $this->get_model()->delete_related_permanently($this, $relationName, $query_params);
2259
-        } else {
2260
-            $count = count($this->get_all_from_cache($relationName));
2261
-        }
2262
-        $this->clear_cache($relationName, null, true);
2263
-        return $count;
2264
-    }
2265
-
2266
-
2267
-
2268
-    /**
2269
-     * is_set
2270
-     * Just a simple utility function children can use for checking if property exists
2271
-     *
2272
-     * @access  public
2273
-     * @param  string $field_name property to check
2274
-     * @return bool                              TRUE if existing,FALSE if not.
2275
-     */
2276
-    public function is_set($field_name)
2277
-    {
2278
-        return isset($this->_fields[$field_name]);
2279
-    }
2280
-
2281
-
2282
-
2283
-    /**
2284
-     * Just a simple utility function children can use for checking if property (or properties) exists and throwing an
2285
-     * EE_Error exception if they don't
2286
-     *
2287
-     * @param  mixed (string|array) $properties properties to check
2288
-     * @throws EE_Error
2289
-     * @return bool                              TRUE if existing, throw EE_Error if not.
2290
-     */
2291
-    protected function _property_exists($properties)
2292
-    {
2293
-        foreach ((array)$properties as $property_name) {
2294
-            //first make sure this property exists
2295
-            if ( ! $this->_fields[$property_name]) {
2296
-                throw new EE_Error(
2297
-                    sprintf(
2298
-                        __(
2299
-                            'Trying to retrieve a non-existent property (%s).  Double check the spelling please',
2300
-                            'event_espresso'
2301
-                        ),
2302
-                        $property_name
2303
-                    )
2304
-                );
2305
-            }
2306
-        }
2307
-        return true;
2308
-    }
2309
-
2310
-
2311
-
2312
-    /**
2313
-     * This simply returns an array of model fields for this object
2314
-     *
2315
-     * @return array
2316
-     * @throws \EE_Error
2317
-     */
2318
-    public function model_field_array()
2319
-    {
2320
-        $fields = $this->get_model()->field_settings(false);
2321
-        $properties = array();
2322
-        //remove prepended underscore
2323
-        foreach ($fields as $field_name => $settings) {
2324
-            $properties[$field_name] = $this->get($field_name);
2325
-        }
2326
-        return $properties;
2327
-    }
2328
-
2329
-
2330
-
2331
-    /**
2332
-     * Very handy general function to allow for plugins to extend any child of EE_Base_Class.
2333
-     * If a method is called on a child of EE_Base_Class that doesn't exist, this function is called
2334
-     * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments. Instead of
2335
-     * requiring a plugin to extend the EE_Base_Class (which works fine is there's only 1 plugin, but when will that
2336
-     * happen?) they can add a hook onto 'filters_hook_espresso__{className}__{methodName}' (eg,
2337
-     * filters_hook_espresso__EE_Answer__my_great_function) and accepts 2 arguments: the object on which the function
2338
-     * was called, and an array of the original arguments passed to the function. Whatever their callback function
2339
-     * returns will be returned by this function. Example: in functions.php (or in a plugin):
2340
-     * add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3); function
2341
-     * my_callback($previousReturnValue,EE_Base_Class $object,$argsArray){
2342
-     * $returnString= "you called my_callback! and passed args:".implode(",",$argsArray);
2343
-     *        return $previousReturnValue.$returnString;
2344
-     * }
2345
-     * require('EE_Answer.class.php');
2346
-     * $answer= EE_Answer::new_instance(array('REG_ID' => 2,'QST_ID' => 3,'ANS_value' => The answer is 42'));
2347
-     * echo $answer->my_callback('monkeys',100);
2348
-     * //will output "you called my_callback! and passed args:monkeys,100"
2349
-     *
2350
-     * @param string $methodName name of method which was called on a child of EE_Base_Class, but which
2351
-     * @param array  $args       array of original arguments passed to the function
2352
-     * @throws EE_Error
2353
-     * @return mixed whatever the plugin which calls add_filter decides
2354
-     */
2355
-    public function __call($methodName, $args)
2356
-    {
2357
-        $className = get_class($this);
2358
-        $tagName = "FHEE__{$className}__{$methodName}";
2359
-        if ( ! has_filter($tagName)) {
2360
-            throw new EE_Error(
2361
-                sprintf(
2362
-                    __(
2363
-                        "Method %s on class %s does not exist! You can create one with the following code in functions.php or in a plugin: add_filter('%s','my_callback',10,3);function my_callback(\$previousReturnValue,EE_Base_Class \$object, \$argsArray){/*function body*/return \$whatever;}",
2364
-                        "event_espresso"
2365
-                    ),
2366
-                    $methodName,
2367
-                    $className,
2368
-                    $tagName
2369
-                )
2370
-            );
2371
-        }
2372
-        return apply_filters($tagName, null, $this, $args);
2373
-    }
2374
-
2375
-
2376
-
2377
-    /**
2378
-     * Similar to insert_post_meta, adds a record in the Extra_Meta model's table with the given key and value.
2379
-     * A $previous_value can be specified in case there are many meta rows with the same key
2380
-     *
2381
-     * @param string $meta_key
2382
-     * @param mixed  $meta_value
2383
-     * @param mixed  $previous_value
2384
-     * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2385
-     * @throws \EE_Error
2386
-     * NOTE: if the values haven't changed, returns 0
2387
-     */
2388
-    public function update_extra_meta($meta_key, $meta_value, $previous_value = null)
2389
-    {
2390
-        $query_params = array(
2391
-            array(
2392
-                'EXM_key'  => $meta_key,
2393
-                'OBJ_ID'   => $this->ID(),
2394
-                'EXM_type' => $this->get_model()->get_this_model_name(),
2395
-            ),
2396
-        );
2397
-        if ($previous_value !== null) {
2398
-            $query_params[0]['EXM_value'] = $meta_value;
2399
-        }
2400
-        $existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2401
-        if ( ! $existing_rows_like_that) {
2402
-            return $this->add_extra_meta($meta_key, $meta_value);
2403
-        }
2404
-        foreach ($existing_rows_like_that as $existing_row) {
2405
-            $existing_row->save(array('EXM_value' => $meta_value));
2406
-        }
2407
-        return count($existing_rows_like_that);
2408
-    }
2409
-
2410
-
2411
-
2412
-    /**
2413
-     * Adds a new extra meta record. If $unique is set to TRUE, we'll first double-check
2414
-     * no other extra meta for this model object have the same key. Returns TRUE if the
2415
-     * extra meta row was entered, false if not
2416
-     *
2417
-     * @param string  $meta_key
2418
-     * @param string  $meta_value
2419
-     * @param boolean $unique
2420
-     * @return boolean
2421
-     * @throws \EE_Error
2422
-     */
2423
-    public function add_extra_meta($meta_key, $meta_value, $unique = false)
2424
-    {
2425
-        if ($unique) {
2426
-            $existing_extra_meta = EEM_Extra_Meta::instance()->get_one(
2427
-                array(
2428
-                    array(
2429
-                        'EXM_key'  => $meta_key,
2430
-                        'OBJ_ID'   => $this->ID(),
2431
-                        'EXM_type' => $this->get_model()->get_this_model_name(),
2432
-                    ),
2433
-                )
2434
-            );
2435
-            if ($existing_extra_meta) {
2436
-                return false;
2437
-            }
2438
-        }
2439
-        $new_extra_meta = EE_Extra_Meta::new_instance(
2440
-            array(
2441
-                'EXM_key'   => $meta_key,
2442
-                'EXM_value' => $meta_value,
2443
-                'OBJ_ID'    => $this->ID(),
2444
-                'EXM_type'  => $this->get_model()->get_this_model_name(),
2445
-            )
2446
-        );
2447
-        $new_extra_meta->save();
2448
-        return true;
2449
-    }
2450
-
2451
-
2452
-
2453
-    /**
2454
-     * Deletes all the extra meta rows for this record as specified by key. If $meta_value
2455
-     * is specified, only deletes extra meta records with that value.
2456
-     *
2457
-     * @param string $meta_key
2458
-     * @param string $meta_value
2459
-     * @return int number of extra meta rows deleted
2460
-     * @throws \EE_Error
2461
-     */
2462
-    public function delete_extra_meta($meta_key, $meta_value = null)
2463
-    {
2464
-        $query_params = array(
2465
-            array(
2466
-                'EXM_key'  => $meta_key,
2467
-                'OBJ_ID'   => $this->ID(),
2468
-                'EXM_type' => $this->get_model()->get_this_model_name(),
2469
-            ),
2470
-        );
2471
-        if ($meta_value !== null) {
2472
-            $query_params[0]['EXM_value'] = $meta_value;
2473
-        }
2474
-        return EEM_Extra_Meta::instance()->delete($query_params);
2475
-    }
2476
-
2477
-
2478
-
2479
-    /**
2480
-     * Gets the extra meta with the given meta key. If you specify "single" we just return 1, otherwise
2481
-     * an array of everything found. Requires that this model actually have a relation of type EE_Has_Many_Any_Relation.
2482
-     * You can specify $default is case you haven't found the extra meta
2483
-     *
2484
-     * @param string  $meta_key
2485
-     * @param boolean $single
2486
-     * @param mixed   $default if we don't find anything, what should we return?
2487
-     * @return mixed single value if $single; array if ! $single
2488
-     * @throws \EE_Error
2489
-     */
2490
-    public function get_extra_meta($meta_key, $single = false, $default = null)
2491
-    {
2492
-        if ($single) {
2493
-            $result = $this->get_first_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2494
-            if ($result instanceof EE_Extra_Meta) {
2495
-                return $result->value();
2496
-            } else {
2497
-                return $default;
2498
-            }
2499
-        } else {
2500
-            $results = $this->get_many_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2501
-            if ($results) {
2502
-                $values = array();
2503
-                foreach ($results as $result) {
2504
-                    if ($result instanceof EE_Extra_Meta) {
2505
-                        $values[$result->ID()] = $result->value();
2506
-                    }
2507
-                }
2508
-                return $values;
2509
-            } else {
2510
-                return $default;
2511
-            }
2512
-        }
2513
-    }
2514
-
2515
-
2516
-
2517
-    /**
2518
-     * Returns a simple array of all the extra meta associated with this model object.
2519
-     * If $one_of_each_key is true (Default), it will be an array of simple key-value pairs, keys being the
2520
-     * extra meta's key, and teh value being its value. However, if there are duplicate extra meta rows with
2521
-     * the same key, only one will be used. (eg array('foo'=>'bar','monkey'=>123))
2522
-     * If $one_of_each_key is false, it will return an array with the top-level keys being
2523
-     * the extra meta keys, but their values are also arrays, which have the extra-meta's ID as their sub-key, and
2524
-     * finally the extra meta's value as each sub-value. (eg
2525
-     * array('foo'=>array(1=>'bar',2=>'bill'),'monkey'=>array(3=>123)))
2526
-     *
2527
-     * @param boolean $one_of_each_key
2528
-     * @return array
2529
-     * @throws \EE_Error
2530
-     */
2531
-    public function all_extra_meta_array($one_of_each_key = true)
2532
-    {
2533
-        $return_array = array();
2534
-        if ($one_of_each_key) {
2535
-            $extra_meta_objs = $this->get_many_related('Extra_Meta', array('group_by' => 'EXM_key'));
2536
-            foreach ($extra_meta_objs as $extra_meta_obj) {
2537
-                if ($extra_meta_obj instanceof EE_Extra_Meta) {
2538
-                    $return_array[$extra_meta_obj->key()] = $extra_meta_obj->value();
2539
-                }
2540
-            }
2541
-        } else {
2542
-            $extra_meta_objs = $this->get_many_related('Extra_Meta');
2543
-            foreach ($extra_meta_objs as $extra_meta_obj) {
2544
-                if ($extra_meta_obj instanceof EE_Extra_Meta) {
2545
-                    if ( ! isset($return_array[$extra_meta_obj->key()])) {
2546
-                        $return_array[$extra_meta_obj->key()] = array();
2547
-                    }
2548
-                    $return_array[$extra_meta_obj->key()][$extra_meta_obj->ID()] = $extra_meta_obj->value();
2549
-                }
2550
-            }
2551
-        }
2552
-        return $return_array;
2553
-    }
2554
-
2555
-
2556
-
2557
-    /**
2558
-     * Gets a pretty nice displayable nice for this model object. Often overridden
2559
-     *
2560
-     * @return string
2561
-     * @throws \EE_Error
2562
-     */
2563
-    public function name()
2564
-    {
2565
-        //find a field that's not a text field
2566
-        $field_we_can_use = $this->get_model()->get_a_field_of_type('EE_Text_Field_Base');
2567
-        if ($field_we_can_use) {
2568
-            return $this->get($field_we_can_use->get_name());
2569
-        } else {
2570
-            $first_few_properties = $this->model_field_array();
2571
-            $first_few_properties = array_slice($first_few_properties, 0, 3);
2572
-            $name_parts = array();
2573
-            foreach ($first_few_properties as $name => $value) {
2574
-                $name_parts[] = "$name:$value";
2575
-            }
2576
-            return implode(",", $name_parts);
2577
-        }
2578
-    }
2579
-
2580
-
2581
-
2582
-    /**
2583
-     * in_entity_map
2584
-     * Checks if this model object has been proven to already be in the entity map
2585
-     *
2586
-     * @return boolean
2587
-     * @throws \EE_Error
2588
-     */
2589
-    public function in_entity_map()
2590
-    {
2591
-        if ($this->ID() && $this->get_model()->get_from_entity_map($this->ID()) === $this) {
2592
-            //well, if we looked, did we find it in the entity map?
2593
-            return true;
2594
-        } else {
2595
-            return false;
2596
-        }
2597
-    }
2598
-
2599
-
2600
-
2601
-    /**
2602
-     * refresh_from_db
2603
-     * Makes sure the fields and values on this model object are in-sync with what's in the database.
2604
-     *
2605
-     * @throws EE_Error if this model object isn't in the entity mapper (because then you should
2606
-     * just use what's in the entity mapper and refresh it) and WP_DEBUG is TRUE
2607
-     */
2608
-    public function refresh_from_db()
2609
-    {
2610
-        if ($this->ID() && $this->in_entity_map()) {
2611
-            $this->get_model()->refresh_entity_map_from_db($this->ID());
2612
-        } else {
2613
-            //if it doesn't have ID, you shouldn't be asking to refresh it from teh database (because its not in the database)
2614
-            //if it has an ID but it's not in the map, and you're asking me to refresh it
2615
-            //that's kinda dangerous. You should just use what's in the entity map, or add this to the entity map if there's
2616
-            //absolutely nothing in it for this ID
2617
-            if (WP_DEBUG) {
2618
-                throw new EE_Error(
2619
-                    sprintf(
2620
-                        __('Trying to refresh a model object with ID "%1$s" that\'s not in the entity map? First off: you should put it in the entity map by calling %2$s. Second off, if you want what\'s in the database right now, you should just call %3$s yourself and discard this model object.',
2621
-                            'event_espresso'),
2622
-                        $this->ID(),
2623
-                        get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2624
-                        get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2625
-                    )
2626
-                );
2627
-            }
2628
-        }
2629
-    }
2630
-
2631
-
2632
-
2633
-    /**
2634
-     * Because some other plugins, like Advanced Cron Manager, expect all objects to have this method
2635
-     * (probably a bad assumption they have made, oh well)
2636
-     *
2637
-     * @return string
2638
-     */
2639
-    public function __toString()
2640
-    {
2641
-        try {
2642
-            return sprintf('%s (%s)', $this->name(), $this->ID());
2643
-        } catch (Exception $e) {
2644
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2645
-            return '';
2646
-        }
2647
-    }
2648
-
2649
-
2650
-
2651
-    /**
2652
-     * Clear related model objects if they're already in the DB, because otherwise when we
2653
-     * UN-serialize this model object we'll need to be careful to add them to the entity map.
2654
-     * This means if we have made changes to those related model objects, and want to unserialize
2655
-     * the this model object on a subsequent request, changes to those related model objects will be lost.
2656
-     * Instead, those related model objects should be directly serialized and stored.
2657
-     * Eg, the following won't work:
2658
-     * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2659
-     * $att = $reg->attendee();
2660
-     * $att->set( 'ATT_fname', 'Dirk' );
2661
-     * update_option( 'my_option', serialize( $reg ) );
2662
-     * //END REQUEST
2663
-     * //START NEXT REQUEST
2664
-     * $reg = get_option( 'my_option' );
2665
-     * $reg->attendee()->save();
2666
-     * And would need to be replace with:
2667
-     * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2668
-     * $att = $reg->attendee();
2669
-     * $att->set( 'ATT_fname', 'Dirk' );
2670
-     * update_option( 'my_option', serialize( $reg ) );
2671
-     * //END REQUEST
2672
-     * //START NEXT REQUEST
2673
-     * $att = get_option( 'my_option' );
2674
-     * $att->save();
2675
-     *
2676
-     * @return array
2677
-     * @throws \EE_Error
2678
-     */
2679
-    public function __sleep()
2680
-    {
2681
-        foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
2682
-            if ($relation_obj instanceof EE_Belongs_To_Relation) {
2683
-                $classname = 'EE_' . $this->get_model()->get_this_model_name();
2684
-                if (
2685
-                    $this->get_one_from_cache($relation_name) instanceof $classname
2686
-                    && $this->get_one_from_cache($relation_name)->ID()
2687
-                ) {
2688
-                    $this->clear_cache($relation_name, $this->get_one_from_cache($relation_name)->ID());
2689
-                }
2690
-            }
2691
-        }
2692
-        $this->_props_n_values_provided_in_constructor = array();
2693
-        return array_keys(get_object_vars($this));
2694
-    }
2695
-
2696
-
2697
-
2698
-    /**
2699
-     * restore _props_n_values_provided_in_constructor
2700
-     * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
2701
-     * and therefore should NOT be used to determine if state change has occurred since initial construction.
2702
-     * At best, you would only be able to detect if state change has occurred during THIS request.
2703
-     */
2704
-    public function __wakeup()
2705
-    {
2706
-        $this->_props_n_values_provided_in_constructor = $this->_fields;
2707
-    }
28
+	/**
29
+	 * This is an array of the original properties and values provided during construction
30
+	 * of this model object. (keys are model field names, values are their values).
31
+	 * This list is important to remember so that when we are merging data from the db, we know
32
+	 * which values to override and which to not override.
33
+	 *
34
+	 * @var array
35
+	 */
36
+	protected $_props_n_values_provided_in_constructor;
37
+
38
+	/**
39
+	 * Timezone
40
+	 * This gets set by the "set_timezone()" method so that we know what timezone incoming strings|timestamps are in.
41
+	 * This can also be used before a get to set what timezone you want strings coming out of the object to be in.  NOT
42
+	 * all EE_Base_Class child classes use this property but any that use a EE_Datetime_Field data type will have
43
+	 * access to it.
44
+	 *
45
+	 * @var string
46
+	 */
47
+	protected $_timezone;
48
+
49
+
50
+
51
+	/**
52
+	 * date format
53
+	 * pattern or format for displaying dates
54
+	 *
55
+	 * @var string $_dt_frmt
56
+	 */
57
+	protected $_dt_frmt;
58
+
59
+
60
+
61
+	/**
62
+	 * time format
63
+	 * pattern or format for displaying time
64
+	 *
65
+	 * @var string $_tm_frmt
66
+	 */
67
+	protected $_tm_frmt;
68
+
69
+
70
+
71
+	/**
72
+	 * This property is for holding a cached array of object properties indexed by property name as the key.
73
+	 * The purpose of this is for setting a cache on properties that may have calculated values after a
74
+	 * prepare_for_get.  That way the cache can be checked first and the calculated property returned instead of having
75
+	 * to recalculate. Used by _set_cached_property() and _get_cached_property() methods.
76
+	 *
77
+	 * @var array
78
+	 */
79
+	protected $_cached_properties = array();
80
+
81
+	/**
82
+	 * An array containing keys of the related model, and values are either an array of related mode objects or a
83
+	 * single
84
+	 * related model object. see the model's _model_relations. The keys should match those specified. And if the
85
+	 * relation is of type EE_Belongs_To (or one of its children), then there should only be ONE related model object,
86
+	 * all others have an array)
87
+	 *
88
+	 * @var array
89
+	 */
90
+	protected $_model_relations = array();
91
+
92
+	/**
93
+	 * Array where keys are field names (see the model's _fields property) and values are their values. To see what
94
+	 * their types should be, look at what that field object returns on its prepare_for_get and prepare_for_set methods)
95
+	 *
96
+	 * @var array
97
+	 */
98
+	protected $_fields = array();
99
+
100
+	/**
101
+	 * @var boolean indicating whether or not this model object is intended to ever be saved
102
+	 * For example, we might create model objects intended to only be used for the duration
103
+	 * of this request and to be thrown away, and if they were accidentally saved
104
+	 * it would be a bug.
105
+	 */
106
+	protected $_allow_persist = true;
107
+
108
+	/**
109
+	 * @var boolean indicating whether or not this model object's properties have changed since construction
110
+	 */
111
+	protected $_has_changes = false;
112
+
113
+
114
+
115
+	/**
116
+	 * basic constructor for Event Espresso classes, performs any necessary initialization, and verifies it's children
117
+	 * play nice
118
+	 *
119
+	 * @param array   $fieldValues                             where each key is a field (ie, array key in the 2nd
120
+	 *                                                         layer of the model's _fields array, (eg, EVT_ID,
121
+	 *                                                         TXN_amount, QST_name, etc) and values are their values
122
+	 * @param boolean $bydb                                    a flag for setting if the class is instantiated by the
123
+	 *                                                         corresponding db model or not.
124
+	 * @param string  $timezone                                indicate what timezone you want any datetime fields to
125
+	 *                                                         be in when instantiating a EE_Base_Class object.
126
+	 * @param array   $date_formats                            An array of date formats to set on construct where first
127
+	 *                                                         value is the date_format and second value is the time
128
+	 *                                                         format.
129
+	 * @throws EE_Error
130
+	 */
131
+	protected function __construct($fieldValues = array(), $bydb = false, $timezone = '', $date_formats = array())
132
+	{
133
+		$className = get_class($this);
134
+		do_action("AHEE__{$className}__construct", $this, $fieldValues);
135
+		$model = $this->get_model();
136
+		$model_fields = $model->field_settings(false);
137
+		// ensure $fieldValues is an array
138
+		$fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
139
+		// EEH_Debug_Tools::printr( $fieldValues, '$fieldValues  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
140
+		// verify client code has not passed any invalid field names
141
+		foreach ($fieldValues as $field_name => $field_value) {
142
+			if ( ! isset($model_fields[$field_name])) {
143
+				throw new EE_Error(sprintf(__("Invalid field (%s) passed to constructor of %s. Allowed fields are :%s",
144
+					"event_espresso"), $field_name, get_class($this), implode(", ", array_keys($model_fields))));
145
+			}
146
+		}
147
+		// EEH_Debug_Tools::printr( $model_fields, '$model_fields  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
148
+		$this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
149
+		if ( ! empty($date_formats) && is_array($date_formats)) {
150
+			list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
151
+		} else {
152
+			//set default formats for date and time
153
+			$this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
154
+			$this->_tm_frmt = (string)get_option('time_format', 'g:i a');
155
+		}
156
+		//if db model is instantiating
157
+		if ($bydb) {
158
+			//client code has indicated these field values are from the database
159
+			foreach ($model_fields as $fieldName => $field) {
160
+				$this->set_from_db($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null);
161
+			}
162
+		} else {
163
+			//we're constructing a brand
164
+			//new instance of the model object. Generally, this means we'll need to do more field validation
165
+			foreach ($model_fields as $fieldName => $field) {
166
+				$this->set($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null, true);
167
+			}
168
+		}
169
+		//remember what values were passed to this constructor
170
+		$this->_props_n_values_provided_in_constructor = $fieldValues;
171
+		//remember in entity mapper
172
+		if ( ! $bydb && $model->has_primary_key_field() && $this->ID()) {
173
+			$model->add_to_entity_map($this);
174
+		}
175
+		//setup all the relations
176
+		foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
177
+			if ($relation_obj instanceof EE_Belongs_To_Relation) {
178
+				$this->_model_relations[$relation_name] = null;
179
+			} else {
180
+				$this->_model_relations[$relation_name] = array();
181
+			}
182
+		}
183
+		/**
184
+		 * Action done at the end of each model object construction
185
+		 *
186
+		 * @param EE_Base_Class $this the model object just created
187
+		 */
188
+		do_action('AHEE__EE_Base_Class__construct__finished', $this);
189
+	}
190
+
191
+
192
+
193
+	/**
194
+	 * Gets whether or not this model object is allowed to persist/be saved to the database.
195
+	 *
196
+	 * @return boolean
197
+	 */
198
+	public function allow_persist()
199
+	{
200
+		return $this->_allow_persist;
201
+	}
202
+
203
+
204
+
205
+	/**
206
+	 * Sets whether or not this model object should be allowed to be saved to the DB.
207
+	 * Normally once this is set to FALSE you wouldn't set it back to TRUE, unless
208
+	 * you got new information that somehow made you change your mind.
209
+	 *
210
+	 * @param boolean $allow_persist
211
+	 * @return boolean
212
+	 */
213
+	public function set_allow_persist($allow_persist)
214
+	{
215
+		return $this->_allow_persist = $allow_persist;
216
+	}
217
+
218
+
219
+
220
+	/**
221
+	 * Gets the field's original value when this object was constructed during this request.
222
+	 * This can be helpful when determining if a model object has changed or not
223
+	 *
224
+	 * @param string $field_name
225
+	 * @return mixed|null
226
+	 * @throws \EE_Error
227
+	 */
228
+	public function get_original($field_name)
229
+	{
230
+		if (isset($this->_props_n_values_provided_in_constructor[$field_name])
231
+			&& $field_settings = $this->get_model()->field_settings_for($field_name)
232
+		) {
233
+			return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[$field_name]);
234
+		} else {
235
+			return null;
236
+		}
237
+	}
238
+
239
+
240
+
241
+	/**
242
+	 * @param EE_Base_Class $obj
243
+	 * @return string
244
+	 */
245
+	public function get_class($obj)
246
+	{
247
+		return get_class($obj);
248
+	}
249
+
250
+
251
+
252
+	/**
253
+	 * Overrides parent because parent expects old models.
254
+	 * This also doesn't do any validation, and won't work for serialized arrays
255
+	 *
256
+	 * @param    string $field_name
257
+	 * @param    mixed  $field_value
258
+	 * @param bool      $use_default
259
+	 * @throws \EE_Error
260
+	 */
261
+	public function set($field_name, $field_value, $use_default = false)
262
+	{
263
+		// if not using default and nothing has changed, and object has already been setup (has ID),
264
+		// then don't do anything
265
+		if (
266
+			! $use_default
267
+			&& $this->_fields[$field_name] === $field_value
268
+			&& $this->ID()
269
+		) {
270
+			return;
271
+		}
272
+		$this->_has_changes = true;
273
+		$field_obj = $this->get_model()->field_settings_for($field_name);
274
+		if ($field_obj instanceof EE_Model_Field_Base) {
275
+			//			if ( method_exists( $field_obj, 'set_timezone' )) {
276
+			if ($field_obj instanceof EE_Datetime_Field) {
277
+				$field_obj->set_timezone($this->_timezone);
278
+				$field_obj->set_date_format($this->_dt_frmt);
279
+				$field_obj->set_time_format($this->_tm_frmt);
280
+			}
281
+			$holder_of_value = $field_obj->prepare_for_set($field_value);
282
+			//should the value be null?
283
+			if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
284
+				$this->_fields[$field_name] = $field_obj->get_default_value();
285
+				/**
286
+				 * To save having to refactor all the models, if a default value is used for a
287
+				 * EE_Datetime_Field, and that value is not null nor is it a DateTime
288
+				 * object.  Then let's do a set again to ensure that it becomes a DateTime
289
+				 * object.
290
+				 *
291
+				 * @since 4.6.10+
292
+				 */
293
+				if (
294
+					$field_obj instanceof EE_Datetime_Field
295
+					&& $this->_fields[$field_name] !== null
296
+					&& ! $this->_fields[$field_name] instanceof DateTime
297
+				) {
298
+					empty($this->_fields[$field_name])
299
+						? $this->set($field_name, time())
300
+						: $this->set($field_name, $this->_fields[$field_name]);
301
+				}
302
+			} else {
303
+				$this->_fields[$field_name] = $holder_of_value;
304
+			}
305
+			//if we're not in the constructor...
306
+			//now check if what we set was a primary key
307
+			if (
308
+				//note: props_n_values_provided_in_constructor is only set at the END of the constructor
309
+				$this->_props_n_values_provided_in_constructor
310
+				&& $field_value
311
+				&& $field_name === self::_get_primary_key_name(get_class($this))
312
+			) {
313
+				//if so, we want all this object's fields to be filled either with
314
+				//what we've explicitly set on this model
315
+				//or what we have in the db
316
+				// echo "setting primary key!";
317
+				$fields_on_model = self::_get_model(get_class($this))->field_settings();
318
+				$obj_in_db = self::_get_model(get_class($this))->get_one_by_ID($field_value);
319
+				foreach ($fields_on_model as $field_obj) {
320
+					if ( ! array_key_exists($field_obj->get_name(), $this->_props_n_values_provided_in_constructor)
321
+						 && $field_obj->get_name() !== $field_name
322
+					) {
323
+						$this->set($field_obj->get_name(), $obj_in_db->get($field_obj->get_name()));
324
+					}
325
+				}
326
+				//oh this model object has an ID? well make sure its in the entity mapper
327
+				$this->get_model()->add_to_entity_map($this);
328
+			}
329
+			//let's unset any cache for this field_name from the $_cached_properties property.
330
+			$this->_clear_cached_property($field_name);
331
+		} else {
332
+			throw new EE_Error(sprintf(__("A valid EE_Model_Field_Base could not be found for the given field name: %s",
333
+				"event_espresso"), $field_name));
334
+		}
335
+	}
336
+
337
+
338
+
339
+	/**
340
+	 * This sets the field value on the db column if it exists for the given $column_name or
341
+	 * saves it to EE_Extra_Meta if the given $column_name does not match a db column.
342
+	 *
343
+	 * @see EE_message::get_column_value for related documentation on the necessity of this method.
344
+	 * @param string $field_name  Must be the exact column name.
345
+	 * @param mixed  $field_value The value to set.
346
+	 * @return int|bool @see EE_Base_Class::update_extra_meta() for return docs.
347
+	 * @throws \EE_Error
348
+	 */
349
+	public function set_field_or_extra_meta($field_name, $field_value)
350
+	{
351
+		if ($this->get_model()->has_field($field_name)) {
352
+			$this->set($field_name, $field_value);
353
+			return true;
354
+		} else {
355
+			//ensure this object is saved first so that extra meta can be properly related.
356
+			$this->save();
357
+			return $this->update_extra_meta($field_name, $field_value);
358
+		}
359
+	}
360
+
361
+
362
+
363
+	/**
364
+	 * This retrieves the value of the db column set on this class or if that's not present
365
+	 * it will attempt to retrieve from extra_meta if found.
366
+	 * Example Usage:
367
+	 * Via EE_Message child class:
368
+	 * Due to the dynamic nature of the EE_messages system, EE_messengers will always have a "to",
369
+	 * "from", "subject", and "content" field (as represented in the EE_Message schema), however they may
370
+	 * also have additional main fields specific to the messenger.  The system accommodates those extra
371
+	 * fields through the EE_Extra_Meta table.  This method allows for EE_messengers to retrieve the
372
+	 * value for those extra fields dynamically via the EE_message object.
373
+	 *
374
+	 * @param  string $field_name expecting the fully qualified field name.
375
+	 * @return mixed|null  value for the field if found.  null if not found.
376
+	 * @throws \EE_Error
377
+	 */
378
+	public function get_field_or_extra_meta($field_name)
379
+	{
380
+		if ($this->get_model()->has_field($field_name)) {
381
+			$column_value = $this->get($field_name);
382
+		} else {
383
+			//This isn't a column in the main table, let's see if it is in the extra meta.
384
+			$column_value = $this->get_extra_meta($field_name, true, null);
385
+		}
386
+		return $column_value;
387
+	}
388
+
389
+
390
+
391
+	/**
392
+	 * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
393
+	 * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
394
+	 * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
395
+	 * available to all child classes that may be using the EE_Datetime_Field for a field data type.
396
+	 *
397
+	 * @access public
398
+	 * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
399
+	 * @return void
400
+	 * @throws \EE_Error
401
+	 */
402
+	public function set_timezone($timezone = '')
403
+	{
404
+		$this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
405
+		//make sure we clear all cached properties because they won't be relevant now
406
+		$this->_clear_cached_properties();
407
+		//make sure we update field settings and the date for all EE_Datetime_Fields
408
+		$model_fields = $this->get_model()->field_settings(false);
409
+		foreach ($model_fields as $field_name => $field_obj) {
410
+			if ($field_obj instanceof EE_Datetime_Field) {
411
+				$field_obj->set_timezone($this->_timezone);
412
+				if (isset($this->_fields[$field_name]) && $this->_fields[$field_name] instanceof DateTime) {
413
+					$this->_fields[$field_name]->setTimezone(new DateTimeZone($this->_timezone));
414
+				}
415
+			}
416
+		}
417
+	}
418
+
419
+
420
+
421
+	/**
422
+	 * This just returns whatever is set for the current timezone.
423
+	 *
424
+	 * @access public
425
+	 * @return string timezone string
426
+	 */
427
+	public function get_timezone()
428
+	{
429
+		return $this->_timezone;
430
+	}
431
+
432
+
433
+
434
+	/**
435
+	 * This sets the internal date format to what is sent in to be used as the new default for the class
436
+	 * internally instead of wp set date format options
437
+	 *
438
+	 * @since 4.6
439
+	 * @param string $format should be a format recognizable by PHP date() functions.
440
+	 */
441
+	public function set_date_format($format)
442
+	{
443
+		$this->_dt_frmt = $format;
444
+		//clear cached_properties because they won't be relevant now.
445
+		$this->_clear_cached_properties();
446
+	}
447
+
448
+
449
+
450
+	/**
451
+	 * This sets the internal time format string to what is sent in to be used as the new default for the
452
+	 * class internally instead of wp set time format options.
453
+	 *
454
+	 * @since 4.6
455
+	 * @param string $format should be a format recognizable by PHP date() functions.
456
+	 */
457
+	public function set_time_format($format)
458
+	{
459
+		$this->_tm_frmt = $format;
460
+		//clear cached_properties because they won't be relevant now.
461
+		$this->_clear_cached_properties();
462
+	}
463
+
464
+
465
+
466
+	/**
467
+	 * This returns the current internal set format for the date and time formats.
468
+	 *
469
+	 * @param bool $full           if true (default), then return the full format.  Otherwise will return an array
470
+	 *                             where the first value is the date format and the second value is the time format.
471
+	 * @return mixed string|array
472
+	 */
473
+	public function get_format($full = true)
474
+	{
475
+		return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
476
+	}
477
+
478
+
479
+
480
+	/**
481
+	 * cache
482
+	 * stores the passed model object on the current model object.
483
+	 * In certain circumstances, we can use this cached model object instead of querying for another one entirely.
484
+	 *
485
+	 * @param string        $relationName    one of the keys in the _model_relations array on the model. Eg
486
+	 *                                       'Registration' associated with this model object
487
+	 * @param EE_Base_Class $object_to_cache that has a relation to this model object. (Eg, if this is a Transaction,
488
+	 *                                       that could be a payment or a registration)
489
+	 * @param null          $cache_id        a string or number that will be used as the key for any Belongs_To_Many
490
+	 *                                       items which will be stored in an array on this object
491
+	 * @throws EE_Error
492
+	 * @return mixed    index into cache, or just TRUE if the relation is of type Belongs_To (because there's only one
493
+	 *                  related thing, no array)
494
+	 */
495
+	public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
496
+	{
497
+		// its entirely possible that there IS no related object yet in which case there is nothing to cache.
498
+		if ( ! $object_to_cache instanceof EE_Base_Class) {
499
+			return false;
500
+		}
501
+		// also get "how" the object is related, or throw an error
502
+		if ( ! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
503
+			throw new EE_Error(sprintf(__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
504
+				$relationName, get_class($this)));
505
+		}
506
+		// how many things are related ?
507
+		if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
508
+			// if it's a "belongs to" relationship, then there's only one related model object  eg, if this is a registration, there's only 1 attendee for it
509
+			// so for these model objects just set it to be cached
510
+			$this->_model_relations[$relationName] = $object_to_cache;
511
+			$return = true;
512
+		} else {
513
+			// otherwise, this is the "many" side of a one to many relationship, so we'll add the object to the array of related objects for that type.
514
+			// eg: if this is an event, there are many registrations for that event, so we cache the registrations in an array
515
+			if ( ! is_array($this->_model_relations[$relationName])) {
516
+				// if for some reason, the cached item is a model object, then stick that in the array, otherwise start with an empty array
517
+				$this->_model_relations[$relationName] = $this->_model_relations[$relationName] instanceof EE_Base_Class
518
+					? array($this->_model_relations[$relationName]) : array();
519
+			}
520
+			// first check for a cache_id which is normally empty
521
+			if ( ! empty($cache_id)) {
522
+				// if the cache_id exists, then it means we are purposely trying to cache this with a known key that can then be used to retrieve the object later on
523
+				$this->_model_relations[$relationName][$cache_id] = $object_to_cache;
524
+				$return = $cache_id;
525
+			} elseif ($object_to_cache->ID()) {
526
+				// OR the cached object originally came from the db, so let's just use it's PK for an ID
527
+				$this->_model_relations[$relationName][$object_to_cache->ID()] = $object_to_cache;
528
+				$return = $object_to_cache->ID();
529
+			} else {
530
+				// OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
531
+				$this->_model_relations[$relationName][] = $object_to_cache;
532
+				// move the internal pointer to the end of the array
533
+				end($this->_model_relations[$relationName]);
534
+				// and grab the key so that we can return it
535
+				$return = key($this->_model_relations[$relationName]);
536
+			}
537
+		}
538
+		return $return;
539
+	}
540
+
541
+
542
+
543
+	/**
544
+	 * For adding an item to the cached_properties property.
545
+	 *
546
+	 * @access protected
547
+	 * @param string      $fieldname the property item the corresponding value is for.
548
+	 * @param mixed       $value     The value we are caching.
549
+	 * @param string|null $cache_type
550
+	 * @return void
551
+	 * @throws \EE_Error
552
+	 */
553
+	protected function _set_cached_property($fieldname, $value, $cache_type = null)
554
+	{
555
+		//first make sure this property exists
556
+		$this->get_model()->field_settings_for($fieldname);
557
+		$cache_type = empty($cache_type) ? 'standard' : $cache_type;
558
+		$this->_cached_properties[$fieldname][$cache_type] = $value;
559
+	}
560
+
561
+
562
+
563
+	/**
564
+	 * This returns the value cached property if it exists OR the actual property value if the cache doesn't exist.
565
+	 * This also SETS the cache if we return the actual property!
566
+	 *
567
+	 * @param string $fieldname        the name of the property we're trying to retrieve
568
+	 * @param bool   $pretty
569
+	 * @param string $extra_cache_ref  This allows the user to specify an extra cache ref for the given property
570
+	 *                                 (in cases where the same property may be used for different outputs
571
+	 *                                 - i.e. datetime, money etc.)
572
+	 *                                 It can also accept certain pre-defined "schema" strings
573
+	 *                                 to define how to output the property.
574
+	 *                                 see the field's prepare_for_pretty_echoing for what strings can be used
575
+	 * @return mixed                   whatever the value for the property is we're retrieving
576
+	 * @throws \EE_Error
577
+	 */
578
+	protected function _get_cached_property($fieldname, $pretty = false, $extra_cache_ref = null)
579
+	{
580
+		//verify the field exists
581
+		$this->get_model()->field_settings_for($fieldname);
582
+		$cache_type = $pretty ? 'pretty' : 'standard';
583
+		$cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
584
+		if (isset($this->_cached_properties[$fieldname][$cache_type])) {
585
+			return $this->_cached_properties[$fieldname][$cache_type];
586
+		}
587
+		$value = $this->_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
588
+		$this->_set_cached_property($fieldname, $value, $cache_type);
589
+		return $value;
590
+	}
591
+
592
+
593
+
594
+	/**
595
+	 * If the cache didn't fetch the needed item, this fetches it.
596
+	 * @param string $fieldname
597
+	 * @param bool $pretty
598
+	 * @param string $extra_cache_ref
599
+	 * @return mixed
600
+	 */
601
+	protected function _get_fresh_property($fieldname, $pretty = false, $extra_cache_ref = null)
602
+	{
603
+		$field_obj = $this->get_model()->field_settings_for($fieldname);
604
+		// If this is an EE_Datetime_Field we need to make sure timezone, formats, and output are correct
605
+		if ($field_obj instanceof EE_Datetime_Field) {
606
+			$this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
607
+		}
608
+		if ( ! isset($this->_fields[$fieldname])) {
609
+			$this->_fields[$fieldname] = null;
610
+		}
611
+		$value = $pretty
612
+			? $field_obj->prepare_for_pretty_echoing($this->_fields[$fieldname], $extra_cache_ref)
613
+			: $field_obj->prepare_for_get($this->_fields[$fieldname]);
614
+		return $value;
615
+	}
616
+
617
+
618
+
619
+	/**
620
+	 * set timezone, formats, and output for EE_Datetime_Field objects
621
+	 *
622
+	 * @param \EE_Datetime_Field $datetime_field
623
+	 * @param bool               $pretty
624
+	 * @param null $date_or_time
625
+	 * @return void
626
+	 * @throws \EE_Error
627
+	 */
628
+	protected function _prepare_datetime_field(
629
+		EE_Datetime_Field $datetime_field,
630
+		$pretty = false,
631
+		$date_or_time = null
632
+	) {
633
+		$datetime_field->set_timezone($this->_timezone);
634
+		$datetime_field->set_date_format($this->_dt_frmt, $pretty);
635
+		$datetime_field->set_time_format($this->_tm_frmt, $pretty);
636
+		//set the output returned
637
+		switch ($date_or_time) {
638
+			case 'D' :
639
+				$datetime_field->set_date_time_output('date');
640
+				break;
641
+			case 'T' :
642
+				$datetime_field->set_date_time_output('time');
643
+				break;
644
+			default :
645
+				$datetime_field->set_date_time_output();
646
+		}
647
+	}
648
+
649
+
650
+
651
+	/**
652
+	 * This just takes care of clearing out the cached_properties
653
+	 *
654
+	 * @return void
655
+	 */
656
+	protected function _clear_cached_properties()
657
+	{
658
+		$this->_cached_properties = array();
659
+	}
660
+
661
+
662
+
663
+	/**
664
+	 * This just clears out ONE property if it exists in the cache
665
+	 *
666
+	 * @param  string $property_name the property to remove if it exists (from the _cached_properties array)
667
+	 * @return void
668
+	 */
669
+	protected function _clear_cached_property($property_name)
670
+	{
671
+		if (isset($this->_cached_properties[$property_name])) {
672
+			unset($this->_cached_properties[$property_name]);
673
+		}
674
+	}
675
+
676
+
677
+
678
+	/**
679
+	 * Ensures that this related thing is a model object.
680
+	 *
681
+	 * @param mixed  $object_or_id EE_base_Class/int/string either a related model object, or its ID
682
+	 * @param string $model_name   name of the related thing, eg 'Attendee',
683
+	 * @return EE_Base_Class
684
+	 * @throws \EE_Error
685
+	 */
686
+	protected function ensure_related_thing_is_model_obj($object_or_id, $model_name)
687
+	{
688
+		$other_model_instance = self::_get_model_instance_with_name(
689
+			self::_get_model_classname($model_name),
690
+			$this->_timezone
691
+		);
692
+		return $other_model_instance->ensure_is_obj($object_or_id);
693
+	}
694
+
695
+
696
+
697
+	/**
698
+	 * Forgets the cached model of the given relation Name. So the next time we request it,
699
+	 * we will fetch it again from the database. (Handy if you know it's changed somehow).
700
+	 * If a specific object is supplied, and the relationship to it is either a HasMany or HABTM,
701
+	 * then only remove that one object from our cached array. Otherwise, clear the entire list
702
+	 *
703
+	 * @param string $relationName                         one of the keys in the _model_relations array on the model.
704
+	 *                                                     Eg 'Registration'
705
+	 * @param mixed  $object_to_remove_or_index_into_array or an index into the array of cached things, or NULL
706
+	 *                                                     if you intend to use $clear_all = TRUE, or the relation only
707
+	 *                                                     has 1 object anyways (ie, it's a BelongsToRelation)
708
+	 * @param bool   $clear_all                            This flags clearing the entire cache relation property if
709
+	 *                                                     this is HasMany or HABTM.
710
+	 * @throws EE_Error
711
+	 * @return EE_Base_Class | boolean from which was cleared from the cache, or true if we requested to remove a
712
+	 *                       relation from all
713
+	 */
714
+	public function clear_cache($relationName, $object_to_remove_or_index_into_array = null, $clear_all = false)
715
+	{
716
+		$relationship_to_model = $this->get_model()->related_settings_for($relationName);
717
+		$index_in_cache = '';
718
+		if ( ! $relationship_to_model) {
719
+			throw new EE_Error(
720
+				sprintf(
721
+					__("There is no relationship to %s on a %s. Cannot clear that cache", 'event_espresso'),
722
+					$relationName,
723
+					get_class($this)
724
+				)
725
+			);
726
+		}
727
+		if ($clear_all) {
728
+			$obj_removed = true;
729
+			$this->_model_relations[$relationName] = null;
730
+		} elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
731
+			$obj_removed = $this->_model_relations[$relationName];
732
+			$this->_model_relations[$relationName] = null;
733
+		} else {
734
+			if ($object_to_remove_or_index_into_array instanceof EE_Base_Class
735
+				&& $object_to_remove_or_index_into_array->ID()
736
+			) {
737
+				$index_in_cache = $object_to_remove_or_index_into_array->ID();
738
+				if (is_array($this->_model_relations[$relationName])
739
+					&& ! isset($this->_model_relations[$relationName][$index_in_cache])
740
+				) {
741
+					$index_found_at = null;
742
+					//find this object in the array even though it has a different key
743
+					foreach ($this->_model_relations[$relationName] as $index => $obj) {
744
+						if (
745
+							$obj instanceof EE_Base_Class
746
+							&& (
747
+								$obj == $object_to_remove_or_index_into_array
748
+								|| $obj->ID() === $object_to_remove_or_index_into_array->ID()
749
+							)
750
+						) {
751
+							$index_found_at = $index;
752
+							break;
753
+						}
754
+					}
755
+					if ($index_found_at) {
756
+						$index_in_cache = $index_found_at;
757
+					} else {
758
+						//it wasn't found. huh. well obviously it doesn't need to be removed from teh cache
759
+						//if it wasn't in it to begin with. So we're done
760
+						return $object_to_remove_or_index_into_array;
761
+					}
762
+				}
763
+			} elseif ($object_to_remove_or_index_into_array instanceof EE_Base_Class) {
764
+				//so they provided a model object, but it's not yet saved to the DB... so let's go hunting for it!
765
+				foreach ($this->get_all_from_cache($relationName) as $index => $potentially_obj_we_want) {
766
+					if ($potentially_obj_we_want == $object_to_remove_or_index_into_array) {
767
+						$index_in_cache = $index;
768
+					}
769
+				}
770
+			} else {
771
+				$index_in_cache = $object_to_remove_or_index_into_array;
772
+			}
773
+			//supposedly we've found it. But it could just be that the client code
774
+			//provided a bad index/object
775
+			if (
776
+			isset(
777
+				$this->_model_relations[$relationName],
778
+				$this->_model_relations[$relationName][$index_in_cache]
779
+			)
780
+			) {
781
+				$obj_removed = $this->_model_relations[$relationName][$index_in_cache];
782
+				unset($this->_model_relations[$relationName][$index_in_cache]);
783
+			} else {
784
+				//that thing was never cached anyways.
785
+				$obj_removed = null;
786
+			}
787
+		}
788
+		return $obj_removed;
789
+	}
790
+
791
+
792
+
793
+	/**
794
+	 * update_cache_after_object_save
795
+	 * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has
796
+	 * obtained after being saved to the db
797
+	 *
798
+	 * @param string         $relationName       - the type of object that is cached
799
+	 * @param \EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
800
+	 * @param string         $current_cache_id   - the ID that was used when originally caching the object
801
+	 * @return boolean TRUE on success, FALSE on fail
802
+	 * @throws \EE_Error
803
+	 */
804
+	public function update_cache_after_object_save(
805
+		$relationName,
806
+		EE_Base_Class $newly_saved_object,
807
+		$current_cache_id = ''
808
+	) {
809
+		// verify that incoming object is of the correct type
810
+		$obj_class = 'EE_' . $relationName;
811
+		if ($newly_saved_object instanceof $obj_class) {
812
+			/* @type EE_Base_Class $newly_saved_object */
813
+			// now get the type of relation
814
+			$relationship_to_model = $this->get_model()->related_settings_for($relationName);
815
+			// if this is a 1:1 relationship
816
+			if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
817
+				// then just replace the cached object with the newly saved object
818
+				$this->_model_relations[$relationName] = $newly_saved_object;
819
+				return true;
820
+				// or if it's some kind of sordid feral polyamorous relationship...
821
+			} elseif (is_array($this->_model_relations[$relationName])
822
+					  && isset($this->_model_relations[$relationName][$current_cache_id])
823
+			) {
824
+				// then remove the current cached item
825
+				unset($this->_model_relations[$relationName][$current_cache_id]);
826
+				// and cache the newly saved object using it's new ID
827
+				$this->_model_relations[$relationName][$newly_saved_object->ID()] = $newly_saved_object;
828
+				return true;
829
+			}
830
+		}
831
+		return false;
832
+	}
833
+
834
+
835
+
836
+	/**
837
+	 * Fetches a single EE_Base_Class on that relation. (If the relation is of type
838
+	 * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
839
+	 *
840
+	 * @param string $relationName
841
+	 * @return EE_Base_Class
842
+	 */
843
+	public function get_one_from_cache($relationName)
844
+	{
845
+		$cached_array_or_object = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName]
846
+			: null;
847
+		if (is_array($cached_array_or_object)) {
848
+			return array_shift($cached_array_or_object);
849
+		} else {
850
+			return $cached_array_or_object;
851
+		}
852
+	}
853
+
854
+
855
+
856
+	/**
857
+	 * Fetches a single EE_Base_Class on that relation. (If the relation is of type
858
+	 * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
859
+	 *
860
+	 * @param string $relationName
861
+	 * @throws \EE_Error
862
+	 * @return EE_Base_Class[] NOT necessarily indexed by primary keys
863
+	 */
864
+	public function get_all_from_cache($relationName)
865
+	{
866
+		$objects = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName] : array();
867
+		// if the result is not an array, but exists, make it an array
868
+		$objects = is_array($objects) ? $objects : array($objects);
869
+		//bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
870
+		//basically, if this model object was stored in the session, and these cached model objects
871
+		//already have IDs, let's make sure they're in their model's entity mapper
872
+		//otherwise we will have duplicates next time we call
873
+		// EE_Registry::instance()->load_model( $relationName )->get_one_by_ID( $result->ID() );
874
+		$model = EE_Registry::instance()->load_model($relationName);
875
+		foreach ($objects as $model_object) {
876
+			if ($model instanceof EEM_Base && $model_object instanceof EE_Base_Class) {
877
+				//ensure its in the map if it has an ID; otherwise it will be added to the map when its saved
878
+				if ($model_object->ID()) {
879
+					$model->add_to_entity_map($model_object);
880
+				}
881
+			} else {
882
+				throw new EE_Error(
883
+					sprintf(
884
+						__(
885
+							'Error retrieving related model objects. Either $1%s is not a model or $2%s is not a model object',
886
+							'event_espresso'
887
+						),
888
+						$relationName,
889
+						gettype($model_object)
890
+					)
891
+				);
892
+			}
893
+		}
894
+		return $objects;
895
+	}
896
+
897
+
898
+
899
+	/**
900
+	 * Returns the next x number of EE_Base_Class objects in sequence from this object as found in the database
901
+	 * matching the given query conditions.
902
+	 *
903
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
904
+	 * @param int   $limit              How many objects to return.
905
+	 * @param array $query_params       Any additional conditions on the query.
906
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
907
+	 *                                  you can indicate just the columns you want returned
908
+	 * @return array|EE_Base_Class[]
909
+	 * @throws \EE_Error
910
+	 */
911
+	public function next_x($field_to_order_by = null, $limit = 1, $query_params = array(), $columns_to_select = null)
912
+	{
913
+		$field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
914
+			? $this->get_model()->get_primary_key_field()->get_name()
915
+			: $field_to_order_by;
916
+		$current_value = ! empty($field) ? $this->get($field) : null;
917
+		if (empty($field) || empty($current_value)) {
918
+			return array();
919
+		}
920
+		return $this->get_model()->next_x($current_value, $field, $limit, $query_params, $columns_to_select);
921
+	}
922
+
923
+
924
+
925
+	/**
926
+	 * Returns the previous x number of EE_Base_Class objects in sequence from this object as found in the database
927
+	 * matching the given query conditions.
928
+	 *
929
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
930
+	 * @param int   $limit              How many objects to return.
931
+	 * @param array $query_params       Any additional conditions on the query.
932
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
933
+	 *                                  you can indicate just the columns you want returned
934
+	 * @return array|EE_Base_Class[]
935
+	 * @throws \EE_Error
936
+	 */
937
+	public function previous_x(
938
+		$field_to_order_by = null,
939
+		$limit = 1,
940
+		$query_params = array(),
941
+		$columns_to_select = null
942
+	) {
943
+		$field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
944
+			? $this->get_model()->get_primary_key_field()->get_name()
945
+			: $field_to_order_by;
946
+		$current_value = ! empty($field) ? $this->get($field) : null;
947
+		if (empty($field) || empty($current_value)) {
948
+			return array();
949
+		}
950
+		return $this->get_model()->previous_x($current_value, $field, $limit, $query_params, $columns_to_select);
951
+	}
952
+
953
+
954
+
955
+	/**
956
+	 * Returns the next EE_Base_Class object in sequence from this object as found in the database
957
+	 * matching the given query conditions.
958
+	 *
959
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
960
+	 * @param array $query_params       Any additional conditions on the query.
961
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
962
+	 *                                  you can indicate just the columns you want returned
963
+	 * @return array|EE_Base_Class
964
+	 * @throws \EE_Error
965
+	 */
966
+	public function next($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
967
+	{
968
+		$field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
969
+			? $this->get_model()->get_primary_key_field()->get_name()
970
+			: $field_to_order_by;
971
+		$current_value = ! empty($field) ? $this->get($field) : null;
972
+		if (empty($field) || empty($current_value)) {
973
+			return array();
974
+		}
975
+		return $this->get_model()->next($current_value, $field, $query_params, $columns_to_select);
976
+	}
977
+
978
+
979
+
980
+	/**
981
+	 * Returns the previous EE_Base_Class object in sequence from this object as found in the database
982
+	 * matching the given query conditions.
983
+	 *
984
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
985
+	 * @param array $query_params       Any additional conditions on the query.
986
+	 * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
987
+	 *                                  you can indicate just the column you want returned
988
+	 * @return array|EE_Base_Class
989
+	 * @throws \EE_Error
990
+	 */
991
+	public function previous($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
992
+	{
993
+		$field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
994
+			? $this->get_model()->get_primary_key_field()->get_name()
995
+			: $field_to_order_by;
996
+		$current_value = ! empty($field) ? $this->get($field) : null;
997
+		if (empty($field) || empty($current_value)) {
998
+			return array();
999
+		}
1000
+		return $this->get_model()->previous($current_value, $field, $query_params, $columns_to_select);
1001
+	}
1002
+
1003
+
1004
+
1005
+	/**
1006
+	 * Overrides parent because parent expects old models.
1007
+	 * This also doesn't do any validation, and won't work for serialized arrays
1008
+	 *
1009
+	 * @param string $field_name
1010
+	 * @param mixed  $field_value_from_db
1011
+	 * @throws \EE_Error
1012
+	 */
1013
+	public function set_from_db($field_name, $field_value_from_db)
1014
+	{
1015
+		$field_obj = $this->get_model()->field_settings_for($field_name);
1016
+		if ($field_obj instanceof EE_Model_Field_Base) {
1017
+			//you would think the DB has no NULLs for non-null label fields right? wrong!
1018
+			//eg, a CPT model object could have an entry in the posts table, but no
1019
+			//entry in the meta table. Meaning that all its columns in the meta table
1020
+			//are null! yikes! so when we find one like that, use defaults for its meta columns
1021
+			if ($field_value_from_db === null) {
1022
+				if ($field_obj->is_nullable()) {
1023
+					//if the field allows nulls, then let it be null
1024
+					$field_value = null;
1025
+				} else {
1026
+					$field_value = $field_obj->get_default_value();
1027
+				}
1028
+			} else {
1029
+				$field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1030
+			}
1031
+			$this->_fields[$field_name] = $field_value;
1032
+			$this->_clear_cached_property($field_name);
1033
+		}
1034
+	}
1035
+
1036
+
1037
+
1038
+	/**
1039
+	 * verifies that the specified field is of the correct type
1040
+	 *
1041
+	 * @param string $field_name
1042
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1043
+	 *                                (in cases where the same property may be used for different outputs
1044
+	 *                                - i.e. datetime, money etc.)
1045
+	 * @return mixed
1046
+	 * @throws \EE_Error
1047
+	 */
1048
+	public function get($field_name, $extra_cache_ref = null)
1049
+	{
1050
+		return $this->_get_cached_property($field_name, false, $extra_cache_ref);
1051
+	}
1052
+
1053
+
1054
+
1055
+	/**
1056
+	 * This method simply returns the RAW unprocessed value for the given property in this class
1057
+	 *
1058
+	 * @param  string $field_name A valid fieldname
1059
+	 * @return mixed              Whatever the raw value stored on the property is.
1060
+	 * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1061
+	 */
1062
+	public function get_raw($field_name)
1063
+	{
1064
+		$field_settings = $this->get_model()->field_settings_for($field_name);
1065
+		return $field_settings instanceof EE_Datetime_Field && $this->_fields[$field_name] instanceof DateTime
1066
+			? $this->_fields[$field_name]->format('U')
1067
+			: $this->_fields[$field_name];
1068
+	}
1069
+
1070
+
1071
+
1072
+	/**
1073
+	 * This is used to return the internal DateTime object used for a field that is a
1074
+	 * EE_Datetime_Field.
1075
+	 *
1076
+	 * @param string $field_name               The field name retrieving the DateTime object.
1077
+	 * @return mixed null | false | DateTime  If the requested field is NOT a EE_Datetime_Field then
1078
+	 * @throws \EE_Error
1079
+	 *                                         an error is set and false returned.  If the field IS an
1080
+	 *                                         EE_Datetime_Field and but the field value is null, then
1081
+	 *                                         just null is returned (because that indicates that likely
1082
+	 *                                         this field is nullable).
1083
+	 */
1084
+	public function get_DateTime_object($field_name)
1085
+	{
1086
+		$field_settings = $this->get_model()->field_settings_for($field_name);
1087
+		if ( ! $field_settings instanceof EE_Datetime_Field) {
1088
+			EE_Error::add_error(
1089
+				sprintf(
1090
+					__(
1091
+						'The field %s is not an EE_Datetime_Field field.  There is no DateTime object stored on this field type.',
1092
+						'event_espresso'
1093
+					),
1094
+					$field_name
1095
+				),
1096
+				__FILE__,
1097
+				__FUNCTION__,
1098
+				__LINE__
1099
+			);
1100
+			return false;
1101
+		}
1102
+		return $this->_fields[$field_name];
1103
+	}
1104
+
1105
+
1106
+
1107
+	/**
1108
+	 * To be used in template to immediately echo out the value, and format it for output.
1109
+	 * Eg, should call stripslashes and whatnot before echoing
1110
+	 *
1111
+	 * @param string $field_name      the name of the field as it appears in the DB
1112
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1113
+	 *                                (in cases where the same property may be used for different outputs
1114
+	 *                                - i.e. datetime, money etc.)
1115
+	 * @return void
1116
+	 * @throws \EE_Error
1117
+	 */
1118
+	public function e($field_name, $extra_cache_ref = null)
1119
+	{
1120
+		echo $this->get_pretty($field_name, $extra_cache_ref);
1121
+	}
1122
+
1123
+
1124
+
1125
+	/**
1126
+	 * Exactly like e(), echoes out the field, but sets its schema to 'form_input', so that it
1127
+	 * can be easily used as the value of form input.
1128
+	 *
1129
+	 * @param string $field_name
1130
+	 * @return void
1131
+	 * @throws \EE_Error
1132
+	 */
1133
+	public function f($field_name)
1134
+	{
1135
+		$this->e($field_name, 'form_input');
1136
+	}
1137
+
1138
+
1139
+
1140
+	/**
1141
+	 * Gets a pretty view of the field's value. $extra_cache_ref can specify different formats for this.
1142
+	 * The $extra_cache_ref will be passed to the model field's prepare_for_pretty_echoing, so consult the field's class
1143
+	 * to see what options are available.
1144
+	 * @param string $field_name
1145
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1146
+	 *                                (in cases where the same property may be used for different outputs
1147
+	 *                                - i.e. datetime, money etc.)
1148
+	 * @return mixed
1149
+	 * @throws \EE_Error
1150
+	 */
1151
+	public function get_pretty($field_name, $extra_cache_ref = null)
1152
+	{
1153
+		return $this->_get_cached_property($field_name, true, $extra_cache_ref);
1154
+	}
1155
+
1156
+
1157
+
1158
+	/**
1159
+	 * This simply returns the datetime for the given field name
1160
+	 * Note: this protected function is called by the wrapper get_date or get_time or get_datetime functions
1161
+	 * (and the equivalent e_date, e_time, e_datetime).
1162
+	 *
1163
+	 * @access   protected
1164
+	 * @param string   $field_name   Field on the instantiated EE_Base_Class child object
1165
+	 * @param string   $dt_frmt      valid datetime format used for date
1166
+	 *                               (if '' then we just use the default on the field,
1167
+	 *                               if NULL we use the last-used format)
1168
+	 * @param string   $tm_frmt      Same as above except this is for time format
1169
+	 * @param string   $date_or_time if NULL then both are returned, otherwise "D" = only date and "T" = only time.
1170
+	 * @param  boolean $echo         Whether the dtt is echoing using pretty echoing or just returned using vanilla get
1171
+	 * @return string|bool|EE_Error string on success, FALSE on fail, or EE_Error Exception is thrown
1172
+	 *                               if field is not a valid dtt field, or void if echoing
1173
+	 * @throws \EE_Error
1174
+	 */
1175
+	protected function _get_datetime($field_name, $dt_frmt = '', $tm_frmt = '', $date_or_time = '', $echo = false)
1176
+	{
1177
+		// clear cached property
1178
+		$this->_clear_cached_property($field_name);
1179
+		//reset format properties because they are used in get()
1180
+		$this->_dt_frmt = $dt_frmt !== '' ? $dt_frmt : $this->_dt_frmt;
1181
+		$this->_tm_frmt = $tm_frmt !== '' ? $tm_frmt : $this->_tm_frmt;
1182
+		if ($echo) {
1183
+			$this->e($field_name, $date_or_time);
1184
+			return '';
1185
+		}
1186
+		return $this->get($field_name, $date_or_time);
1187
+	}
1188
+
1189
+
1190
+
1191
+	/**
1192
+	 * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the date
1193
+	 * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1194
+	 * other echoes the pretty value for dtt)
1195
+	 *
1196
+	 * @param  string $field_name name of model object datetime field holding the value
1197
+	 * @param  string $format     format for the date returned (if NULL we use default in dt_frmt property)
1198
+	 * @return string            datetime value formatted
1199
+	 * @throws \EE_Error
1200
+	 */
1201
+	public function get_date($field_name, $format = '')
1202
+	{
1203
+		return $this->_get_datetime($field_name, $format, null, 'D');
1204
+	}
1205
+
1206
+
1207
+
1208
+	/**
1209
+	 * @param      $field_name
1210
+	 * @param string $format
1211
+	 * @throws \EE_Error
1212
+	 */
1213
+	public function e_date($field_name, $format = '')
1214
+	{
1215
+		$this->_get_datetime($field_name, $format, null, 'D', true);
1216
+	}
1217
+
1218
+
1219
+
1220
+	/**
1221
+	 * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the time
1222
+	 * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1223
+	 * other echoes the pretty value for dtt)
1224
+	 *
1225
+	 * @param  string $field_name name of model object datetime field holding the value
1226
+	 * @param  string $format     format for the time returned ( if NULL we use default in tm_frmt property)
1227
+	 * @return string             datetime value formatted
1228
+	 * @throws \EE_Error
1229
+	 */
1230
+	public function get_time($field_name, $format = '')
1231
+	{
1232
+		return $this->_get_datetime($field_name, null, $format, 'T');
1233
+	}
1234
+
1235
+
1236
+
1237
+	/**
1238
+	 * @param      $field_name
1239
+	 * @param string $format
1240
+	 * @throws \EE_Error
1241
+	 */
1242
+	public function e_time($field_name, $format = '')
1243
+	{
1244
+		$this->_get_datetime($field_name, null, $format, 'T', true);
1245
+	}
1246
+
1247
+
1248
+
1249
+	/**
1250
+	 * below are wrapper functions for the various datetime outputs that can be obtained for returning the date AND
1251
+	 * time portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1252
+	 * other echoes the pretty value for dtt)
1253
+	 *
1254
+	 * @param  string $field_name name of model object datetime field holding the value
1255
+	 * @param  string $dt_frmt    format for the date returned (if NULL we use default in dt_frmt property)
1256
+	 * @param  string $tm_frmt    format for the time returned (if NULL we use default in tm_frmt property)
1257
+	 * @return string             datetime value formatted
1258
+	 * @throws \EE_Error
1259
+	 */
1260
+	public function get_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1261
+	{
1262
+		return $this->_get_datetime($field_name, $dt_frmt, $tm_frmt);
1263
+	}
1264
+
1265
+
1266
+
1267
+	/**
1268
+	 * @param string $field_name
1269
+	 * @param string $dt_frmt
1270
+	 * @param string $tm_frmt
1271
+	 * @throws \EE_Error
1272
+	 */
1273
+	public function e_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1274
+	{
1275
+		$this->_get_datetime($field_name, $dt_frmt, $tm_frmt, null, true);
1276
+	}
1277
+
1278
+
1279
+
1280
+	/**
1281
+	 * Get the i8ln value for a date using the WordPress @see date_i18n function.
1282
+	 *
1283
+	 * @param string $field_name The EE_Datetime_Field reference for the date being retrieved.
1284
+	 * @param string $format     PHP valid date/time string format.  If none is provided then the internal set format
1285
+	 *                           on the object will be used.
1286
+	 * @return string Date and time string in set locale or false if no field exists for the given
1287
+	 * @throws \EE_Error
1288
+	 *                           field name.
1289
+	 */
1290
+	public function get_i18n_datetime($field_name, $format = '')
1291
+	{
1292
+		$format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1293
+		return date_i18n(
1294
+			$format,
1295
+			EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
1296
+		);
1297
+	}
1298
+
1299
+
1300
+
1301
+	/**
1302
+	 * This method validates whether the given field name is a valid field on the model object as well as it is of a
1303
+	 * type EE_Datetime_Field.  On success there will be returned the field settings.  On fail an EE_Error exception is
1304
+	 * thrown.
1305
+	 *
1306
+	 * @param  string $field_name The field name being checked
1307
+	 * @throws EE_Error
1308
+	 * @return EE_Datetime_Field
1309
+	 */
1310
+	protected function _get_dtt_field_settings($field_name)
1311
+	{
1312
+		$field = $this->get_model()->field_settings_for($field_name);
1313
+		//check if field is dtt
1314
+		if ($field instanceof EE_Datetime_Field) {
1315
+			return $field;
1316
+		} else {
1317
+			throw new EE_Error(sprintf(__('The field name "%s" has been requested for the EE_Base_Class datetime functions and it is not a valid EE_Datetime_Field.  Please check the spelling of the field and make sure it has been setup as a EE_Datetime_Field in the %s model constructor',
1318
+				'event_espresso'), $field_name, self::_get_model_classname(get_class($this))));
1319
+		}
1320
+	}
1321
+
1322
+
1323
+
1324
+
1325
+	/**
1326
+	 * NOTE ABOUT BELOW:
1327
+	 * These convenience date and time setters are for setting date and time independently.  In other words you might
1328
+	 * want to change the time on a datetime_field but leave the date the same (or vice versa). IF on the other hand
1329
+	 * you want to set both date and time at the same time, you can just use the models default set($fieldname,$value)
1330
+	 * method and make sure you send the entire datetime value for setting.
1331
+	 */
1332
+	/**
1333
+	 * sets the time on a datetime property
1334
+	 *
1335
+	 * @access protected
1336
+	 * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1337
+	 * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1338
+	 * @throws \EE_Error
1339
+	 */
1340
+	protected function _set_time_for($time, $fieldname)
1341
+	{
1342
+		$this->_set_date_time('T', $time, $fieldname);
1343
+	}
1344
+
1345
+
1346
+
1347
+	/**
1348
+	 * sets the date on a datetime property
1349
+	 *
1350
+	 * @access protected
1351
+	 * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1352
+	 * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1353
+	 * @throws \EE_Error
1354
+	 */
1355
+	protected function _set_date_for($date, $fieldname)
1356
+	{
1357
+		$this->_set_date_time('D', $date, $fieldname);
1358
+	}
1359
+
1360
+
1361
+
1362
+	/**
1363
+	 * This takes care of setting a date or time independently on a given model object property. This method also
1364
+	 * verifies that the given fieldname matches a model object property and is for a EE_Datetime_Field field
1365
+	 *
1366
+	 * @access protected
1367
+	 * @param string          $what           "T" for time, 'B' for both, 'D' for Date.
1368
+	 * @param string|DateTime $datetime_value A valid Date or Time string (or DateTime object)
1369
+	 * @param string          $fieldname      the name of the field the date OR time is being set on (must match a
1370
+	 *                                        EE_Datetime_Field property)
1371
+	 * @throws \EE_Error
1372
+	 */
1373
+	protected function _set_date_time($what = 'T', $datetime_value, $fieldname)
1374
+	{
1375
+		$field = $this->_get_dtt_field_settings($fieldname);
1376
+		$field->set_timezone($this->_timezone);
1377
+		$field->set_date_format($this->_dt_frmt);
1378
+		$field->set_time_format($this->_tm_frmt);
1379
+		switch ($what) {
1380
+			case 'T' :
1381
+				$this->_fields[$fieldname] = $field->prepare_for_set_with_new_time(
1382
+					$datetime_value,
1383
+					$this->_fields[$fieldname]
1384
+				);
1385
+				break;
1386
+			case 'D' :
1387
+				$this->_fields[$fieldname] = $field->prepare_for_set_with_new_date(
1388
+					$datetime_value,
1389
+					$this->_fields[$fieldname]
1390
+				);
1391
+				break;
1392
+			case 'B' :
1393
+				$this->_fields[$fieldname] = $field->prepare_for_set($datetime_value);
1394
+				break;
1395
+		}
1396
+		$this->_clear_cached_property($fieldname);
1397
+	}
1398
+
1399
+
1400
+
1401
+	/**
1402
+	 * This will return a timestamp for the website timezone but ONLY when the current website timezone is different
1403
+	 * than the timezone set for the website. NOTE, this currently only works well with methods that return values.  If
1404
+	 * you use it with methods that echo values the $_timestamp property may not get reset to its original value and
1405
+	 * that could lead to some unexpected results!
1406
+	 *
1407
+	 * @access public
1408
+	 * @param string               $field_name This is the name of the field on the object that contains the date/time
1409
+	 *                                         value being returned.
1410
+	 * @param string               $callback   must match a valid method in this class (defaults to get_datetime)
1411
+	 * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1412
+	 * @param string               $prepend    You can include something to prepend on the timestamp
1413
+	 * @param string               $append     You can include something to append on the timestamp
1414
+	 * @throws EE_Error
1415
+	 * @return string timestamp
1416
+	 */
1417
+	public function display_in_my_timezone(
1418
+		$field_name,
1419
+		$callback = 'get_datetime',
1420
+		$args = null,
1421
+		$prepend = '',
1422
+		$append = ''
1423
+	) {
1424
+		$timezone = EEH_DTT_Helper::get_timezone();
1425
+		if ($timezone === $this->_timezone) {
1426
+			return '';
1427
+		}
1428
+		$original_timezone = $this->_timezone;
1429
+		$this->set_timezone($timezone);
1430
+		$fn = (array)$field_name;
1431
+		$args = array_merge($fn, (array)$args);
1432
+		if ( ! method_exists($this, $callback)) {
1433
+			throw new EE_Error(
1434
+				sprintf(
1435
+					__(
1436
+						'The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling',
1437
+						'event_espresso'
1438
+					),
1439
+					$callback
1440
+				)
1441
+			);
1442
+		}
1443
+		$args = (array)$args;
1444
+		$return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1445
+		$this->set_timezone($original_timezone);
1446
+		return $return;
1447
+	}
1448
+
1449
+
1450
+
1451
+	/**
1452
+	 * Deletes this model object.
1453
+	 * This calls the `EE_Base_Class::_delete` method.  Child classes wishing to change default behaviour should
1454
+	 * override
1455
+	 * `EE_Base_Class::_delete` NOT this class.
1456
+	 *
1457
+	 * @return boolean | int
1458
+	 * @throws \EE_Error
1459
+	 */
1460
+	public function delete()
1461
+	{
1462
+		/**
1463
+		 * Called just before the `EE_Base_Class::_delete` method call.
1464
+		 * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1465
+		 * should be aware that `_delete` may not always result in a permanent delete.  For example, `EE_Soft_Delete_Base_Class::_delete`
1466
+		 * soft deletes (trash) the object and does not permanently delete it.
1467
+		 *
1468
+		 * @param EE_Base_Class $model_object about to be 'deleted'
1469
+		 */
1470
+		do_action('AHEE__EE_Base_Class__delete__before', $this);
1471
+		$result = $this->_delete();
1472
+		/**
1473
+		 * Called just after the `EE_Base_Class::_delete` method call.
1474
+		 * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1475
+		 * should be aware that `_delete` may not always result in a permanent delete.  For example `EE_Soft_Base_Class::_delete`
1476
+		 * soft deletes (trash) the object and does not permanently delete it.
1477
+		 *
1478
+		 * @param EE_Base_Class $model_object that was just 'deleted'
1479
+		 * @param boolean       $result
1480
+		 */
1481
+		do_action('AHEE__EE_Base_Class__delete__end', $this, $result);
1482
+		return $result;
1483
+	}
1484
+
1485
+
1486
+
1487
+	/**
1488
+	 * Calls the specific delete method for the instantiated class.
1489
+	 * This method is called by the public `EE_Base_Class::delete` method.  Any child classes desiring to override
1490
+	 * default functionality for "delete" (which is to call `permanently_delete`) should override this method NOT
1491
+	 * `EE_Base_Class::delete`
1492
+	 *
1493
+	 * @return bool|int
1494
+	 * @throws \EE_Error
1495
+	 */
1496
+	protected function _delete()
1497
+	{
1498
+		return $this->delete_permanently();
1499
+	}
1500
+
1501
+
1502
+
1503
+	/**
1504
+	 * Deletes this model object permanently from db (but keep in mind related models my block the delete and return an
1505
+	 * error)
1506
+	 *
1507
+	 * @return bool | int
1508
+	 * @throws \EE_Error
1509
+	 */
1510
+	public function delete_permanently()
1511
+	{
1512
+		/**
1513
+		 * Called just before HARD deleting a model object
1514
+		 *
1515
+		 * @param EE_Base_Class $model_object about to be 'deleted'
1516
+		 */
1517
+		do_action('AHEE__EE_Base_Class__delete_permanently__before', $this);
1518
+		$model = $this->get_model();
1519
+		$result = $model->delete_permanently_by_ID($this->ID());
1520
+		$this->refresh_cache_of_related_objects();
1521
+		/**
1522
+		 * Called just after HARD deleting a model object
1523
+		 *
1524
+		 * @param EE_Base_Class $model_object that was just 'deleted'
1525
+		 * @param boolean       $result
1526
+		 */
1527
+		do_action('AHEE__EE_Base_Class__delete_permanently__end', $this, $result);
1528
+		return $result;
1529
+	}
1530
+
1531
+
1532
+
1533
+	/**
1534
+	 * When this model object is deleted, it may still be cached on related model objects. This clears the cache of
1535
+	 * related model objects
1536
+	 *
1537
+	 * @throws \EE_Error
1538
+	 */
1539
+	public function refresh_cache_of_related_objects()
1540
+	{
1541
+		foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
1542
+			if ( ! empty($this->_model_relations[$relation_name])) {
1543
+				$related_objects = $this->_model_relations[$relation_name];
1544
+				if ($relation_obj instanceof EE_Belongs_To_Relation) {
1545
+					//this relation only stores a single model object, not an array
1546
+					//but let's make it consistent
1547
+					$related_objects = array($related_objects);
1548
+				}
1549
+				foreach ($related_objects as $related_object) {
1550
+					//only refresh their cache if they're in memory
1551
+					if ($related_object instanceof EE_Base_Class) {
1552
+						$related_object->clear_cache($this->get_model()->get_this_model_name(), $this);
1553
+					}
1554
+				}
1555
+			}
1556
+		}
1557
+	}
1558
+
1559
+
1560
+
1561
+	/**
1562
+	 *        Saves this object to the database. An array may be supplied to set some values on this
1563
+	 * object just before saving.
1564
+	 *
1565
+	 * @access public
1566
+	 * @param array $set_cols_n_values keys are field names, values are their new values,
1567
+	 *                                 if provided during the save() method (often client code will change the fields'
1568
+	 *                                 values before calling save)
1569
+	 * @throws \EE_Error
1570
+	 * @return int , 1 on a successful update, the ID of the new entry on insert; 0 on failure or if the model object
1571
+	 *                                 isn't allowed to persist (as determined by EE_Base_Class::allow_persist())
1572
+	 */
1573
+	public function save($set_cols_n_values = array())
1574
+	{
1575
+		/**
1576
+		 * Filters the fields we're about to save on the model object
1577
+		 *
1578
+		 * @param array         $set_cols_n_values
1579
+		 * @param EE_Base_Class $model_object
1580
+		 */
1581
+		$set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1582
+			$this);
1583
+		//set attributes as provided in $set_cols_n_values
1584
+		foreach ($set_cols_n_values as $column => $value) {
1585
+			$this->set($column, $value);
1586
+		}
1587
+		// no changes ? then don't do anything
1588
+		if (! $this->_has_changes && $this->ID() && $this->get_model()->get_primary_key_field()->is_auto_increment()) {
1589
+			return 0;
1590
+		}
1591
+		/**
1592
+		 * Saving a model object.
1593
+		 * Before we perform a save, this action is fired.
1594
+		 *
1595
+		 * @param EE_Base_Class $model_object the model object about to be saved.
1596
+		 */
1597
+		do_action('AHEE__EE_Base_Class__save__begin', $this);
1598
+		if ( ! $this->allow_persist()) {
1599
+			return 0;
1600
+		}
1601
+		//now get current attribute values
1602
+		$save_cols_n_values = $this->_fields;
1603
+		//if the object already has an ID, update it. Otherwise, insert it
1604
+		//also: change the assumption about values passed to the model NOT being prepare dby the model object. They have been
1605
+		$old_assumption_concerning_value_preparation = $this->get_model()
1606
+															->get_assumption_concerning_values_already_prepared_by_model_object();
1607
+		$this->get_model()->assume_values_already_prepared_by_model_object(true);
1608
+		//does this model have an autoincrement PK?
1609
+		if ($this->get_model()->has_primary_key_field()) {
1610
+			if ($this->get_model()->get_primary_key_field()->is_auto_increment()) {
1611
+				//ok check if it's set, if so: update; if not, insert
1612
+				if ( ! empty($save_cols_n_values[self::_get_primary_key_name(get_class($this))])) {
1613
+					$results = $this->get_model()->update_by_ID($save_cols_n_values, $this->ID());
1614
+				} else {
1615
+					unset($save_cols_n_values[self::_get_primary_key_name(get_class($this))]);
1616
+					$results = $this->get_model()->insert($save_cols_n_values);
1617
+					if ($results) {
1618
+						//if successful, set the primary key
1619
+						//but don't use the normal SET method, because it will check if
1620
+						//an item with the same ID exists in the mapper & db, then
1621
+						//will find it in the db (because we just added it) and THAT object
1622
+						//will get added to the mapper before we can add this one!
1623
+						//but if we just avoid using the SET method, all that headache can be avoided
1624
+						$pk_field_name = self::_get_primary_key_name(get_class($this));
1625
+						$this->_fields[$pk_field_name] = $results;
1626
+						$this->_clear_cached_property($pk_field_name);
1627
+						$this->get_model()->add_to_entity_map($this);
1628
+						$this->_update_cached_related_model_objs_fks();
1629
+					}
1630
+				}
1631
+			} else {//PK is NOT auto-increment
1632
+				//so check if one like it already exists in the db
1633
+				if ($this->get_model()->exists_by_ID($this->ID())) {
1634
+					if (WP_DEBUG && ! $this->in_entity_map()) {
1635
+						throw new EE_Error(
1636
+							sprintf(
1637
+								__('Using a model object %1$s that is NOT in the entity map, can lead to unexpected errors. You should either: %4$s 1. Put it in the entity mapper by calling %2$s %4$s 2. Discard this model object and use what is in the entity mapper %4$s 3. Fetch from the database using %3$s',
1638
+									'event_espresso'),
1639
+								get_class($this),
1640
+								get_class($this->get_model()) . '::instance()->add_to_entity_map()',
1641
+								get_class($this->get_model()) . '::instance()->get_one_by_ID()',
1642
+								'<br />'
1643
+							)
1644
+						);
1645
+					}
1646
+					$results = $this->get_model()->update_by_ID($save_cols_n_values, $this->ID());
1647
+				} else {
1648
+					$results = $this->get_model()->insert($save_cols_n_values);
1649
+					$this->_update_cached_related_model_objs_fks();
1650
+				}
1651
+			}
1652
+		} else {//there is NO primary key
1653
+			$already_in_db = false;
1654
+			foreach ($this->get_model()->unique_indexes() as $index) {
1655
+				$uniqueness_where_params = array_intersect_key($save_cols_n_values, $index->fields());
1656
+				if ($this->get_model()->exists(array($uniqueness_where_params))) {
1657
+					$already_in_db = true;
1658
+				}
1659
+			}
1660
+			if ($already_in_db) {
1661
+				$combined_pk_fields_n_values = array_intersect_key($save_cols_n_values,
1662
+					$this->get_model()->get_combined_primary_key_fields());
1663
+				$results = $this->get_model()->update($save_cols_n_values, $combined_pk_fields_n_values);
1664
+			} else {
1665
+				$results = $this->get_model()->insert($save_cols_n_values);
1666
+			}
1667
+		}
1668
+		//restore the old assumption about values being prepared by the model object
1669
+		$this->get_model()
1670
+			 ->assume_values_already_prepared_by_model_object($old_assumption_concerning_value_preparation);
1671
+		/**
1672
+		 * After saving the model object this action is called
1673
+		 *
1674
+		 * @param EE_Base_Class $model_object which was just saved
1675
+		 * @param boolean|int   $results      if it were updated, TRUE or FALSE; if it were newly inserted
1676
+		 *                                    the new ID (or 0 if an error occurred and it wasn't updated)
1677
+		 */
1678
+		do_action('AHEE__EE_Base_Class__save__end', $this, $results);
1679
+		$this->_has_changes = false;
1680
+		return $results;
1681
+	}
1682
+
1683
+
1684
+
1685
+	/**
1686
+	 * Updates the foreign key on related models objects pointing to this to have this model object's ID
1687
+	 * as their foreign key.  If the cached related model objects already exist in the db, saves them (so that the DB
1688
+	 * is consistent) Especially useful in case we JUST added this model object ot the database and we want to let its
1689
+	 * cached relations with foreign keys to it know about that change. Eg: we've created a transaction but haven't
1690
+	 * saved it to the db. We also create a registration and don't save it to the DB, but we DO cache it on the
1691
+	 * transaction. Now, when we save the transaction, the registration's TXN_ID will be automatically updated, whether
1692
+	 * or not they exist in the DB (if they do, their DB records will be automatically updated)
1693
+	 *
1694
+	 * @return void
1695
+	 * @throws \EE_Error
1696
+	 */
1697
+	protected function _update_cached_related_model_objs_fks()
1698
+	{
1699
+		foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
1700
+			if ($relation_obj instanceof EE_Has_Many_Relation) {
1701
+				foreach ($this->get_all_from_cache($relation_name) as $related_model_obj_in_cache) {
1702
+					$fk_to_this = $related_model_obj_in_cache->get_model()->get_foreign_key_to(
1703
+						$this->get_model()->get_this_model_name()
1704
+					);
1705
+					$related_model_obj_in_cache->set($fk_to_this->get_name(), $this->ID());
1706
+					if ($related_model_obj_in_cache->ID()) {
1707
+						$related_model_obj_in_cache->save();
1708
+					}
1709
+				}
1710
+			}
1711
+		}
1712
+	}
1713
+
1714
+
1715
+
1716
+	/**
1717
+	 * Saves this model object and its NEW cached relations to the database.
1718
+	 * (Meaning, for now, IT DOES NOT WORK if the cached items already exist in the DB.
1719
+	 * In order for that to work, we would need to mark model objects as dirty/clean...
1720
+	 * because otherwise, there's a potential for infinite looping of saving
1721
+	 * Saves the cached related model objects, and ensures the relation between them
1722
+	 * and this object and properly setup
1723
+	 *
1724
+	 * @return int ID of new model object on save; 0 on failure+
1725
+	 * @throws \EE_Error
1726
+	 */
1727
+	public function save_new_cached_related_model_objs()
1728
+	{
1729
+		//make sure this has been saved
1730
+		if ( ! $this->ID()) {
1731
+			$id = $this->save();
1732
+		} else {
1733
+			$id = $this->ID();
1734
+		}
1735
+		//now save all the NEW cached model objects  (ie they don't exist in the DB)
1736
+		foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1737
+			if ($this->_model_relations[$relationName]) {
1738
+				//is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
1739
+				//or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
1740
+				if ($relationObj instanceof EE_Belongs_To_Relation) {
1741
+					//add a relation to that relation type (which saves the appropriate thing in the process)
1742
+					//but ONLY if it DOES NOT exist in the DB
1743
+					/* @var $related_model_obj EE_Base_Class */
1744
+					$related_model_obj = $this->_model_relations[$relationName];
1745
+					//					if( ! $related_model_obj->ID()){
1746
+					$this->_add_relation_to($related_model_obj, $relationName);
1747
+					$related_model_obj->save_new_cached_related_model_objs();
1748
+					//					}
1749
+				} else {
1750
+					foreach ($this->_model_relations[$relationName] as $related_model_obj) {
1751
+						//add a relation to that relation type (which saves the appropriate thing in the process)
1752
+						//but ONLY if it DOES NOT exist in the DB
1753
+						//						if( ! $related_model_obj->ID()){
1754
+						$this->_add_relation_to($related_model_obj, $relationName);
1755
+						$related_model_obj->save_new_cached_related_model_objs();
1756
+						//						}
1757
+					}
1758
+				}
1759
+			}
1760
+		}
1761
+		return $id;
1762
+	}
1763
+
1764
+
1765
+
1766
+	/**
1767
+	 * for getting a model while instantiated.
1768
+	 *
1769
+	 * @return \EEM_Base | \EEM_CPT_Base
1770
+	 */
1771
+	public function get_model()
1772
+	{
1773
+		$modelName = self::_get_model_classname(get_class($this));
1774
+		return self::_get_model_instance_with_name($modelName, $this->_timezone);
1775
+	}
1776
+
1777
+
1778
+
1779
+	/**
1780
+	 * @param $props_n_values
1781
+	 * @param $classname
1782
+	 * @return mixed bool|EE_Base_Class|EEM_CPT_Base
1783
+	 * @throws \EE_Error
1784
+	 */
1785
+	protected static function _get_object_from_entity_mapper($props_n_values, $classname)
1786
+	{
1787
+		//TODO: will not work for Term_Relationships because they have no PK!
1788
+		$primary_id_ref = self::_get_primary_key_name($classname);
1789
+		if (array_key_exists($primary_id_ref, $props_n_values) && ! empty($props_n_values[$primary_id_ref])) {
1790
+			$id = $props_n_values[$primary_id_ref];
1791
+			return self::_get_model($classname)->get_from_entity_map($id);
1792
+		}
1793
+		return false;
1794
+	}
1795
+
1796
+
1797
+
1798
+	/**
1799
+	 * This is called by child static "new_instance" method and we'll check to see if there is an existing db entry for
1800
+	 * the primary key (if present in incoming values). If there is a key in the incoming array that matches the
1801
+	 * primary key for the model AND it is not null, then we check the db. If there's a an object we return it.  If not
1802
+	 * we return false.
1803
+	 *
1804
+	 * @param  array  $props_n_values   incoming array of properties and their values
1805
+	 * @param  string $classname        the classname of the child class
1806
+	 * @param null    $timezone
1807
+	 * @param array   $date_formats     incoming date_formats in an array where the first value is the
1808
+	 *                                  date_format and the second value is the time format
1809
+	 * @return mixed (EE_Base_Class|bool)
1810
+	 * @throws \EE_Error
1811
+	 */
1812
+	protected static function _check_for_object($props_n_values, $classname, $timezone = null, $date_formats = array())
1813
+	{
1814
+		$existing = null;
1815
+		if (self::_get_model($classname)->has_primary_key_field()) {
1816
+			$primary_id_ref = self::_get_primary_key_name($classname);
1817
+			if (array_key_exists($primary_id_ref, $props_n_values)
1818
+				&& ! empty($props_n_values[$primary_id_ref])
1819
+			) {
1820
+				$existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1821
+					$props_n_values[$primary_id_ref]
1822
+				);
1823
+			}
1824
+		} elseif (self::_get_model($classname, $timezone)->has_all_combined_primary_key_fields($props_n_values)) {
1825
+			//no primary key on this model, but there's still a matching item in the DB
1826
+			$existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1827
+				self::_get_model($classname, $timezone)->get_index_primary_key_string($props_n_values)
1828
+			);
1829
+		}
1830
+		if ($existing) {
1831
+			//set date formats if present before setting values
1832
+			if ( ! empty($date_formats) && is_array($date_formats)) {
1833
+				$existing->set_date_format($date_formats[0]);
1834
+				$existing->set_time_format($date_formats[1]);
1835
+			} else {
1836
+				//set default formats for date and time
1837
+				$existing->set_date_format(get_option('date_format'));
1838
+				$existing->set_time_format(get_option('time_format'));
1839
+			}
1840
+			foreach ($props_n_values as $property => $field_value) {
1841
+				$existing->set($property, $field_value);
1842
+			}
1843
+			return $existing;
1844
+		} else {
1845
+			return false;
1846
+		}
1847
+	}
1848
+
1849
+
1850
+
1851
+	/**
1852
+	 * Gets the EEM_*_Model for this class
1853
+	 *
1854
+	 * @access public now, as this is more convenient
1855
+	 * @param      $classname
1856
+	 * @param null $timezone
1857
+	 * @throws EE_Error
1858
+	 * @return EEM_Base
1859
+	 */
1860
+	protected static function _get_model($classname, $timezone = null)
1861
+	{
1862
+		//find model for this class
1863
+		if ( ! $classname) {
1864
+			throw new EE_Error(
1865
+				sprintf(
1866
+					__(
1867
+						"What were you thinking calling _get_model(%s)?? You need to specify the class name",
1868
+						"event_espresso"
1869
+					),
1870
+					$classname
1871
+				)
1872
+			);
1873
+		}
1874
+		$modelName = self::_get_model_classname($classname);
1875
+		return self::_get_model_instance_with_name($modelName, $timezone);
1876
+	}
1877
+
1878
+
1879
+
1880
+	/**
1881
+	 * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1882
+	 *
1883
+	 * @param string $model_classname
1884
+	 * @param null   $timezone
1885
+	 * @return EEM_Base
1886
+	 */
1887
+	protected static function _get_model_instance_with_name($model_classname, $timezone = null)
1888
+	{
1889
+		$model_classname = str_replace('EEM_', '', $model_classname);
1890
+		$model = EE_Registry::instance()->load_model($model_classname);
1891
+		$model->set_timezone($timezone);
1892
+		return $model;
1893
+	}
1894
+
1895
+
1896
+
1897
+	/**
1898
+	 * If a model name is provided (eg Registration), gets the model classname for that model.
1899
+	 * Also works if a model class's classname is provided (eg EE_Registration).
1900
+	 *
1901
+	 * @param null $model_name
1902
+	 * @return string like EEM_Attendee
1903
+	 */
1904
+	private static function _get_model_classname($model_name = null)
1905
+	{
1906
+		if (strpos($model_name, "EE_") === 0) {
1907
+			$model_classname = str_replace("EE_", "EEM_", $model_name);
1908
+		} else {
1909
+			$model_classname = "EEM_" . $model_name;
1910
+		}
1911
+		return $model_classname;
1912
+	}
1913
+
1914
+
1915
+
1916
+	/**
1917
+	 * returns the name of the primary key attribute
1918
+	 *
1919
+	 * @param null $classname
1920
+	 * @throws EE_Error
1921
+	 * @return string
1922
+	 */
1923
+	protected static function _get_primary_key_name($classname = null)
1924
+	{
1925
+		if ( ! $classname) {
1926
+			throw new EE_Error(
1927
+				sprintf(
1928
+					__("What were you thinking calling _get_primary_key_name(%s)", "event_espresso"),
1929
+					$classname
1930
+				)
1931
+			);
1932
+		}
1933
+		return self::_get_model($classname)->get_primary_key_field()->get_name();
1934
+	}
1935
+
1936
+
1937
+
1938
+	/**
1939
+	 * Gets the value of the primary key.
1940
+	 * If the object hasn't yet been saved, it should be whatever the model field's default was
1941
+	 * (eg, if this were the EE_Event class, look at the primary key field on EEM_Event and see what its default value
1942
+	 * is. Usually defaults for integer primary keys are 0; string primary keys are usually NULL).
1943
+	 *
1944
+	 * @return mixed, if the primary key is of type INT it'll be an int. Otherwise it could be a string
1945
+	 * @throws \EE_Error
1946
+	 */
1947
+	public function ID()
1948
+	{
1949
+		//now that we know the name of the variable, use a variable variable to get its value and return its
1950
+		if ($this->get_model()->has_primary_key_field()) {
1951
+			return $this->_fields[self::_get_primary_key_name(get_class($this))];
1952
+		} else {
1953
+			return $this->get_model()->get_index_primary_key_string($this->_fields);
1954
+		}
1955
+	}
1956
+
1957
+
1958
+
1959
+	/**
1960
+	 * Adds a relationship to the specified EE_Base_Class object, given the relationship's name. Eg, if the current
1961
+	 * model is related to a group of events, the $relationName should be 'Event', and should be a key in the EE
1962
+	 * Model's $_model_relations array. If this model object doesn't exist in the DB, just caches the related thing
1963
+	 *
1964
+	 * @param mixed  $otherObjectModelObjectOrID       EE_Base_Class or the ID of the other object
1965
+	 * @param string $relationName                     eg 'Events','Question',etc.
1966
+	 *                                                 an attendee to a group, you also want to specify which role they
1967
+	 *                                                 will have in that group. So you would use this parameter to
1968
+	 *                                                 specify array('role-column-name'=>'role-id')
1969
+	 * @param array  $extra_join_model_fields_n_values You can optionally include an array of key=>value pairs that
1970
+	 *                                                 allow you to further constrict the relation to being added.
1971
+	 *                                                 However, keep in mind that the columns (keys) given must match a
1972
+	 *                                                 column on the JOIN table and currently only the HABTM models
1973
+	 *                                                 accept these additional conditions.  Also remember that if an
1974
+	 *                                                 exact match isn't found for these extra cols/val pairs, then a
1975
+	 *                                                 NEW row is created in the join table.
1976
+	 * @param null   $cache_id
1977
+	 * @throws EE_Error
1978
+	 * @return EE_Base_Class the object the relation was added to
1979
+	 */
1980
+	public function _add_relation_to(
1981
+		$otherObjectModelObjectOrID,
1982
+		$relationName,
1983
+		$extra_join_model_fields_n_values = array(),
1984
+		$cache_id = null
1985
+	) {
1986
+		//if this thing exists in the DB, save the relation to the DB
1987
+		if ($this->ID()) {
1988
+			$otherObject = $this->get_model()
1989
+								->add_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
1990
+									$extra_join_model_fields_n_values);
1991
+			//clear cache so future get_many_related and get_first_related() return new results.
1992
+			$this->clear_cache($relationName, $otherObject, true);
1993
+			if ($otherObject instanceof EE_Base_Class) {
1994
+				$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
1995
+			}
1996
+		} else {
1997
+			//this thing doesn't exist in the DB,  so just cache it
1998
+			if ( ! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
1999
+				throw new EE_Error(sprintf(
2000
+					__('Before a model object is saved to the database, calls to _add_relation_to must be passed an actual object, not just an ID. You provided %s as the model object to a %s',
2001
+						'event_espresso'),
2002
+					$otherObjectModelObjectOrID,
2003
+					get_class($this)
2004
+				));
2005
+			} else {
2006
+				$otherObject = $otherObjectModelObjectOrID;
2007
+			}
2008
+			$this->cache($relationName, $otherObjectModelObjectOrID, $cache_id);
2009
+		}
2010
+		if ($otherObject instanceof EE_Base_Class) {
2011
+			//fix the reciprocal relation too
2012
+			if ($otherObject->ID()) {
2013
+				//its saved so assumed relations exist in the DB, so we can just
2014
+				//clear the cache so future queries use the updated info in the DB
2015
+				$otherObject->clear_cache($this->get_model()->get_this_model_name(), null, true);
2016
+			} else {
2017
+				//it's not saved, so it caches relations like this
2018
+				$otherObject->cache($this->get_model()->get_this_model_name(), $this);
2019
+			}
2020
+		}
2021
+		return $otherObject;
2022
+	}
2023
+
2024
+
2025
+
2026
+	/**
2027
+	 * Removes a relationship to the specified EE_Base_Class object, given the relationships' name. Eg, if the current
2028
+	 * model is related to a group of events, the $relationName should be 'Events', and should be a key in the EE
2029
+	 * Model's $_model_relations array. If this model object doesn't exist in the DB, just removes the related thing
2030
+	 * from the cache
2031
+	 *
2032
+	 * @param mixed  $otherObjectModelObjectOrID
2033
+	 *                EE_Base_Class or the ID of the other object, OR an array key into the cache if this isn't saved
2034
+	 *                to the DB yet
2035
+	 * @param string $relationName
2036
+	 * @param array  $where_query
2037
+	 *                You can optionally include an array of key=>value pairs that allow you to further constrict the
2038
+	 *                relation to being added. However, keep in mind that the columns (keys) given must match a column
2039
+	 *                on the JOIN table and currently only the HABTM models accept these additional conditions. Also
2040
+	 *                remember that if an exact match isn't found for these extra cols/val pairs, then a NEW row is
2041
+	 *                created in the join table.
2042
+	 * @return EE_Base_Class the relation was removed from
2043
+	 * @throws \EE_Error
2044
+	 */
2045
+	public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = array())
2046
+	{
2047
+		if ($this->ID()) {
2048
+			//if this exists in the DB, save the relation change to the DB too
2049
+			$otherObject = $this->get_model()
2050
+								->remove_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2051
+									$where_query);
2052
+			$this->clear_cache($relationName, $otherObject);
2053
+		} else {
2054
+			//this doesn't exist in the DB, just remove it from the cache
2055
+			$otherObject = $this->clear_cache($relationName, $otherObjectModelObjectOrID);
2056
+		}
2057
+		if ($otherObject instanceof EE_Base_Class) {
2058
+			$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2059
+		}
2060
+		return $otherObject;
2061
+	}
2062
+
2063
+
2064
+
2065
+	/**
2066
+	 * Removes ALL the related things for the $relationName.
2067
+	 *
2068
+	 * @param string $relationName
2069
+	 * @param array  $where_query_params like EEM_Base::get_all's $query_params[0] (where conditions)
2070
+	 * @return EE_Base_Class
2071
+	 * @throws \EE_Error
2072
+	 */
2073
+	public function _remove_relations($relationName, $where_query_params = array())
2074
+	{
2075
+		if ($this->ID()) {
2076
+			//if this exists in the DB, save the relation change to the DB too
2077
+			$otherObjects = $this->get_model()->remove_relations($this, $relationName, $where_query_params);
2078
+			$this->clear_cache($relationName, null, true);
2079
+		} else {
2080
+			//this doesn't exist in the DB, just remove it from the cache
2081
+			$otherObjects = $this->clear_cache($relationName, null, true);
2082
+		}
2083
+		if (is_array($otherObjects)) {
2084
+			foreach ($otherObjects as $otherObject) {
2085
+				$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2086
+			}
2087
+		}
2088
+		return $otherObjects;
2089
+	}
2090
+
2091
+
2092
+
2093
+	/**
2094
+	 * Gets all the related model objects of the specified type. Eg, if the current class if
2095
+	 * EE_Event, you could call $this->get_many_related('Registration') to get an array of all the
2096
+	 * EE_Registration objects which related to this event. Note: by default, we remove the "default query params"
2097
+	 * because we want to get even deleted items etc.
2098
+	 *
2099
+	 * @param string $relationName key in the model's _model_relations array
2100
+	 * @param array  $query_params like EEM_Base::get_all
2101
+	 * @return EE_Base_Class[] Results not necessarily indexed by IDs, because some results might not have primary keys
2102
+	 * @throws \EE_Error
2103
+	 *                             or might not be saved yet. Consider using EEM_Base::get_IDs() on these results if
2104
+	 *                             you want IDs
2105
+	 */
2106
+	public function get_many_related($relationName, $query_params = array())
2107
+	{
2108
+		if ($this->ID()) {
2109
+			//this exists in the DB, so get the related things from either the cache or the DB
2110
+			//if there are query parameters, forget about caching the related model objects.
2111
+			if ($query_params) {
2112
+				$related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2113
+			} else {
2114
+				//did we already cache the result of this query?
2115
+				$cached_results = $this->get_all_from_cache($relationName);
2116
+				if ( ! $cached_results) {
2117
+					$related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2118
+					//if no query parameters were passed, then we got all the related model objects
2119
+					//for that relation. We can cache them then.
2120
+					foreach ($related_model_objects as $related_model_object) {
2121
+						$this->cache($relationName, $related_model_object);
2122
+					}
2123
+				} else {
2124
+					$related_model_objects = $cached_results;
2125
+				}
2126
+			}
2127
+		} else {
2128
+			//this doesn't exist in the DB, so just get the related things from the cache
2129
+			$related_model_objects = $this->get_all_from_cache($relationName);
2130
+		}
2131
+		return $related_model_objects;
2132
+	}
2133
+
2134
+
2135
+
2136
+	/**
2137
+	 * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default,
2138
+	 * unless otherwise specified in the $query_params
2139
+	 *
2140
+	 * @param string $relation_name  model_name like 'Event', or 'Registration'
2141
+	 * @param array  $query_params   like EEM_Base::get_all's
2142
+	 * @param string $field_to_count name of field to count by. By default, uses primary key
2143
+	 * @param bool   $distinct       if we want to only count the distinct values for the column then you can trigger
2144
+	 *                               that by the setting $distinct to TRUE;
2145
+	 * @return int
2146
+	 */
2147
+	public function count_related($relation_name, $query_params = array(), $field_to_count = null, $distinct = false)
2148
+	{
2149
+		return $this->get_model()->count_related($this, $relation_name, $query_params, $field_to_count, $distinct);
2150
+	}
2151
+
2152
+
2153
+
2154
+	/**
2155
+	 * Instead of getting the related model objects, simply sums up the values of the specified field.
2156
+	 * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params
2157
+	 *
2158
+	 * @param string $relation_name model_name like 'Event', or 'Registration'
2159
+	 * @param array  $query_params  like EEM_Base::get_all's
2160
+	 * @param string $field_to_sum  name of field to count by.
2161
+	 *                              By default, uses primary key (which doesn't make much sense, so you should probably
2162
+	 *                              change it)
2163
+	 * @return int
2164
+	 */
2165
+	public function sum_related($relation_name, $query_params = array(), $field_to_sum = null)
2166
+	{
2167
+		return $this->get_model()->sum_related($this, $relation_name, $query_params, $field_to_sum);
2168
+	}
2169
+
2170
+
2171
+
2172
+	/**
2173
+	 * Gets the first (ie, one) related model object of the specified type.
2174
+	 *
2175
+	 * @param string $relationName key in the model's _model_relations array
2176
+	 * @param array  $query_params like EEM_Base::get_all
2177
+	 * @return EE_Base_Class (not an array, a single object)
2178
+	 * @throws \EE_Error
2179
+	 */
2180
+	public function get_first_related($relationName, $query_params = array())
2181
+	{
2182
+		if ($this->ID()) {//this exists in the DB, get from the cache OR the DB
2183
+			//if they've provided some query parameters, don't bother trying to cache the result
2184
+			//also make sure we're not caching the result of get_first_related
2185
+			//on a relation which should have an array of objects (because the cache might have an array of objects)
2186
+			if ($query_params
2187
+				|| ! $this->get_model()->related_settings_for($relationName)
2188
+					 instanceof
2189
+					 EE_Belongs_To_Relation
2190
+			) {
2191
+				$related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2192
+			} else {
2193
+				//first, check if we've already cached the result of this query
2194
+				$cached_result = $this->get_one_from_cache($relationName);
2195
+				if ( ! $cached_result) {
2196
+					$related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2197
+					$this->cache($relationName, $related_model_object);
2198
+				} else {
2199
+					$related_model_object = $cached_result;
2200
+				}
2201
+			}
2202
+		} else {
2203
+			$related_model_object = null;
2204
+			//this doesn't exist in the Db, but maybe the relation is of type belongs to, and so the related thing might
2205
+			if ($this->get_model()->related_settings_for($relationName) instanceof EE_Belongs_To_Relation) {
2206
+				$related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2207
+			}
2208
+			//this doesn't exist in the DB and apparently the thing it belongs to doesn't either, just get what's cached on this object
2209
+			if ( ! $related_model_object) {
2210
+				$related_model_object = $this->get_one_from_cache($relationName);
2211
+			}
2212
+		}
2213
+		return $related_model_object;
2214
+	}
2215
+
2216
+
2217
+
2218
+	/**
2219
+	 * Does a delete on all related objects of type $relationName and removes
2220
+	 * the current model object's relation to them. If they can't be deleted (because
2221
+	 * of blocking related model objects) does nothing. If the related model objects are
2222
+	 * soft-deletable, they will be soft-deleted regardless of related blocking model objects.
2223
+	 * If this model object doesn't exist yet in the DB, just removes its related things
2224
+	 *
2225
+	 * @param string $relationName
2226
+	 * @param array  $query_params like EEM_Base::get_all's
2227
+	 * @return int how many deleted
2228
+	 * @throws \EE_Error
2229
+	 */
2230
+	public function delete_related($relationName, $query_params = array())
2231
+	{
2232
+		if ($this->ID()) {
2233
+			$count = $this->get_model()->delete_related($this, $relationName, $query_params);
2234
+		} else {
2235
+			$count = count($this->get_all_from_cache($relationName));
2236
+			$this->clear_cache($relationName, null, true);
2237
+		}
2238
+		return $count;
2239
+	}
2240
+
2241
+
2242
+
2243
+	/**
2244
+	 * Does a hard delete (ie, removes the DB row) on all related objects of type $relationName and removes
2245
+	 * the current model object's relation to them. If they can't be deleted (because
2246
+	 * of blocking related model objects) just does a soft delete on it instead, if possible.
2247
+	 * If the related thing isn't a soft-deletable model object, this function is identical
2248
+	 * to delete_related(). If this model object doesn't exist in the DB, just remove its related things
2249
+	 *
2250
+	 * @param string $relationName
2251
+	 * @param array  $query_params like EEM_Base::get_all's
2252
+	 * @return int how many deleted (including those soft deleted)
2253
+	 * @throws \EE_Error
2254
+	 */
2255
+	public function delete_related_permanently($relationName, $query_params = array())
2256
+	{
2257
+		if ($this->ID()) {
2258
+			$count = $this->get_model()->delete_related_permanently($this, $relationName, $query_params);
2259
+		} else {
2260
+			$count = count($this->get_all_from_cache($relationName));
2261
+		}
2262
+		$this->clear_cache($relationName, null, true);
2263
+		return $count;
2264
+	}
2265
+
2266
+
2267
+
2268
+	/**
2269
+	 * is_set
2270
+	 * Just a simple utility function children can use for checking if property exists
2271
+	 *
2272
+	 * @access  public
2273
+	 * @param  string $field_name property to check
2274
+	 * @return bool                              TRUE if existing,FALSE if not.
2275
+	 */
2276
+	public function is_set($field_name)
2277
+	{
2278
+		return isset($this->_fields[$field_name]);
2279
+	}
2280
+
2281
+
2282
+
2283
+	/**
2284
+	 * Just a simple utility function children can use for checking if property (or properties) exists and throwing an
2285
+	 * EE_Error exception if they don't
2286
+	 *
2287
+	 * @param  mixed (string|array) $properties properties to check
2288
+	 * @throws EE_Error
2289
+	 * @return bool                              TRUE if existing, throw EE_Error if not.
2290
+	 */
2291
+	protected function _property_exists($properties)
2292
+	{
2293
+		foreach ((array)$properties as $property_name) {
2294
+			//first make sure this property exists
2295
+			if ( ! $this->_fields[$property_name]) {
2296
+				throw new EE_Error(
2297
+					sprintf(
2298
+						__(
2299
+							'Trying to retrieve a non-existent property (%s).  Double check the spelling please',
2300
+							'event_espresso'
2301
+						),
2302
+						$property_name
2303
+					)
2304
+				);
2305
+			}
2306
+		}
2307
+		return true;
2308
+	}
2309
+
2310
+
2311
+
2312
+	/**
2313
+	 * This simply returns an array of model fields for this object
2314
+	 *
2315
+	 * @return array
2316
+	 * @throws \EE_Error
2317
+	 */
2318
+	public function model_field_array()
2319
+	{
2320
+		$fields = $this->get_model()->field_settings(false);
2321
+		$properties = array();
2322
+		//remove prepended underscore
2323
+		foreach ($fields as $field_name => $settings) {
2324
+			$properties[$field_name] = $this->get($field_name);
2325
+		}
2326
+		return $properties;
2327
+	}
2328
+
2329
+
2330
+
2331
+	/**
2332
+	 * Very handy general function to allow for plugins to extend any child of EE_Base_Class.
2333
+	 * If a method is called on a child of EE_Base_Class that doesn't exist, this function is called
2334
+	 * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments. Instead of
2335
+	 * requiring a plugin to extend the EE_Base_Class (which works fine is there's only 1 plugin, but when will that
2336
+	 * happen?) they can add a hook onto 'filters_hook_espresso__{className}__{methodName}' (eg,
2337
+	 * filters_hook_espresso__EE_Answer__my_great_function) and accepts 2 arguments: the object on which the function
2338
+	 * was called, and an array of the original arguments passed to the function. Whatever their callback function
2339
+	 * returns will be returned by this function. Example: in functions.php (or in a plugin):
2340
+	 * add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3); function
2341
+	 * my_callback($previousReturnValue,EE_Base_Class $object,$argsArray){
2342
+	 * $returnString= "you called my_callback! and passed args:".implode(",",$argsArray);
2343
+	 *        return $previousReturnValue.$returnString;
2344
+	 * }
2345
+	 * require('EE_Answer.class.php');
2346
+	 * $answer= EE_Answer::new_instance(array('REG_ID' => 2,'QST_ID' => 3,'ANS_value' => The answer is 42'));
2347
+	 * echo $answer->my_callback('monkeys',100);
2348
+	 * //will output "you called my_callback! and passed args:monkeys,100"
2349
+	 *
2350
+	 * @param string $methodName name of method which was called on a child of EE_Base_Class, but which
2351
+	 * @param array  $args       array of original arguments passed to the function
2352
+	 * @throws EE_Error
2353
+	 * @return mixed whatever the plugin which calls add_filter decides
2354
+	 */
2355
+	public function __call($methodName, $args)
2356
+	{
2357
+		$className = get_class($this);
2358
+		$tagName = "FHEE__{$className}__{$methodName}";
2359
+		if ( ! has_filter($tagName)) {
2360
+			throw new EE_Error(
2361
+				sprintf(
2362
+					__(
2363
+						"Method %s on class %s does not exist! You can create one with the following code in functions.php or in a plugin: add_filter('%s','my_callback',10,3);function my_callback(\$previousReturnValue,EE_Base_Class \$object, \$argsArray){/*function body*/return \$whatever;}",
2364
+						"event_espresso"
2365
+					),
2366
+					$methodName,
2367
+					$className,
2368
+					$tagName
2369
+				)
2370
+			);
2371
+		}
2372
+		return apply_filters($tagName, null, $this, $args);
2373
+	}
2374
+
2375
+
2376
+
2377
+	/**
2378
+	 * Similar to insert_post_meta, adds a record in the Extra_Meta model's table with the given key and value.
2379
+	 * A $previous_value can be specified in case there are many meta rows with the same key
2380
+	 *
2381
+	 * @param string $meta_key
2382
+	 * @param mixed  $meta_value
2383
+	 * @param mixed  $previous_value
2384
+	 * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2385
+	 * @throws \EE_Error
2386
+	 * NOTE: if the values haven't changed, returns 0
2387
+	 */
2388
+	public function update_extra_meta($meta_key, $meta_value, $previous_value = null)
2389
+	{
2390
+		$query_params = array(
2391
+			array(
2392
+				'EXM_key'  => $meta_key,
2393
+				'OBJ_ID'   => $this->ID(),
2394
+				'EXM_type' => $this->get_model()->get_this_model_name(),
2395
+			),
2396
+		);
2397
+		if ($previous_value !== null) {
2398
+			$query_params[0]['EXM_value'] = $meta_value;
2399
+		}
2400
+		$existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2401
+		if ( ! $existing_rows_like_that) {
2402
+			return $this->add_extra_meta($meta_key, $meta_value);
2403
+		}
2404
+		foreach ($existing_rows_like_that as $existing_row) {
2405
+			$existing_row->save(array('EXM_value' => $meta_value));
2406
+		}
2407
+		return count($existing_rows_like_that);
2408
+	}
2409
+
2410
+
2411
+
2412
+	/**
2413
+	 * Adds a new extra meta record. If $unique is set to TRUE, we'll first double-check
2414
+	 * no other extra meta for this model object have the same key. Returns TRUE if the
2415
+	 * extra meta row was entered, false if not
2416
+	 *
2417
+	 * @param string  $meta_key
2418
+	 * @param string  $meta_value
2419
+	 * @param boolean $unique
2420
+	 * @return boolean
2421
+	 * @throws \EE_Error
2422
+	 */
2423
+	public function add_extra_meta($meta_key, $meta_value, $unique = false)
2424
+	{
2425
+		if ($unique) {
2426
+			$existing_extra_meta = EEM_Extra_Meta::instance()->get_one(
2427
+				array(
2428
+					array(
2429
+						'EXM_key'  => $meta_key,
2430
+						'OBJ_ID'   => $this->ID(),
2431
+						'EXM_type' => $this->get_model()->get_this_model_name(),
2432
+					),
2433
+				)
2434
+			);
2435
+			if ($existing_extra_meta) {
2436
+				return false;
2437
+			}
2438
+		}
2439
+		$new_extra_meta = EE_Extra_Meta::new_instance(
2440
+			array(
2441
+				'EXM_key'   => $meta_key,
2442
+				'EXM_value' => $meta_value,
2443
+				'OBJ_ID'    => $this->ID(),
2444
+				'EXM_type'  => $this->get_model()->get_this_model_name(),
2445
+			)
2446
+		);
2447
+		$new_extra_meta->save();
2448
+		return true;
2449
+	}
2450
+
2451
+
2452
+
2453
+	/**
2454
+	 * Deletes all the extra meta rows for this record as specified by key. If $meta_value
2455
+	 * is specified, only deletes extra meta records with that value.
2456
+	 *
2457
+	 * @param string $meta_key
2458
+	 * @param string $meta_value
2459
+	 * @return int number of extra meta rows deleted
2460
+	 * @throws \EE_Error
2461
+	 */
2462
+	public function delete_extra_meta($meta_key, $meta_value = null)
2463
+	{
2464
+		$query_params = array(
2465
+			array(
2466
+				'EXM_key'  => $meta_key,
2467
+				'OBJ_ID'   => $this->ID(),
2468
+				'EXM_type' => $this->get_model()->get_this_model_name(),
2469
+			),
2470
+		);
2471
+		if ($meta_value !== null) {
2472
+			$query_params[0]['EXM_value'] = $meta_value;
2473
+		}
2474
+		return EEM_Extra_Meta::instance()->delete($query_params);
2475
+	}
2476
+
2477
+
2478
+
2479
+	/**
2480
+	 * Gets the extra meta with the given meta key. If you specify "single" we just return 1, otherwise
2481
+	 * an array of everything found. Requires that this model actually have a relation of type EE_Has_Many_Any_Relation.
2482
+	 * You can specify $default is case you haven't found the extra meta
2483
+	 *
2484
+	 * @param string  $meta_key
2485
+	 * @param boolean $single
2486
+	 * @param mixed   $default if we don't find anything, what should we return?
2487
+	 * @return mixed single value if $single; array if ! $single
2488
+	 * @throws \EE_Error
2489
+	 */
2490
+	public function get_extra_meta($meta_key, $single = false, $default = null)
2491
+	{
2492
+		if ($single) {
2493
+			$result = $this->get_first_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2494
+			if ($result instanceof EE_Extra_Meta) {
2495
+				return $result->value();
2496
+			} else {
2497
+				return $default;
2498
+			}
2499
+		} else {
2500
+			$results = $this->get_many_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2501
+			if ($results) {
2502
+				$values = array();
2503
+				foreach ($results as $result) {
2504
+					if ($result instanceof EE_Extra_Meta) {
2505
+						$values[$result->ID()] = $result->value();
2506
+					}
2507
+				}
2508
+				return $values;
2509
+			} else {
2510
+				return $default;
2511
+			}
2512
+		}
2513
+	}
2514
+
2515
+
2516
+
2517
+	/**
2518
+	 * Returns a simple array of all the extra meta associated with this model object.
2519
+	 * If $one_of_each_key is true (Default), it will be an array of simple key-value pairs, keys being the
2520
+	 * extra meta's key, and teh value being its value. However, if there are duplicate extra meta rows with
2521
+	 * the same key, only one will be used. (eg array('foo'=>'bar','monkey'=>123))
2522
+	 * If $one_of_each_key is false, it will return an array with the top-level keys being
2523
+	 * the extra meta keys, but their values are also arrays, which have the extra-meta's ID as their sub-key, and
2524
+	 * finally the extra meta's value as each sub-value. (eg
2525
+	 * array('foo'=>array(1=>'bar',2=>'bill'),'monkey'=>array(3=>123)))
2526
+	 *
2527
+	 * @param boolean $one_of_each_key
2528
+	 * @return array
2529
+	 * @throws \EE_Error
2530
+	 */
2531
+	public function all_extra_meta_array($one_of_each_key = true)
2532
+	{
2533
+		$return_array = array();
2534
+		if ($one_of_each_key) {
2535
+			$extra_meta_objs = $this->get_many_related('Extra_Meta', array('group_by' => 'EXM_key'));
2536
+			foreach ($extra_meta_objs as $extra_meta_obj) {
2537
+				if ($extra_meta_obj instanceof EE_Extra_Meta) {
2538
+					$return_array[$extra_meta_obj->key()] = $extra_meta_obj->value();
2539
+				}
2540
+			}
2541
+		} else {
2542
+			$extra_meta_objs = $this->get_many_related('Extra_Meta');
2543
+			foreach ($extra_meta_objs as $extra_meta_obj) {
2544
+				if ($extra_meta_obj instanceof EE_Extra_Meta) {
2545
+					if ( ! isset($return_array[$extra_meta_obj->key()])) {
2546
+						$return_array[$extra_meta_obj->key()] = array();
2547
+					}
2548
+					$return_array[$extra_meta_obj->key()][$extra_meta_obj->ID()] = $extra_meta_obj->value();
2549
+				}
2550
+			}
2551
+		}
2552
+		return $return_array;
2553
+	}
2554
+
2555
+
2556
+
2557
+	/**
2558
+	 * Gets a pretty nice displayable nice for this model object. Often overridden
2559
+	 *
2560
+	 * @return string
2561
+	 * @throws \EE_Error
2562
+	 */
2563
+	public function name()
2564
+	{
2565
+		//find a field that's not a text field
2566
+		$field_we_can_use = $this->get_model()->get_a_field_of_type('EE_Text_Field_Base');
2567
+		if ($field_we_can_use) {
2568
+			return $this->get($field_we_can_use->get_name());
2569
+		} else {
2570
+			$first_few_properties = $this->model_field_array();
2571
+			$first_few_properties = array_slice($first_few_properties, 0, 3);
2572
+			$name_parts = array();
2573
+			foreach ($first_few_properties as $name => $value) {
2574
+				$name_parts[] = "$name:$value";
2575
+			}
2576
+			return implode(",", $name_parts);
2577
+		}
2578
+	}
2579
+
2580
+
2581
+
2582
+	/**
2583
+	 * in_entity_map
2584
+	 * Checks if this model object has been proven to already be in the entity map
2585
+	 *
2586
+	 * @return boolean
2587
+	 * @throws \EE_Error
2588
+	 */
2589
+	public function in_entity_map()
2590
+	{
2591
+		if ($this->ID() && $this->get_model()->get_from_entity_map($this->ID()) === $this) {
2592
+			//well, if we looked, did we find it in the entity map?
2593
+			return true;
2594
+		} else {
2595
+			return false;
2596
+		}
2597
+	}
2598
+
2599
+
2600
+
2601
+	/**
2602
+	 * refresh_from_db
2603
+	 * Makes sure the fields and values on this model object are in-sync with what's in the database.
2604
+	 *
2605
+	 * @throws EE_Error if this model object isn't in the entity mapper (because then you should
2606
+	 * just use what's in the entity mapper and refresh it) and WP_DEBUG is TRUE
2607
+	 */
2608
+	public function refresh_from_db()
2609
+	{
2610
+		if ($this->ID() && $this->in_entity_map()) {
2611
+			$this->get_model()->refresh_entity_map_from_db($this->ID());
2612
+		} else {
2613
+			//if it doesn't have ID, you shouldn't be asking to refresh it from teh database (because its not in the database)
2614
+			//if it has an ID but it's not in the map, and you're asking me to refresh it
2615
+			//that's kinda dangerous. You should just use what's in the entity map, or add this to the entity map if there's
2616
+			//absolutely nothing in it for this ID
2617
+			if (WP_DEBUG) {
2618
+				throw new EE_Error(
2619
+					sprintf(
2620
+						__('Trying to refresh a model object with ID "%1$s" that\'s not in the entity map? First off: you should put it in the entity map by calling %2$s. Second off, if you want what\'s in the database right now, you should just call %3$s yourself and discard this model object.',
2621
+							'event_espresso'),
2622
+						$this->ID(),
2623
+						get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2624
+						get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2625
+					)
2626
+				);
2627
+			}
2628
+		}
2629
+	}
2630
+
2631
+
2632
+
2633
+	/**
2634
+	 * Because some other plugins, like Advanced Cron Manager, expect all objects to have this method
2635
+	 * (probably a bad assumption they have made, oh well)
2636
+	 *
2637
+	 * @return string
2638
+	 */
2639
+	public function __toString()
2640
+	{
2641
+		try {
2642
+			return sprintf('%s (%s)', $this->name(), $this->ID());
2643
+		} catch (Exception $e) {
2644
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2645
+			return '';
2646
+		}
2647
+	}
2648
+
2649
+
2650
+
2651
+	/**
2652
+	 * Clear related model objects if they're already in the DB, because otherwise when we
2653
+	 * UN-serialize this model object we'll need to be careful to add them to the entity map.
2654
+	 * This means if we have made changes to those related model objects, and want to unserialize
2655
+	 * the this model object on a subsequent request, changes to those related model objects will be lost.
2656
+	 * Instead, those related model objects should be directly serialized and stored.
2657
+	 * Eg, the following won't work:
2658
+	 * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2659
+	 * $att = $reg->attendee();
2660
+	 * $att->set( 'ATT_fname', 'Dirk' );
2661
+	 * update_option( 'my_option', serialize( $reg ) );
2662
+	 * //END REQUEST
2663
+	 * //START NEXT REQUEST
2664
+	 * $reg = get_option( 'my_option' );
2665
+	 * $reg->attendee()->save();
2666
+	 * And would need to be replace with:
2667
+	 * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2668
+	 * $att = $reg->attendee();
2669
+	 * $att->set( 'ATT_fname', 'Dirk' );
2670
+	 * update_option( 'my_option', serialize( $reg ) );
2671
+	 * //END REQUEST
2672
+	 * //START NEXT REQUEST
2673
+	 * $att = get_option( 'my_option' );
2674
+	 * $att->save();
2675
+	 *
2676
+	 * @return array
2677
+	 * @throws \EE_Error
2678
+	 */
2679
+	public function __sleep()
2680
+	{
2681
+		foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
2682
+			if ($relation_obj instanceof EE_Belongs_To_Relation) {
2683
+				$classname = 'EE_' . $this->get_model()->get_this_model_name();
2684
+				if (
2685
+					$this->get_one_from_cache($relation_name) instanceof $classname
2686
+					&& $this->get_one_from_cache($relation_name)->ID()
2687
+				) {
2688
+					$this->clear_cache($relation_name, $this->get_one_from_cache($relation_name)->ID());
2689
+				}
2690
+			}
2691
+		}
2692
+		$this->_props_n_values_provided_in_constructor = array();
2693
+		return array_keys(get_object_vars($this));
2694
+	}
2695
+
2696
+
2697
+
2698
+	/**
2699
+	 * restore _props_n_values_provided_in_constructor
2700
+	 * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
2701
+	 * and therefore should NOT be used to determine if state change has occurred since initial construction.
2702
+	 * At best, you would only be able to detect if state change has occurred during THIS request.
2703
+	 */
2704
+	public function __wakeup()
2705
+	{
2706
+		$this->_props_n_values_provided_in_constructor = $this->_fields;
2707
+	}
2708 2708
 
2709 2709
 
2710 2710
 
Please login to merge, or discard this patch.