Completed
Branch models-cleanup/main (de94a1)
by
unknown
61:24 queued 51:13
created
caffeinated/admin/hooks/Global_EE_Caf_Hooks.class.php 2 patches
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -15,42 +15,42 @@
 block discarded – undo
15 15
 class Global_EE_Caf_Hooks
16 16
 {
17 17
 
18
-    public function __construct()
19
-    {
20
-        $this->_do_hooks();
21
-    }
22
-
23
-
24
-    private function _do_hooks()
25
-    {
26
-        add_filter('FHEE_show_sponsors_meta_box', '__return_false', 10);
27
-        add_filter('FHEE_show_ratings_request_meta_box', '__return_false', 10);
28
-        add_filter(
29
-            'FHEE__EE_Admin_Page_Core__load_global_scripts_styles__loader_containers',
30
-            array($this, 'forums_lazy_loading'),
31
-            10
32
-        );
33
-        add_action(
34
-            'AHEE__EE_Admin_Page__espresso_news_post_box__after_content',
35
-            array($this, 'extra_news_box_content'),
36
-            10
37
-        );
38
-    }
39
-
40
-
41
-    public function extra_news_box_content($content)
42
-    {
43
-        echo '<h3 style="margin:0">' . __('From the Forums', 'event_espresso') . '</h3>';
44
-        echo '<div id="ee_forum_posts_content">';
45
-        $url = 'http://eventespresso.com/forum/event-espresso-support/feed/';
46
-        EE_Admin_Page::cached_rss_display('ee_forum_posts_content', $url);
47
-        echo '</div>';
48
-    }
49
-
50
-
51
-    public function forums_lazy_loading($ids)
52
-    {
53
-        $ids[] = 'ee_forum_posts_content';
54
-        return $ids;
55
-    }
18
+	public function __construct()
19
+	{
20
+		$this->_do_hooks();
21
+	}
22
+
23
+
24
+	private function _do_hooks()
25
+	{
26
+		add_filter('FHEE_show_sponsors_meta_box', '__return_false', 10);
27
+		add_filter('FHEE_show_ratings_request_meta_box', '__return_false', 10);
28
+		add_filter(
29
+			'FHEE__EE_Admin_Page_Core__load_global_scripts_styles__loader_containers',
30
+			array($this, 'forums_lazy_loading'),
31
+			10
32
+		);
33
+		add_action(
34
+			'AHEE__EE_Admin_Page__espresso_news_post_box__after_content',
35
+			array($this, 'extra_news_box_content'),
36
+			10
37
+		);
38
+	}
39
+
40
+
41
+	public function extra_news_box_content($content)
42
+	{
43
+		echo '<h3 style="margin:0">' . __('From the Forums', 'event_espresso') . '</h3>';
44
+		echo '<div id="ee_forum_posts_content">';
45
+		$url = 'http://eventespresso.com/forum/event-espresso-support/feed/';
46
+		EE_Admin_Page::cached_rss_display('ee_forum_posts_content', $url);
47
+		echo '</div>';
48
+	}
49
+
50
+
51
+	public function forums_lazy_loading($ids)
52
+	{
53
+		$ids[] = 'ee_forum_posts_content';
54
+		return $ids;
55
+	}
56 56
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -40,7 +40,7 @@
 block discarded – undo
40 40
 
41 41
     public function extra_news_box_content($content)
42 42
     {
43
-        echo '<h3 style="margin:0">' . __('From the Forums', 'event_espresso') . '</h3>';
43
+        echo '<h3 style="margin:0">'.__('From the Forums', 'event_espresso').'</h3>';
44 44
         echo '<div id="ee_forum_posts_content">';
45 45
         $url = 'http://eventespresso.com/forum/event-espresso-support/feed/';
46 46
         EE_Admin_Page::cached_rss_display('ee_forum_posts_content', $url);
Please login to merge, or discard this patch.
registration_form/espresso_events_Registration_Form_Hooks.class.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -52,7 +52,7 @@
 block discarded – undo
52 52
     /**
53 53
      * Callback for FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks hook
54 54
      *
55
-     * @param $callbacks
55
+     * @param callable[] $callbacks
56 56
      * @return array
57 57
      */
58 58
     public function modify_callbacks($callbacks)
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -135,7 +135,7 @@  discard block
 block discarded – undo
135 135
                 : array();
136 136
             $EQGids = array_keys($EQGs);
137 137
 
138
-            if (! empty($QSGs)) {
138
+            if ( ! empty($QSGs)) {
139 139
                 $html = count($QSGs) > 10 ? '<div style="height:250px;overflow:auto;">' : '';
140 140
                 foreach ($QSGs as $QSG) {
141 141
                     $checked = in_array($QSG->ID(), $EQGids, true)
@@ -155,16 +155,16 @@  discard block
 block discarded – undo
155 155
                     );
156 156
 
157 157
                     $html .= '
158
-					<p id="event-question-group-' . $QSG->ID() . '">
159
-						<input value="' . $QSG->ID() . '" type="checkbox"'
158
+					<p id="event-question-group-' . $QSG->ID().'">
159
+						<input value="' . $QSG->ID().'" type="checkbox"'
160 160
                              . $visibility
161
-                             . ' name="question_groups[' . $QSG->ID() . ']"' . $checked . ' />
162
-						<a href="' . $edit_link . '" title="'
161
+                             . ' name="question_groups['.$QSG->ID().']"'.$checked.' />
162
+						<a href="' . $edit_link.'" title="'
163 163
                              . sprintf(
164 164
                                  esc_attr__('Edit %s Group', 'event_espresso'),
165 165
                                  $QSG->get('QSG_name')
166 166
                              )
167
-                             . '" target="_blank">' . $QSG->get('QSG_name') . '</a>
167
+                             . '" target="_blank">'.$QSG->get('QSG_name').'</a>
168 168
 					</p>';
169 169
                 }
170 170
                 $html .= count($QSGs) > 10 ? '</div>' : '';
@@ -203,7 +203,7 @@  discard block
 block discarded – undo
203 203
         $current_qgs = array_keys($current_qgs); // we just want the ids
204 204
 
205 205
         // now let's get the groups selected in the editor and update (IF we have data)
206
-        if (! empty($question_groups)) {
206
+        if ( ! empty($question_groups)) {
207 207
             foreach ($question_groups as $id => $val) {
208 208
                 // add to event
209 209
                 if ($val) {
Please login to merge, or discard this patch.
Indentation   +192 added lines, -192 removed lines patch added patch discarded remove patch
@@ -16,210 +16,210 @@
 block discarded – undo
16 16
 class espresso_events_Registration_Form_Hooks extends EE_Admin_Hooks
17 17
 {
18 18
 
19
-    /**
20
-     * @var EE_Event|null
21
-     */
22
-    protected $_event;
23
-
24
-
25
-    protected function _set_hooks_properties()
26
-    {
27
-
28
-        $this->_name = 'registration_form';
29
-        $this->_metaboxes = array(
30
-            0 => array(
31
-                'page_route' => array('edit', 'create_new'),
32
-                'func'       => 'primary_questions',
33
-                'label'      => esc_html__('Questions for Primary Registrant', 'event_espresso'),
34
-                'priority'   => 'default',
35
-                'context'    => 'side',
36
-            ),
37
-        );
38
-
39
-        // hook into the handler for saving question groups
40
-        add_filter(
41
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
42
-            array($this, 'modify_callbacks'),
43
-            10
44
-        );
45
-
46
-        // hook into revision restores (we're hooking into the global action because EE_Admin_Hooks classes are already
47
-        // restricted by page)
48
-        add_action('AHEE_EE_Admin_Page_CPT__restore_revision', array($this, 'restore_revision'), 10, 2);
49
-    }
50
-
51
-
52
-    /**
53
-     * Callback for FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks hook
54
-     *
55
-     * @param $callbacks
56
-     * @return array
57
-     */
58
-    public function modify_callbacks($callbacks)
59
-    {
60
-        // now let's add the question group callback
61
-        $callbacks[] = array($this, 'primary_question_group_update');
62
-        return $callbacks;
63
-    }
64
-
65
-
66
-    /**
67
-     * Hooked into revision restores.
68
-     *
69
-     * @param $post_id
70
-     * @param $revision_id
71
-     * @return EE_Base_Class
72
-     * @throws EE_Error
73
-     * @throws InvalidArgumentException
74
-     * @throws ReflectionException
75
-     * @throws InvalidDataTypeException
76
-     * @throws InvalidInterfaceException
77
-     */
78
-    public function restore_revision($post_id, $revision_id)
79
-    {
80
-        $EVT_MDL = EE_Registry::instance()->load_model('Event');
81
-        $post_evt = $EVT_MDL->get_one_by_ID($post_id);
82
-        // restore revision for primary questions
83
-        $post_evt->restore_revision(
84
-            $revision_id,
85
-            ['Question_Group'],
86
-            ['Question_Group' => ['Event_Question_Group.EQG_primary' => true]]
87
-        );
88
-        return $post_evt;
89
-    }
90
-
91
-
92
-    /**
93
-     * Content of metabox.
94
-     *
95
-     * @param $post_id
96
-     * @param $post
97
-     * @throws EE_Error
98
-     * @throws InvalidArgumentException
99
-     * @throws InvalidDataTypeException
100
-     * @throws InvalidInterfaceException
101
-     */
102
-    public function primary_questions($post_id, $post)
103
-    {
104
-        $this->_event = $this->_adminpage_obj->get_event_object();
105
-        $event_id = $this->_event->ID();
106
-        ?>
19
+	/**
20
+	 * @var EE_Event|null
21
+	 */
22
+	protected $_event;
23
+
24
+
25
+	protected function _set_hooks_properties()
26
+	{
27
+
28
+		$this->_name = 'registration_form';
29
+		$this->_metaboxes = array(
30
+			0 => array(
31
+				'page_route' => array('edit', 'create_new'),
32
+				'func'       => 'primary_questions',
33
+				'label'      => esc_html__('Questions for Primary Registrant', 'event_espresso'),
34
+				'priority'   => 'default',
35
+				'context'    => 'side',
36
+			),
37
+		);
38
+
39
+		// hook into the handler for saving question groups
40
+		add_filter(
41
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
42
+			array($this, 'modify_callbacks'),
43
+			10
44
+		);
45
+
46
+		// hook into revision restores (we're hooking into the global action because EE_Admin_Hooks classes are already
47
+		// restricted by page)
48
+		add_action('AHEE_EE_Admin_Page_CPT__restore_revision', array($this, 'restore_revision'), 10, 2);
49
+	}
50
+
51
+
52
+	/**
53
+	 * Callback for FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks hook
54
+	 *
55
+	 * @param $callbacks
56
+	 * @return array
57
+	 */
58
+	public function modify_callbacks($callbacks)
59
+	{
60
+		// now let's add the question group callback
61
+		$callbacks[] = array($this, 'primary_question_group_update');
62
+		return $callbacks;
63
+	}
64
+
65
+
66
+	/**
67
+	 * Hooked into revision restores.
68
+	 *
69
+	 * @param $post_id
70
+	 * @param $revision_id
71
+	 * @return EE_Base_Class
72
+	 * @throws EE_Error
73
+	 * @throws InvalidArgumentException
74
+	 * @throws ReflectionException
75
+	 * @throws InvalidDataTypeException
76
+	 * @throws InvalidInterfaceException
77
+	 */
78
+	public function restore_revision($post_id, $revision_id)
79
+	{
80
+		$EVT_MDL = EE_Registry::instance()->load_model('Event');
81
+		$post_evt = $EVT_MDL->get_one_by_ID($post_id);
82
+		// restore revision for primary questions
83
+		$post_evt->restore_revision(
84
+			$revision_id,
85
+			['Question_Group'],
86
+			['Question_Group' => ['Event_Question_Group.EQG_primary' => true]]
87
+		);
88
+		return $post_evt;
89
+	}
90
+
91
+
92
+	/**
93
+	 * Content of metabox.
94
+	 *
95
+	 * @param $post_id
96
+	 * @param $post
97
+	 * @throws EE_Error
98
+	 * @throws InvalidArgumentException
99
+	 * @throws InvalidDataTypeException
100
+	 * @throws InvalidInterfaceException
101
+	 */
102
+	public function primary_questions($post_id, $post)
103
+	{
104
+		$this->_event = $this->_adminpage_obj->get_event_object();
105
+		$event_id = $this->_event->ID();
106
+		?>
107 107
         <div class="inside">
108 108
             <p><strong>
109 109
                     <?php _e('Question Groups', 'event_espresso'); ?>
110 110
                 </strong><br/>
111 111
                 <?php
112
-                printf(
113
-                    esc_html__(
114
-                        'Add a pre-populated %1$sgroup of questions%2$s to your event. The personal information group is required for all events',
115
-                        'event_espresso'
116
-                    ),
117
-                    '<a href="admin.php?page=espresso_registration_form" target="_blank">',
118
-                    '</a>'
119
-                )
120
-                ?>
112
+				printf(
113
+					esc_html__(
114
+						'Add a pre-populated %1$sgroup of questions%2$s to your event. The personal information group is required for all events',
115
+						'event_espresso'
116
+					),
117
+					'<a href="admin.php?page=espresso_registration_form" target="_blank">',
118
+					'</a>'
119
+				)
120
+				?>
121 121
             </p>
122 122
             <?php
123 123
 
124
-            $qsg_where['QSG_deleted'] = false;
125
-            $query_params = apply_filters(
126
-                'FHEE__espresso_events_Registration_Form_Hooks__primary_questions__question_group_query_parameters',
127
-                array($qsg_where, 'order_by' => array('QSG_order' => 'ASC'))
128
-            );
129
-            $QSGs = EEM_Question_Group::instance()->get_all($query_params);
130
-            $EQGs = ! empty($event_id)
131
-                ? $this->_event->get_many_related(
132
-                    'Question_Group',
133
-                    [['Event_Question_Group.EQG_primary' => true]]
134
-                )
135
-                : array();
136
-            $EQGids = array_keys($EQGs);
137
-
138
-            if (! empty($QSGs)) {
139
-                $html = count($QSGs) > 10 ? '<div style="height:250px;overflow:auto;">' : '';
140
-                foreach ($QSGs as $QSG) {
141
-                    $checked = in_array($QSG->ID(), $EQGids, true)
142
-                               || $QSG->get('QSG_system') === 1
143
-                        ? ' checked="checked"'
144
-                        : '';
145
-                    $visibility = $QSG->get('QSG_system') === 1
146
-                        ? ' style="visibility:hidden"'
147
-                        : '';
148
-                    $edit_query_args = $this->_adminpage_obj->is_caf() ? array(
149
-                        'action' => 'edit_question_group',
150
-                        'QSG_ID' => $QSG->ID(),
151
-                    ) : array('action' => 'question_groups');
152
-                    $edit_link = EE_Admin_Page::add_query_args_and_nonce(
153
-                        $edit_query_args,
154
-                        EE_FORMS_ADMIN_URL
155
-                    );
156
-
157
-                    $html .= '
124
+			$qsg_where['QSG_deleted'] = false;
125
+			$query_params = apply_filters(
126
+				'FHEE__espresso_events_Registration_Form_Hooks__primary_questions__question_group_query_parameters',
127
+				array($qsg_where, 'order_by' => array('QSG_order' => 'ASC'))
128
+			);
129
+			$QSGs = EEM_Question_Group::instance()->get_all($query_params);
130
+			$EQGs = ! empty($event_id)
131
+				? $this->_event->get_many_related(
132
+					'Question_Group',
133
+					[['Event_Question_Group.EQG_primary' => true]]
134
+				)
135
+				: array();
136
+			$EQGids = array_keys($EQGs);
137
+
138
+			if (! empty($QSGs)) {
139
+				$html = count($QSGs) > 10 ? '<div style="height:250px;overflow:auto;">' : '';
140
+				foreach ($QSGs as $QSG) {
141
+					$checked = in_array($QSG->ID(), $EQGids, true)
142
+							   || $QSG->get('QSG_system') === 1
143
+						? ' checked="checked"'
144
+						: '';
145
+					$visibility = $QSG->get('QSG_system') === 1
146
+						? ' style="visibility:hidden"'
147
+						: '';
148
+					$edit_query_args = $this->_adminpage_obj->is_caf() ? array(
149
+						'action' => 'edit_question_group',
150
+						'QSG_ID' => $QSG->ID(),
151
+					) : array('action' => 'question_groups');
152
+					$edit_link = EE_Admin_Page::add_query_args_and_nonce(
153
+						$edit_query_args,
154
+						EE_FORMS_ADMIN_URL
155
+					);
156
+
157
+					$html .= '
158 158
 					<p id="event-question-group-' . $QSG->ID() . '">
159 159
 						<input value="' . $QSG->ID() . '" type="checkbox"'
160
-                             . $visibility
161
-                             . ' name="question_groups[' . $QSG->ID() . ']"' . $checked . ' />
160
+							 . $visibility
161
+							 . ' name="question_groups[' . $QSG->ID() . ']"' . $checked . ' />
162 162
 						<a href="' . $edit_link . '" title="'
163
-                             . sprintf(
164
-                                 esc_attr__('Edit %s Group', 'event_espresso'),
165
-                                 $QSG->get('QSG_name')
166
-                             )
167
-                             . '" target="_blank">' . $QSG->get('QSG_name') . '</a>
163
+							 . sprintf(
164
+								 esc_attr__('Edit %s Group', 'event_espresso'),
165
+								 $QSG->get('QSG_name')
166
+							 )
167
+							 . '" target="_blank">' . $QSG->get('QSG_name') . '</a>
168 168
 					</p>';
169
-                }
170
-                $html .= count($QSGs) > 10 ? '</div>' : '';
171
-
172
-                echo $html;
173
-            } else {
174
-                esc_html_e(
175
-                    'There seems to be a problem with your questions. Please contact [email protected]',
176
-                    'event_espresso'
177
-                );
178
-            }
179
-            do_action('AHEE_event_editor_questions_notice');
180
-            ?>
169
+				}
170
+				$html .= count($QSGs) > 10 ? '</div>' : '';
171
+
172
+				echo $html;
173
+			} else {
174
+				esc_html_e(
175
+					'There seems to be a problem with your questions. Please contact [email protected]',
176
+					'event_espresso'
177
+				);
178
+			}
179
+			do_action('AHEE_event_editor_questions_notice');
180
+			?>
181 181
         </div>
182 182
         <?php
183
-    }
184
-
185
-
186
-    /**
187
-     * @param EE_Event $evtobj
188
-     * @param array    $data
189
-     * @return bool
190
-     * @throws EE_Error
191
-     */
192
-    public function primary_question_group_update($evtobj, $data)
193
-    {
194
-        $question_groups = ! empty($data['question_groups']) ? (array) $data['question_groups'] : array();
195
-        $added_qgs = array_keys($question_groups);
196
-        $success = array();
197
-
198
-        // let's get all current question groups associated with this event.
199
-        $current_qgs = $evtobj->get_many_related(
200
-            'Question_Group',
201
-            [['Event_Question_Group.EQG_primary' => true]]
202
-        );
203
-        $current_qgs = array_keys($current_qgs); // we just want the ids
204
-
205
-        // now let's get the groups selected in the editor and update (IF we have data)
206
-        if (! empty($question_groups)) {
207
-            foreach ($question_groups as $id => $val) {
208
-                // add to event
209
-                if ($val) {
210
-                    $qg = $evtobj->_add_relation_to($id, 'Question_Group', ['EQG_primary' => true]);
211
-                }
212
-                $success[] = ! empty($qg) ? 1 : 0;
213
-            }
214
-        }
215
-
216
-        // wait a minute... are there question groups missing in the saved groups that ARE with the current event?
217
-        $removed_qgs = array_diff($current_qgs, $added_qgs);
218
-
219
-        foreach ($removed_qgs as $qgid) {
220
-            $qg = $evtobj->_remove_relation_to($qgid, 'Question_Group', ['EQG_primary' => true]);
221
-            $success[] = ! empty($qg) ? 1 : 0;
222
-        }
223
-        return in_array(0, $success, true) ? false : true;
224
-    }
183
+	}
184
+
185
+
186
+	/**
187
+	 * @param EE_Event $evtobj
188
+	 * @param array    $data
189
+	 * @return bool
190
+	 * @throws EE_Error
191
+	 */
192
+	public function primary_question_group_update($evtobj, $data)
193
+	{
194
+		$question_groups = ! empty($data['question_groups']) ? (array) $data['question_groups'] : array();
195
+		$added_qgs = array_keys($question_groups);
196
+		$success = array();
197
+
198
+		// let's get all current question groups associated with this event.
199
+		$current_qgs = $evtobj->get_many_related(
200
+			'Question_Group',
201
+			[['Event_Question_Group.EQG_primary' => true]]
202
+		);
203
+		$current_qgs = array_keys($current_qgs); // we just want the ids
204
+
205
+		// now let's get the groups selected in the editor and update (IF we have data)
206
+		if (! empty($question_groups)) {
207
+			foreach ($question_groups as $id => $val) {
208
+				// add to event
209
+				if ($val) {
210
+					$qg = $evtobj->_add_relation_to($id, 'Question_Group', ['EQG_primary' => true]);
211
+				}
212
+				$success[] = ! empty($qg) ? 1 : 0;
213
+			}
214
+		}
215
+
216
+		// wait a minute... are there question groups missing in the saved groups that ARE with the current event?
217
+		$removed_qgs = array_diff($current_qgs, $added_qgs);
218
+
219
+		foreach ($removed_qgs as $qgid) {
220
+			$qg = $evtobj->_remove_relation_to($qgid, 'Question_Group', ['EQG_primary' => true]);
221
+			$success[] = ! empty($qg) ? 1 : 0;
222
+		}
223
+		return in_array(0, $success, true) ? false : true;
224
+	}
225 225
 }
Please login to merge, or discard this patch.
core/business/EE_Transaction_Payments.class.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -137,7 +137,7 @@
 block discarded – undo
137 137
      * @param EE_Transaction $transaction
138 138
      * @param string         $payment_status One of EEM_Payment's statuses, like 'PAP' (Approved).
139 139
      *                                       By default, searches for approved payments
140
-     * @return float|false   float on success, false on fail
140
+     * @return double   float on success, false on fail
141 141
      * @throws \EE_Error
142 142
      */
143 143
     public function recalculate_total_payments_for_transaction(
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -43,7 +43,7 @@  discard block
 block discarded – undo
43 43
     public static function instance()
44 44
     {
45 45
         // check if class object is instantiated
46
-        if (! self::$_instance instanceof EE_Transaction_Payments) {
46
+        if ( ! self::$_instance instanceof EE_Transaction_Payments) {
47 47
             self::$_instance = new self();
48 48
         }
49 49
         return self::$_instance;
@@ -62,7 +62,7 @@  discard block
 block discarded – undo
62 62
     public function recalculate_transaction_total(EE_Transaction $transaction, $update_txn = true)
63 63
     {
64 64
         $total_line_item = $transaction->total_line_item();
65
-        if (! $total_line_item instanceof EE_Line_Item) {
65
+        if ( ! $total_line_item instanceof EE_Line_Item) {
66 66
             EE_Error::add_error(
67 67
                 sprintf(
68 68
                     __('The Total Line Item for Transaction %1$d\'s was not found or is invalid.', 'event_espresso'),
@@ -101,7 +101,7 @@  discard block
 block discarded – undo
101 101
     public function calculate_total_payments_and_update_status(EE_Transaction $transaction, $update_txn = true)
102 102
     {
103 103
         // verify transaction
104
-        if (! $transaction instanceof EE_Transaction) {
104
+        if ( ! $transaction instanceof EE_Transaction) {
105 105
             EE_Error::add_error(
106 106
                 __('Please provide a valid EE_Transaction object.', 'event_espresso'),
107 107
                 __FILE__,
@@ -116,7 +116,7 @@  discard block
 block discarded – undo
116 116
         if ($total_paid !== false && (float) $total_paid !== $transaction->paid()) {
117 117
             $transaction->set_paid($total_paid);
118 118
             // maybe update status, and make sure to save transaction if not done already
119
-            if (! $transaction->update_status_based_on_total_paid($update_txn)) {
119
+            if ( ! $transaction->update_status_based_on_total_paid($update_txn)) {
120 120
                 if ($update_txn) {
121 121
                     return $transaction->save() ? true : false;
122 122
                 }
@@ -145,7 +145,7 @@  discard block
 block discarded – undo
145 145
         $payment_status = EEM_Payment::status_id_approved
146 146
     ) {
147 147
         // verify transaction
148
-        if (! $transaction instanceof EE_Transaction) {
148
+        if ( ! $transaction instanceof EE_Transaction) {
149 149
             EE_Error::add_error(
150 150
                 __('Please provide a valid EE_Transaction object.', 'event_espresso'),
151 151
                 __FILE__,
@@ -178,7 +178,7 @@  discard block
 block discarded – undo
178 178
     public function delete_payment_and_update_transaction(EE_Payment $payment)
179 179
     {
180 180
         // verify payment
181
-        if (! $payment instanceof EE_Payment) {
181
+        if ( ! $payment instanceof EE_Payment) {
182 182
             EE_Error::add_error(
183 183
                 __('A valid Payment object was not received.', 'event_espresso'),
184 184
                 __FILE__,
@@ -187,10 +187,10 @@  discard block
 block discarded – undo
187 187
             );
188 188
             return false;
189 189
         }
190
-        if (! $this->delete_registration_payments_and_update_registrations($payment)) {
190
+        if ( ! $this->delete_registration_payments_and_update_registrations($payment)) {
191 191
             return false;
192 192
         }
193
-        if (! $payment->delete()) {
193
+        if ( ! $payment->delete()) {
194 194
             EE_Error::add_error(
195 195
                 __('The payment could not be deleted.', 'event_espresso'),
196 196
                 __FILE__,
@@ -213,7 +213,7 @@  discard block
 block discarded – undo
213 213
 
214 214
         // if this fails, that just means that the transaction didn't get its status changed and/or updated.
215 215
         // however the payment was still deleted.
216
-        if (! $this->calculate_total_payments_and_update_status($transaction)) {
216
+        if ( ! $this->calculate_total_payments_and_update_status($transaction)) {
217 217
             EE_Error::add_attention(
218 218
                 __(
219 219
                     'It appears that the Payment was deleted but no change was recorded for the Transaction for an unknown reason. Please verify that all data for this Transaction looks correct..',
@@ -255,7 +255,7 @@  discard block
 block discarded – undo
255 255
         $reg_payment_query_params = ! empty($reg_payment_query_params) ? $reg_payment_query_params
256 256
             : array(array('PAY_ID' => $payment->ID()));
257 257
         $registration_payments = EEM_Registration_Payment::instance()->get_all($reg_payment_query_params);
258
-        if (! empty($registration_payments)) {
258
+        if ( ! empty($registration_payments)) {
259 259
             foreach ($registration_payments as $registration_payment) {
260 260
                 if ($registration_payment instanceof EE_Registration_Payment) {
261 261
                     $amount_paid = $registration_payment->amount();
@@ -321,7 +321,7 @@  discard block
 block discarded – undo
321 321
     public function update_transaction_status_based_on_total_paid(EE_Transaction $transaction, $update_txn = true)
322 322
     {
323 323
         EE_Error::doing_it_wrong(
324
-            __CLASS__ . '::' . __FUNCTION__,
324
+            __CLASS__.'::'.__FUNCTION__,
325 325
             sprintf(
326 326
                 __('This method is deprecated. Please use "%s" instead', 'event_espresso'),
327 327
                 'EE_Transaction::update_status_based_on_total_paid()'
@@ -330,7 +330,7 @@  discard block
 block discarded – undo
330 330
             '5.0.0'
331 331
         );
332 332
         // verify transaction
333
-        if (! $transaction instanceof EE_Transaction) {
333
+        if ( ! $transaction instanceof EE_Transaction) {
334 334
             EE_Error::add_error(
335 335
                 __('Please provide a valid EE_Transaction object.', 'event_espresso'),
336 336
                 __FILE__,
Please login to merge, or discard this patch.
Indentation   +420 added lines, -420 removed lines patch added patch discarded remove patch
@@ -15,424 +15,424 @@
 block discarded – undo
15 15
 class EE_Transaction_Payments
16 16
 {
17 17
 
18
-    /**
19
-     * @var EE_Transaction_Payments $_instance
20
-     * @access    private
21
-     */
22
-    private static $_instance;
23
-
24
-    /**
25
-     * @deprecated
26
-     * @var string
27
-     */
28
-    protected $_old_txn_status;
29
-
30
-    /**
31
-     * @deprecated
32
-     * @var string
33
-     */
34
-    protected $_new_txn_status;
35
-
36
-
37
-    /**
38
-     * @singleton method used to instantiate class object
39
-     * @access    public
40
-     * @return EE_Transaction_Payments instance
41
-     */
42
-    public static function instance()
43
-    {
44
-        // check if class object is instantiated
45
-        if (! self::$_instance instanceof EE_Transaction_Payments) {
46
-            self::$_instance = new self();
47
-        }
48
-        return self::$_instance;
49
-    }
50
-
51
-
52
-    /**
53
-     * recalculate_transaction_total
54
-     *
55
-     * @access private
56
-     * @param EE_Transaction $transaction
57
-     * @param bool           $update_txn
58
-     * @return bool true if TXN total was updated, false if not
59
-     * @throws \EE_Error
60
-     */
61
-    public function recalculate_transaction_total(EE_Transaction $transaction, $update_txn = true)
62
-    {
63
-        $total_line_item = $transaction->total_line_item();
64
-        if (! $total_line_item instanceof EE_Line_Item) {
65
-            EE_Error::add_error(
66
-                sprintf(
67
-                    __('The Total Line Item for Transaction %1$d\'s was not found or is invalid.', 'event_espresso'),
68
-                    $transaction->ID()
69
-                ),
70
-                __FILE__,
71
-                __FUNCTION__,
72
-                __LINE__
73
-            );
74
-            return false;
75
-        }
76
-        $new_total = $total_line_item->recalculate_total_including_taxes();
77
-        $transaction->set_total($new_total);
78
-        if ($update_txn) {
79
-            return $transaction->save() ? true : false;
80
-        }
81
-        return false;
82
-    }
83
-
84
-
85
-    /**
86
-     * Updates the provided EE_Transaction with all the applicable payments
87
-     * returns a boolean for whether the TXN was saved to the db
88
-     * (meaning a status change occurred)
89
-     * or not saved (which could **still** mean that
90
-     * the TXN status changed, but just was not yet saved).
91
-     * So if passing a value of false for the $update_txn param,
92
-     * then client code needs to take responsibility for saving the TXN
93
-     * regardless of what happens within EE_Transaction_Payments;
94
-     *
95
-     * @param            EE_Transaction /int $transaction_obj_or_id EE_Transaction or its ID
96
-     * @param    boolean $update_txn whether to save the TXN
97
-     * @return    boolean        whether the TXN was saved
98
-     * @throws \EE_Error
99
-     */
100
-    public function calculate_total_payments_and_update_status(EE_Transaction $transaction, $update_txn = true)
101
-    {
102
-        // verify transaction
103
-        if (! $transaction instanceof EE_Transaction) {
104
-            EE_Error::add_error(
105
-                __('Please provide a valid EE_Transaction object.', 'event_espresso'),
106
-                __FILE__,
107
-                __FUNCTION__,
108
-                __LINE__
109
-            );
110
-            return false;
111
-        }
112
-        // calculate total paid
113
-        $total_paid = $this->recalculate_total_payments_for_transaction($transaction);
114
-        // if total paid has changed
115
-        if ($total_paid !== false && (float) $total_paid !== $transaction->paid()) {
116
-            $transaction->set_paid($total_paid);
117
-            // maybe update status, and make sure to save transaction if not done already
118
-            if (! $transaction->update_status_based_on_total_paid($update_txn)) {
119
-                if ($update_txn) {
120
-                    return $transaction->save() ? true : false;
121
-                }
122
-            } else {
123
-                // the status got updated and was saved by
124
-                // update_transaction_status_based_on_total_paid()
125
-                return true;
126
-            }
127
-        }
128
-        return false;
129
-    }
130
-
131
-
132
-    /**
133
-     * recalculate_total_payments_for_transaction
134
-     *
135
-     * @access public
136
-     * @param EE_Transaction $transaction
137
-     * @param string         $payment_status One of EEM_Payment's statuses, like 'PAP' (Approved).
138
-     *                                       By default, searches for approved payments
139
-     * @return float|false   float on success, false on fail
140
-     * @throws \EE_Error
141
-     */
142
-    public function recalculate_total_payments_for_transaction(
143
-        EE_Transaction $transaction,
144
-        $payment_status = EEM_Payment::status_id_approved
145
-    ) {
146
-        // verify transaction
147
-        if (! $transaction instanceof EE_Transaction) {
148
-            EE_Error::add_error(
149
-                __('Please provide a valid EE_Transaction object.', 'event_espresso'),
150
-                __FILE__,
151
-                __FUNCTION__,
152
-                __LINE__
153
-            );
154
-            return false;
155
-        }
156
-        // ensure Payment model is loaded
157
-        EE_Registry::instance()->load_model('Payment');
158
-        // calls EEM_Base::sum()
159
-        return EEM_Payment::instance()->sum(
160
-            // query params
161
-            array(array('TXN_ID' => $transaction->ID(), 'STS_ID' => $payment_status)),
162
-            // field to sum
163
-            'PAY_amount'
164
-        );
165
-    }
166
-
167
-
168
-    /**
169
-     * delete_payment_and_update_transaction
170
-     * Before deleting the selected payment, we fetch it's transaction,
171
-     * then delete the payment, and update the transactions' amount paid.
172
-     *
173
-     * @param EE_Payment $payment
174
-     * @return boolean
175
-     * @throws \EE_Error
176
-     */
177
-    public function delete_payment_and_update_transaction(EE_Payment $payment)
178
-    {
179
-        // verify payment
180
-        if (! $payment instanceof EE_Payment) {
181
-            EE_Error::add_error(
182
-                __('A valid Payment object was not received.', 'event_espresso'),
183
-                __FILE__,
184
-                __FUNCTION__,
185
-                __LINE__
186
-            );
187
-            return false;
188
-        }
189
-        if (! $this->delete_registration_payments_and_update_registrations($payment)) {
190
-            return false;
191
-        }
192
-        if (! $payment->delete()) {
193
-            EE_Error::add_error(
194
-                __('The payment could not be deleted.', 'event_espresso'),
195
-                __FILE__,
196
-                __FUNCTION__,
197
-                __LINE__
198
-            );
199
-            return false;
200
-        }
201
-
202
-        $transaction = $payment->transaction();
203
-        $TXN_status = $transaction->status_ID();
204
-        if (
205
-            $TXN_status === EEM_Transaction::abandoned_status_code
206
-            || $TXN_status === EEM_Transaction::failed_status_code
207
-            || $payment->amount() === 0
208
-        ) {
209
-            EE_Error::add_success(__('The Payment was successfully deleted.', 'event_espresso'));
210
-            return true;
211
-        }
212
-
213
-
214
-        // if this fails, that just means that the transaction didn't get its status changed and/or updated.
215
-        // however the payment was still deleted.
216
-        if (! $this->calculate_total_payments_and_update_status($transaction)) {
217
-            EE_Error::add_attention(
218
-                __(
219
-                    'It appears that the Payment was deleted but no change was recorded for the Transaction for an unknown reason. Please verify that all data for this Transaction looks correct..',
220
-                    'event_espresso'
221
-                ),
222
-                __FILE__,
223
-                __FUNCTION__,
224
-                __LINE__
225
-            );
226
-            return true;
227
-        }
228
-
229
-        EE_Error::add_success(
230
-            __(
231
-                'The Payment was successfully deleted, and the Transaction has been updated accordingly.',
232
-                'event_espresso'
233
-            )
234
-        );
235
-        return true;
236
-    }
237
-
238
-
239
-    /**
240
-     * delete_registration_payments_and_update_registrations
241
-     *
242
-     * removes all registration payment records associated with a payment
243
-     * and subtracts their amounts from the corresponding registrations REG_paid field
244
-     *
245
-     * @param EE_Payment $payment
246
-     * @param array      $reg_payment_query_params
247
-     * @return bool
248
-     * @throws \EE_Error
249
-     */
250
-    public function delete_registration_payments_and_update_registrations(
251
-        EE_Payment $payment,
252
-        $reg_payment_query_params = array()
253
-    ) {
254
-        $save_payment = false;
255
-        $reg_payment_query_params = ! empty($reg_payment_query_params) ? $reg_payment_query_params
256
-            : array(array('PAY_ID' => $payment->ID()));
257
-        $registration_payments = EEM_Registration_Payment::instance()->get_all($reg_payment_query_params);
258
-        if (! empty($registration_payments)) {
259
-            foreach ($registration_payments as $registration_payment) {
260
-                if ($registration_payment instanceof EE_Registration_Payment) {
261
-                    $amount_paid = $registration_payment->amount();
262
-                    $registration = $registration_payment->registration();
263
-                    if ($registration instanceof EE_Registration) {
264
-                        $registration->set_paid($registration->paid() - $amount_paid);
265
-                        if ($registration->save() !== false) {
266
-                            $registration_payment->delete_permanently();
267
-                            $save_payment = true;
268
-                        }
269
-                    } else {
270
-                        EE_Error::add_error(
271
-                            sprintf(
272
-                                __(
273
-                                    'An invalid Registration object was associated with Registration Payment ID# %1$d.',
274
-                                    'event_espresso'
275
-                                ),
276
-                                $registration_payment->ID()
277
-                            ),
278
-                            __FILE__,
279
-                            __FUNCTION__,
280
-                            __LINE__
281
-                        );
282
-                        return false;
283
-                    }
284
-                } else {
285
-                    EE_Error::add_error(
286
-                        sprintf(
287
-                            __(
288
-                                'An invalid Registration Payment object was associated with payment ID# %1$d.',
289
-                                'event_espresso'
290
-                            ),
291
-                            $payment->ID()
292
-                        ),
293
-                        __FILE__,
294
-                        __FUNCTION__,
295
-                        __LINE__
296
-                    );
297
-                    return false;
298
-                }
299
-            }
300
-        }
301
-        if ($save_payment) {
302
-            $payment->save();
303
-        }
304
-        return true;
305
-    }
306
-
307
-
308
-
309
-    /********************************** DEPRECATED METHODS **********************************/
310
-
311
-
312
-    /**
313
-     * possibly toggles TXN status
314
-     *
315
-     * @deprecated 4.9.1
316
-     * @param EE_Transaction $transaction
317
-     * @param    boolean     $update_txn whether to save the TXN
318
-     * @return    boolean        whether the TXN was saved
319
-     * @throws \EE_Error
320
-     */
321
-    public function update_transaction_status_based_on_total_paid(EE_Transaction $transaction, $update_txn = true)
322
-    {
323
-        EE_Error::doing_it_wrong(
324
-            __CLASS__ . '::' . __FUNCTION__,
325
-            sprintf(
326
-                __('This method is deprecated. Please use "%s" instead', 'event_espresso'),
327
-                'EE_Transaction::update_status_based_on_total_paid()'
328
-            ),
329
-            '4.9.1',
330
-            '5.0.0'
331
-        );
332
-        // verify transaction
333
-        if (! $transaction instanceof EE_Transaction) {
334
-            EE_Error::add_error(
335
-                __('Please provide a valid EE_Transaction object.', 'event_espresso'),
336
-                __FILE__,
337
-                __FUNCTION__,
338
-                __LINE__
339
-            );
340
-            return false;
341
-        }
342
-        // set transaction status based on comparison of TXN_paid vs TXN_total
343
-        return $transaction->update_status_based_on_total_paid($update_txn);
344
-    }
345
-
346
-
347
-    /**
348
-     * @deprecated 4.9.12
349
-     * @return string
350
-     */
351
-    public function old_txn_status()
352
-    {
353
-        EE_Error::doing_it_wrong(
354
-            __METHOD__,
355
-            esc_html__(
356
-                'This logic has been moved into \EE_Transaction::old_txn_status(), please use that method instead.',
357
-                'event_espresso'
358
-            ),
359
-            '4.9.12'
360
-        );
361
-        return $this->_old_txn_status;
362
-    }
363
-
364
-
365
-    /**
366
-     * @deprecated 4.9.12
367
-     * @param string $old_txn_status
368
-     */
369
-    public function set_old_txn_status($old_txn_status)
370
-    {
371
-        EE_Error::doing_it_wrong(
372
-            __METHOD__,
373
-            esc_html__(
374
-                'This logic has been moved into \EE_Transaction::set_old_txn_status(), please use that method instead.',
375
-                'event_espresso'
376
-            ),
377
-            '4.9.12'
378
-        );
379
-        // only set the first time
380
-        if ($this->_old_txn_status === null) {
381
-            $this->_old_txn_status = $old_txn_status;
382
-        }
383
-    }
384
-
385
-
386
-    /**
387
-     * @deprecated 4.9.12
388
-     * @return string
389
-     */
390
-    public function new_txn_status()
391
-    {
392
-        EE_Error::doing_it_wrong(
393
-            __METHOD__,
394
-            esc_html__(
395
-                'This logic has been removed. Please just use \EE_Transaction::status_ID() instead.',
396
-                'event_espresso'
397
-            ),
398
-            '4.9.12'
399
-        );
400
-        return $this->_new_txn_status;
401
-    }
402
-
403
-
404
-    /**
405
-     * @deprecated 4.9.12
406
-     * @param string $new_txn_status
407
-     */
408
-    public function set_new_txn_status($new_txn_status)
409
-    {
410
-        EE_Error::doing_it_wrong(
411
-            __METHOD__,
412
-            esc_html__(
413
-                'This logic has been removed. Please just use \EE_Transaction::set_status() instead.',
414
-                'event_espresso'
415
-            ),
416
-            '4.9.12'
417
-        );
418
-        $this->_new_txn_status = $new_txn_status;
419
-    }
420
-
421
-
422
-    /**
423
-     * @deprecated 4.9.12
424
-     * @return bool
425
-     */
426
-    public function txn_status_updated()
427
-    {
428
-        EE_Error::doing_it_wrong(
429
-            __METHOD__,
430
-            esc_html__(
431
-                'This logic has been moved into \EE_Transaction::txn_status_updated(), please use that method instead.',
432
-                'event_espresso'
433
-            ),
434
-            '4.9.12'
435
-        );
436
-        return $this->_new_txn_status !== $this->_old_txn_status && $this->_old_txn_status !== null ? true : false;
437
-    }
18
+	/**
19
+	 * @var EE_Transaction_Payments $_instance
20
+	 * @access    private
21
+	 */
22
+	private static $_instance;
23
+
24
+	/**
25
+	 * @deprecated
26
+	 * @var string
27
+	 */
28
+	protected $_old_txn_status;
29
+
30
+	/**
31
+	 * @deprecated
32
+	 * @var string
33
+	 */
34
+	protected $_new_txn_status;
35
+
36
+
37
+	/**
38
+	 * @singleton method used to instantiate class object
39
+	 * @access    public
40
+	 * @return EE_Transaction_Payments instance
41
+	 */
42
+	public static function instance()
43
+	{
44
+		// check if class object is instantiated
45
+		if (! self::$_instance instanceof EE_Transaction_Payments) {
46
+			self::$_instance = new self();
47
+		}
48
+		return self::$_instance;
49
+	}
50
+
51
+
52
+	/**
53
+	 * recalculate_transaction_total
54
+	 *
55
+	 * @access private
56
+	 * @param EE_Transaction $transaction
57
+	 * @param bool           $update_txn
58
+	 * @return bool true if TXN total was updated, false if not
59
+	 * @throws \EE_Error
60
+	 */
61
+	public function recalculate_transaction_total(EE_Transaction $transaction, $update_txn = true)
62
+	{
63
+		$total_line_item = $transaction->total_line_item();
64
+		if (! $total_line_item instanceof EE_Line_Item) {
65
+			EE_Error::add_error(
66
+				sprintf(
67
+					__('The Total Line Item for Transaction %1$d\'s was not found or is invalid.', 'event_espresso'),
68
+					$transaction->ID()
69
+				),
70
+				__FILE__,
71
+				__FUNCTION__,
72
+				__LINE__
73
+			);
74
+			return false;
75
+		}
76
+		$new_total = $total_line_item->recalculate_total_including_taxes();
77
+		$transaction->set_total($new_total);
78
+		if ($update_txn) {
79
+			return $transaction->save() ? true : false;
80
+		}
81
+		return false;
82
+	}
83
+
84
+
85
+	/**
86
+	 * Updates the provided EE_Transaction with all the applicable payments
87
+	 * returns a boolean for whether the TXN was saved to the db
88
+	 * (meaning a status change occurred)
89
+	 * or not saved (which could **still** mean that
90
+	 * the TXN status changed, but just was not yet saved).
91
+	 * So if passing a value of false for the $update_txn param,
92
+	 * then client code needs to take responsibility for saving the TXN
93
+	 * regardless of what happens within EE_Transaction_Payments;
94
+	 *
95
+	 * @param            EE_Transaction /int $transaction_obj_or_id EE_Transaction or its ID
96
+	 * @param    boolean $update_txn whether to save the TXN
97
+	 * @return    boolean        whether the TXN was saved
98
+	 * @throws \EE_Error
99
+	 */
100
+	public function calculate_total_payments_and_update_status(EE_Transaction $transaction, $update_txn = true)
101
+	{
102
+		// verify transaction
103
+		if (! $transaction instanceof EE_Transaction) {
104
+			EE_Error::add_error(
105
+				__('Please provide a valid EE_Transaction object.', 'event_espresso'),
106
+				__FILE__,
107
+				__FUNCTION__,
108
+				__LINE__
109
+			);
110
+			return false;
111
+		}
112
+		// calculate total paid
113
+		$total_paid = $this->recalculate_total_payments_for_transaction($transaction);
114
+		// if total paid has changed
115
+		if ($total_paid !== false && (float) $total_paid !== $transaction->paid()) {
116
+			$transaction->set_paid($total_paid);
117
+			// maybe update status, and make sure to save transaction if not done already
118
+			if (! $transaction->update_status_based_on_total_paid($update_txn)) {
119
+				if ($update_txn) {
120
+					return $transaction->save() ? true : false;
121
+				}
122
+			} else {
123
+				// the status got updated and was saved by
124
+				// update_transaction_status_based_on_total_paid()
125
+				return true;
126
+			}
127
+		}
128
+		return false;
129
+	}
130
+
131
+
132
+	/**
133
+	 * recalculate_total_payments_for_transaction
134
+	 *
135
+	 * @access public
136
+	 * @param EE_Transaction $transaction
137
+	 * @param string         $payment_status One of EEM_Payment's statuses, like 'PAP' (Approved).
138
+	 *                                       By default, searches for approved payments
139
+	 * @return float|false   float on success, false on fail
140
+	 * @throws \EE_Error
141
+	 */
142
+	public function recalculate_total_payments_for_transaction(
143
+		EE_Transaction $transaction,
144
+		$payment_status = EEM_Payment::status_id_approved
145
+	) {
146
+		// verify transaction
147
+		if (! $transaction instanceof EE_Transaction) {
148
+			EE_Error::add_error(
149
+				__('Please provide a valid EE_Transaction object.', 'event_espresso'),
150
+				__FILE__,
151
+				__FUNCTION__,
152
+				__LINE__
153
+			);
154
+			return false;
155
+		}
156
+		// ensure Payment model is loaded
157
+		EE_Registry::instance()->load_model('Payment');
158
+		// calls EEM_Base::sum()
159
+		return EEM_Payment::instance()->sum(
160
+			// query params
161
+			array(array('TXN_ID' => $transaction->ID(), 'STS_ID' => $payment_status)),
162
+			// field to sum
163
+			'PAY_amount'
164
+		);
165
+	}
166
+
167
+
168
+	/**
169
+	 * delete_payment_and_update_transaction
170
+	 * Before deleting the selected payment, we fetch it's transaction,
171
+	 * then delete the payment, and update the transactions' amount paid.
172
+	 *
173
+	 * @param EE_Payment $payment
174
+	 * @return boolean
175
+	 * @throws \EE_Error
176
+	 */
177
+	public function delete_payment_and_update_transaction(EE_Payment $payment)
178
+	{
179
+		// verify payment
180
+		if (! $payment instanceof EE_Payment) {
181
+			EE_Error::add_error(
182
+				__('A valid Payment object was not received.', 'event_espresso'),
183
+				__FILE__,
184
+				__FUNCTION__,
185
+				__LINE__
186
+			);
187
+			return false;
188
+		}
189
+		if (! $this->delete_registration_payments_and_update_registrations($payment)) {
190
+			return false;
191
+		}
192
+		if (! $payment->delete()) {
193
+			EE_Error::add_error(
194
+				__('The payment could not be deleted.', 'event_espresso'),
195
+				__FILE__,
196
+				__FUNCTION__,
197
+				__LINE__
198
+			);
199
+			return false;
200
+		}
201
+
202
+		$transaction = $payment->transaction();
203
+		$TXN_status = $transaction->status_ID();
204
+		if (
205
+			$TXN_status === EEM_Transaction::abandoned_status_code
206
+			|| $TXN_status === EEM_Transaction::failed_status_code
207
+			|| $payment->amount() === 0
208
+		) {
209
+			EE_Error::add_success(__('The Payment was successfully deleted.', 'event_espresso'));
210
+			return true;
211
+		}
212
+
213
+
214
+		// if this fails, that just means that the transaction didn't get its status changed and/or updated.
215
+		// however the payment was still deleted.
216
+		if (! $this->calculate_total_payments_and_update_status($transaction)) {
217
+			EE_Error::add_attention(
218
+				__(
219
+					'It appears that the Payment was deleted but no change was recorded for the Transaction for an unknown reason. Please verify that all data for this Transaction looks correct..',
220
+					'event_espresso'
221
+				),
222
+				__FILE__,
223
+				__FUNCTION__,
224
+				__LINE__
225
+			);
226
+			return true;
227
+		}
228
+
229
+		EE_Error::add_success(
230
+			__(
231
+				'The Payment was successfully deleted, and the Transaction has been updated accordingly.',
232
+				'event_espresso'
233
+			)
234
+		);
235
+		return true;
236
+	}
237
+
238
+
239
+	/**
240
+	 * delete_registration_payments_and_update_registrations
241
+	 *
242
+	 * removes all registration payment records associated with a payment
243
+	 * and subtracts their amounts from the corresponding registrations REG_paid field
244
+	 *
245
+	 * @param EE_Payment $payment
246
+	 * @param array      $reg_payment_query_params
247
+	 * @return bool
248
+	 * @throws \EE_Error
249
+	 */
250
+	public function delete_registration_payments_and_update_registrations(
251
+		EE_Payment $payment,
252
+		$reg_payment_query_params = array()
253
+	) {
254
+		$save_payment = false;
255
+		$reg_payment_query_params = ! empty($reg_payment_query_params) ? $reg_payment_query_params
256
+			: array(array('PAY_ID' => $payment->ID()));
257
+		$registration_payments = EEM_Registration_Payment::instance()->get_all($reg_payment_query_params);
258
+		if (! empty($registration_payments)) {
259
+			foreach ($registration_payments as $registration_payment) {
260
+				if ($registration_payment instanceof EE_Registration_Payment) {
261
+					$amount_paid = $registration_payment->amount();
262
+					$registration = $registration_payment->registration();
263
+					if ($registration instanceof EE_Registration) {
264
+						$registration->set_paid($registration->paid() - $amount_paid);
265
+						if ($registration->save() !== false) {
266
+							$registration_payment->delete_permanently();
267
+							$save_payment = true;
268
+						}
269
+					} else {
270
+						EE_Error::add_error(
271
+							sprintf(
272
+								__(
273
+									'An invalid Registration object was associated with Registration Payment ID# %1$d.',
274
+									'event_espresso'
275
+								),
276
+								$registration_payment->ID()
277
+							),
278
+							__FILE__,
279
+							__FUNCTION__,
280
+							__LINE__
281
+						);
282
+						return false;
283
+					}
284
+				} else {
285
+					EE_Error::add_error(
286
+						sprintf(
287
+							__(
288
+								'An invalid Registration Payment object was associated with payment ID# %1$d.',
289
+								'event_espresso'
290
+							),
291
+							$payment->ID()
292
+						),
293
+						__FILE__,
294
+						__FUNCTION__,
295
+						__LINE__
296
+					);
297
+					return false;
298
+				}
299
+			}
300
+		}
301
+		if ($save_payment) {
302
+			$payment->save();
303
+		}
304
+		return true;
305
+	}
306
+
307
+
308
+
309
+	/********************************** DEPRECATED METHODS **********************************/
310
+
311
+
312
+	/**
313
+	 * possibly toggles TXN status
314
+	 *
315
+	 * @deprecated 4.9.1
316
+	 * @param EE_Transaction $transaction
317
+	 * @param    boolean     $update_txn whether to save the TXN
318
+	 * @return    boolean        whether the TXN was saved
319
+	 * @throws \EE_Error
320
+	 */
321
+	public function update_transaction_status_based_on_total_paid(EE_Transaction $transaction, $update_txn = true)
322
+	{
323
+		EE_Error::doing_it_wrong(
324
+			__CLASS__ . '::' . __FUNCTION__,
325
+			sprintf(
326
+				__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
327
+				'EE_Transaction::update_status_based_on_total_paid()'
328
+			),
329
+			'4.9.1',
330
+			'5.0.0'
331
+		);
332
+		// verify transaction
333
+		if (! $transaction instanceof EE_Transaction) {
334
+			EE_Error::add_error(
335
+				__('Please provide a valid EE_Transaction object.', 'event_espresso'),
336
+				__FILE__,
337
+				__FUNCTION__,
338
+				__LINE__
339
+			);
340
+			return false;
341
+		}
342
+		// set transaction status based on comparison of TXN_paid vs TXN_total
343
+		return $transaction->update_status_based_on_total_paid($update_txn);
344
+	}
345
+
346
+
347
+	/**
348
+	 * @deprecated 4.9.12
349
+	 * @return string
350
+	 */
351
+	public function old_txn_status()
352
+	{
353
+		EE_Error::doing_it_wrong(
354
+			__METHOD__,
355
+			esc_html__(
356
+				'This logic has been moved into \EE_Transaction::old_txn_status(), please use that method instead.',
357
+				'event_espresso'
358
+			),
359
+			'4.9.12'
360
+		);
361
+		return $this->_old_txn_status;
362
+	}
363
+
364
+
365
+	/**
366
+	 * @deprecated 4.9.12
367
+	 * @param string $old_txn_status
368
+	 */
369
+	public function set_old_txn_status($old_txn_status)
370
+	{
371
+		EE_Error::doing_it_wrong(
372
+			__METHOD__,
373
+			esc_html__(
374
+				'This logic has been moved into \EE_Transaction::set_old_txn_status(), please use that method instead.',
375
+				'event_espresso'
376
+			),
377
+			'4.9.12'
378
+		);
379
+		// only set the first time
380
+		if ($this->_old_txn_status === null) {
381
+			$this->_old_txn_status = $old_txn_status;
382
+		}
383
+	}
384
+
385
+
386
+	/**
387
+	 * @deprecated 4.9.12
388
+	 * @return string
389
+	 */
390
+	public function new_txn_status()
391
+	{
392
+		EE_Error::doing_it_wrong(
393
+			__METHOD__,
394
+			esc_html__(
395
+				'This logic has been removed. Please just use \EE_Transaction::status_ID() instead.',
396
+				'event_espresso'
397
+			),
398
+			'4.9.12'
399
+		);
400
+		return $this->_new_txn_status;
401
+	}
402
+
403
+
404
+	/**
405
+	 * @deprecated 4.9.12
406
+	 * @param string $new_txn_status
407
+	 */
408
+	public function set_new_txn_status($new_txn_status)
409
+	{
410
+		EE_Error::doing_it_wrong(
411
+			__METHOD__,
412
+			esc_html__(
413
+				'This logic has been removed. Please just use \EE_Transaction::set_status() instead.',
414
+				'event_espresso'
415
+			),
416
+			'4.9.12'
417
+		);
418
+		$this->_new_txn_status = $new_txn_status;
419
+	}
420
+
421
+
422
+	/**
423
+	 * @deprecated 4.9.12
424
+	 * @return bool
425
+	 */
426
+	public function txn_status_updated()
427
+	{
428
+		EE_Error::doing_it_wrong(
429
+			__METHOD__,
430
+			esc_html__(
431
+				'This logic has been moved into \EE_Transaction::txn_status_updated(), please use that method instead.',
432
+				'event_espresso'
433
+			),
434
+			'4.9.12'
435
+		);
436
+		return $this->_new_txn_status !== $this->_old_txn_status && $this->_old_txn_status !== null ? true : false;
437
+	}
438 438
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Import.class.php 3 patches
Doc Comments   +4 added lines, -8 removed lines patch added patch discarded remove patch
@@ -87,7 +87,6 @@  discard block
 block discarded – undo
87 87
      *
88 88
      * @param    string $title  - heading for the form
89 89
      * @param    string $intro  - additional text explaing what to do
90
-     * @param    string $page   - EE Admin page to direct form to - in the form "espresso_{pageslug}"
91 90
      * @param    string $action - EE Admin page route array "action" that form will direct to
92 91
      * @param    string $type   - type of file to import
93 92
      *                          @ return    string
@@ -130,7 +129,7 @@  discard block
 block discarded – undo
130 129
     /**
131 130
      * @Import Event Espresso data - some code "borrowed" from event espresso csv_import.php
132 131
      * @access public
133
-     * @return boolean success
132
+     * @return boolean|null success
134 133
      */
135 134
     public function import()
136 135
     {
@@ -304,9 +303,7 @@  discard block
 block discarded – undo
304 303
      * @access public
305 304
      * @param array $csv_data_array - the array containing the csv data produced from
306 305
      *                              EE_CSV::import_csv_to_model_data_array()
307
-     * @param array $fields_to_save - an array containing the csv column names as keys with the corresponding db table
308
-     *                              fields they will be saved to
309
-     * @return TRUE on success, FALSE on fail
306
+     * @return boolean on success, FALSE on fail
310 307
      * @throws \EE_Error
311 308
      */
312 309
     public function save_csv_data_array_to_db($csv_data_array, $model_name = false)
@@ -459,7 +456,7 @@  discard block
 block discarded – undo
459 456
      * to the newly-inserted real ID.
460 457
      *
461 458
      * @param type $csv_data_array
462
-     * @param type $export_from_site_a_to_b
459
+     * @param boolean $export_from_site_a_to_b
463 460
      * @param type $old_db_to_new_db_mapping
464 461
      * @return array updated $old_db_to_new_db_mapping
465 462
      */
@@ -626,7 +623,6 @@  discard block
 block discarded – undo
626 623
      * @param type     $id_in_csv
627 624
      * @param type     $model_object_data
628 625
      * @param EEM_Base $model
629
-     * @param type     $old_db_to_new_db_mapping
630 626
      * @return
631 627
      */
632 628
     protected function _decide_whether_to_insert_or_update_given_data_from_same_db(
@@ -758,7 +754,7 @@  discard block
 block discarded – undo
758 754
      * @param type   $object_id
759 755
      * @param string $model_name
760 756
      * @param array  $old_db_to_new_db_mapping
761
-     * @param type   $export_from_site_a_to_b
757
+     * @param boolean   $export_from_site_a_to_b
762 758
      * @return int
763 759
      */
764 760
     protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b)
Please login to merge, or discard this patch.
Spacing   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -135,7 +135,7 @@  discard block
 block discarded – undo
135 135
     public function import()
136 136
     {
137 137
 
138
-        require_once(EE_CLASSES . 'EE_CSV.class.php');
138
+        require_once(EE_CLASSES.'EE_CSV.class.php');
139 139
         $this->EE_CSV = EE_CSV::instance();
140 140
 
141 141
         if (isset($_REQUEST['import'])) {
@@ -179,18 +179,18 @@  discard block
 block discarded – undo
179 179
                         break;
180 180
                 }
181 181
 
182
-                if (! $error_msg) {
182
+                if ( ! $error_msg) {
183 183
                     $filename = $_FILES['file']['name'][0];
184 184
                     $file_ext = substr(strrchr($filename, '.'), 1);
185 185
                     $file_type = $_FILES['file']['type'][0];
186 186
                     $temp_file = $_FILES['file']['tmp_name'][0];
187
-                    $filesize = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB
187
+                    $filesize = $_FILES['file']['size'][0] / 1024; // convert from bytes to KB
188 188
 
189 189
                     if ($file_ext == 'csv') {
190
-                        $max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB
190
+                        $max_upload = $this->EE_CSV->get_max_upload_size(); // max upload size in KB
191 191
                         if ($filesize < $max_upload || true) {
192 192
                             $wp_upload_dir = str_replace(array('\\', '/'), '/', wp_upload_dir());
193
-                            $path_to_file = $wp_upload_dir['basedir'] . '/espresso/' . $filename;
193
+                            $path_to_file = $wp_upload_dir['basedir'].'/espresso/'.$filename;
194 194
 
195 195
                             if (move_uploaded_file($temp_file, $path_to_file)) {
196 196
                                 // convert csv to array
@@ -324,8 +324,8 @@  discard block
 block discarded – undo
324 324
         // begin looking through the $csv_data_array, expecting the toplevel key to be the model's name...
325 325
         $old_site_url = 'none-specified';
326 326
         // hanlde metadata
327
-        if (isset($csv_data_array[ EE_CSV::metadata_header ])) {
328
-            $csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]);
327
+        if (isset($csv_data_array[EE_CSV::metadata_header])) {
328
+            $csv_metadata = array_shift($csv_data_array[EE_CSV::metadata_header]);
329 329
             // ok so its metadata, dont try to save it to ehte db obviously...
330 330
             if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) {
331 331
                 EE_Error::add_attention(
@@ -350,14 +350,14 @@  discard block
 block discarded – undo
350 350
                     )
351 351
                 );
352 352
             };
353
-            unset($csv_data_array[ EE_CSV::metadata_header ]);
353
+            unset($csv_data_array[EE_CSV::metadata_header]);
354 354
         }
355 355
         /**
356 356
          * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and
357 357
          * the value will be the newly-inserted ID.
358 358
          * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option
359 359
          */
360
-        $old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), array());
360
+        $old_db_to_new_db_mapping = get_option('ee_id_mapping_from'.sanitize_title($old_site_url), array());
361 361
         if ($old_db_to_new_db_mapping) {
362 362
             EE_Error::add_attention(
363 363
                 sprintf(
@@ -377,7 +377,7 @@  discard block
 block discarded – undo
377 377
         );
378 378
 
379 379
         // save the mapping from old db to new db in case they try re-importing the same data from the same website again
380
-        update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping);
380
+        update_option('ee_id_mapping_from'.sanitize_title($old_site_url), $old_db_to_new_db_mapping);
381 381
 
382 382
         if ($this->_total_updates > 0) {
383 383
             EE_Error::add_success(
@@ -500,7 +500,7 @@  discard block
 block discarded – undo
500 500
                 // find the PK in the row of data (or a combined key if
501 501
                 // there is no primary key)
502 502
                 if ($model->has_primary_key_field()) {
503
-                    $id_in_csv = $model_object_data[ $model->primary_key_name() ];
503
+                    $id_in_csv = $model_object_data[$model->primary_key_name()];
504 504
                 } else {
505 505
                     $id_in_csv = $model->get_index_primary_key_string($model_object_data);
506 506
                 }
@@ -544,14 +544,14 @@  discard block
 block discarded – undo
544 544
                         $what_to_do = self::do_update;
545 545
                         // and if this model has a primary key, remember its mapping
546 546
                         if ($model->has_primary_key_field()) {
547
-                            $old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID();
548
-                            $model_object_data[ $model->primary_key_name() ] = $conflicting->ID();
547
+                            $old_db_to_new_db_mapping[$model_name][$id_in_csv] = $conflicting->ID();
548
+                            $model_object_data[$model->primary_key_name()] = $conflicting->ID();
549 549
                         } else {
550 550
                             // we want to update this conflicting item, instead of inserting a conflicting item
551 551
                             // so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields
552 552
                             // for the WHERE conditions in the update). At the time of this comment, there were no models like this
553 553
                             foreach ($model->get_combined_primary_key_fields() as $key_field) {
554
-                                $model_object_data[ $key_field->get_name() ] = $conflicting->get(
554
+                                $model_object_data[$key_field->get_name()] = $conflicting->get(
555 555
                                     $key_field->get_name()
556 556
                                 );
557 557
                             }
@@ -611,7 +611,7 @@  discard block
 block discarded – undo
611 611
         $model_name = $model->get_this_model_name();
612 612
         // if it's a site-to-site export-and-import, see if this modelobject's id
613 613
         // in the old data that we know of
614
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) {
614
+        if (isset($old_db_to_new_db_mapping[$model_name][$id_in_csv])) {
615 615
             return self::do_update;
616 616
         } else {
617 617
             return self::do_insert;
@@ -667,13 +667,13 @@  discard block
 block discarded – undo
667 667
         if (
668 668
             $model->has_primary_key_field() &&
669 669
             $model->get_primary_key_field()->is_auto_increment() &&
670
-            isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ]) &&
670
+            isset($old_db_to_new_db_mapping[$model->get_this_model_name()]) &&
671 671
             isset(
672
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $model_object_data[ $model->primary_key_name() ] ]
672
+                $old_db_to_new_db_mapping[$model->get_this_model_name()][$model_object_data[$model->primary_key_name()]]
673 673
             )
674 674
         ) {
675
-            $model_object_data[ $model->primary_key_name() ] = $old_db_to_new_db_mapping[ $model->get_this_model_name(
676
-            ) ][ $model_object_data[ $model->primary_key_name() ] ];
675
+            $model_object_data[$model->primary_key_name()] = $old_db_to_new_db_mapping[$model->get_this_model_name(
676
+            )][$model_object_data[$model->primary_key_name()]];
677 677
         }
678 678
 
679 679
         try {
@@ -689,10 +689,10 @@  discard block
 block discarded – undo
689 689
                 $found_a_mapping = false;
690 690
                 foreach ($models_pointed_to as $model_pointed_to_by_fk) {
691 691
                     if ($model_name_field) {
692
-                        $value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ];
692
+                        $value_of_model_name_field = $model_object_data[$model_name_field->get_name()];
693 693
                         if ($value_of_model_name_field == $model_pointed_to_by_fk) {
694
-                            $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
695
-                                $model_object_data[ $field_obj->get_name() ],
694
+                            $model_object_data[$field_obj->get_name()] = $this->_find_mapping_in(
695
+                                $model_object_data[$field_obj->get_name()],
696 696
                                 $model_pointed_to_by_fk,
697 697
                                 $old_db_to_new_db_mapping,
698 698
                                 $export_from_site_a_to_b
@@ -701,8 +701,8 @@  discard block
 block discarded – undo
701 701
                             break;
702 702
                         }
703 703
                     } else {
704
-                        $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
705
-                            $model_object_data[ $field_obj->get_name() ],
704
+                        $model_object_data[$field_obj->get_name()] = $this->_find_mapping_in(
705
+                            $model_object_data[$field_obj->get_name()],
706 706
                             $model_pointed_to_by_fk,
707 707
                             $old_db_to_new_db_mapping,
708 708
                             $export_from_site_a_to_b
@@ -767,8 +767,8 @@  discard block
 block discarded – undo
767 767
      */
768 768
     protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b)
769 769
     {
770
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) {
771
-            return $old_db_to_new_db_mapping[ $model_name ][ $object_id ];
770
+        if (isset($old_db_to_new_db_mapping[$model_name][$object_id])) {
771
+            return $old_db_to_new_db_mapping[$model_name][$object_id];
772 772
         } elseif ($object_id == '0' || $object_id == '') {
773 773
             // leave as-is
774 774
             return $object_id;
@@ -776,7 +776,7 @@  discard block
 block discarded – undo
776 776
             // we couldn't find a mapping for this, and it's from a different site,
777 777
             // so blank it out
778 778
             return null;
779
-        } elseif (! $export_from_site_a_to_b) {
779
+        } elseif ( ! $export_from_site_a_to_b) {
780 780
             // we coudln't find a mapping for this, but it's from thsi DB anyway
781 781
             // so let's just leave it as-is
782 782
             return $object_id;
@@ -796,8 +796,8 @@  discard block
 block discarded – undo
796 796
         // remove the primary key, if there is one (we don't want it for inserts OR updates)
797 797
         // we'll put it back in if we need it
798 798
         if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) {
799
-            $effective_id = $model_object_data[ $model->primary_key_name() ];
800
-            unset($model_object_data[ $model->primary_key_name() ]);
799
+            $effective_id = $model_object_data[$model->primary_key_name()];
800
+            unset($model_object_data[$model->primary_key_name()]);
801 801
         } else {
802 802
             $effective_id = $model->get_index_primary_key_string($model_object_data);
803 803
         }
@@ -805,7 +805,7 @@  discard block
 block discarded – undo
805 805
         try {
806 806
             $new_id = $model->insert($model_object_data);
807 807
             if ($new_id) {
808
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id;
808
+                $old_db_to_new_db_mapping[$model->get_this_model_name()][$id_in_csv] = $new_id;
809 809
                 $this->_total_inserts++;
810 810
                 EE_Error::add_success(
811 811
                     sprintf(
@@ -819,7 +819,7 @@  discard block
 block discarded – undo
819 819
                 $this->_total_insert_errors++;
820 820
                 // put the ID used back in there for the error message
821 821
                 if ($model->has_primary_key_field()) {
822
-                    $model_object_data[ $model->primary_key_name() ] = $effective_id;
822
+                    $model_object_data[$model->primary_key_name()] = $effective_id;
823 823
                 }
824 824
                 EE_Error::add_error(
825 825
                     sprintf(
@@ -835,7 +835,7 @@  discard block
 block discarded – undo
835 835
         } catch (EE_Error $e) {
836 836
             $this->_total_insert_errors++;
837 837
             if ($model->has_primary_key_field()) {
838
-                $model_object_data[ $model->primary_key_name() ] = $effective_id;
838
+                $model_object_data[$model->primary_key_name()] = $effective_id;
839 839
             }
840 840
             EE_Error::add_error(
841 841
                 sprintf(
@@ -868,17 +868,17 @@  discard block
 block discarded – undo
868 868
             // one for performing an update, one for everthing else
869 869
             $model_object_data_for_update = $model_object_data;
870 870
             if ($model->has_primary_key_field()) {
871
-                $conditions = array($model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]);
871
+                $conditions = array($model->primary_key_name() => $model_object_data[$model->primary_key_name()]);
872 872
                 // remove the primary key because we shouldn't use it for updating
873
-                unset($model_object_data_for_update[ $model->primary_key_name() ]);
873
+                unset($model_object_data_for_update[$model->primary_key_name()]);
874 874
             } elseif ($model->get_combined_primary_key_fields() > 1) {
875 875
                 $conditions = array();
876 876
                 foreach ($model->get_combined_primary_key_fields() as $key_field) {
877
-                    $conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ];
877
+                    $conditions[$key_field->get_name()] = $model_object_data[$key_field->get_name()];
878 878
                 }
879 879
             } else {
880 880
                 $model->primary_key_name(
881
-                );// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
881
+                ); // this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
882 882
             }
883 883
 
884 884
             $success = $model->update($model_object_data_for_update, array($conditions));
@@ -896,15 +896,15 @@  discard block
 block discarded – undo
896 896
                 // we would have last-minute decided to update. So we'd like to know what we updated
897 897
                 // and so we record what record ended up being updated using the mapping
898 898
                 if ($model->has_primary_key_field()) {
899
-                    $new_key_for_mapping = $model_object_data[ $model->primary_key_name() ];
899
+                    $new_key_for_mapping = $model_object_data[$model->primary_key_name()];
900 900
                 } else {
901 901
                     // no primary key just a combined key
902 902
                     $new_key_for_mapping = $model->get_index_primary_key_string($model_object_data);
903 903
                 }
904
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping;
904
+                $old_db_to_new_db_mapping[$model->get_this_model_name()][$id_in_csv] = $new_key_for_mapping;
905 905
             } else {
906 906
                 $matched_items = $model->get_all(array($conditions));
907
-                if (! $matched_items) {
907
+                if ( ! $matched_items) {
908 908
                     // no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck?
909 909
                     $this->_total_update_errors++;
910 910
                     EE_Error::add_error(
@@ -943,7 +943,7 @@  discard block
 block discarded – undo
943 943
                 implode(",", $model_object_data),
944 944
                 $e->getMessage()
945 945
             );
946
-            $debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString();
946
+            $debug_message = $basic_message.' Stack trace: '.$e->getTraceAsString();
947 947
             EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__);
948 948
         }
949 949
         return $old_db_to_new_db_mapping;
Please login to merge, or discard this patch.
Indentation   +954 added lines, -954 removed lines patch added patch discarded remove patch
@@ -14,91 +14,91 @@  discard block
 block discarded – undo
14 14
 class EE_Import implements ResettableInterface
15 15
 {
16 16
 
17
-    const do_insert = 'insert';
18
-    const do_update = 'update';
19
-    const do_nothing = 'nothing';
20
-
21
-
22
-    // instance of the EE_Import object
23
-    private static $_instance;
24
-
25
-    private static $_csv_array = array();
26
-
27
-    /**
28
-     *
29
-     * @var array of model names
30
-     */
31
-    private static $_model_list = array();
32
-
33
-    private static $_columns_to_save = array();
34
-
35
-    protected $_total_inserts = 0;
36
-    protected $_total_updates = 0;
37
-    protected $_total_insert_errors = 0;
38
-    protected $_total_update_errors = 0;
39
-
40
-
41
-    /**
42
-     *        private constructor to prevent direct creation
43
-     *
44
-     * @Constructor
45
-     * @access private
46
-     * @return void
47
-     */
48
-    private function __construct()
49
-    {
50
-        $this->_total_inserts = 0;
51
-        $this->_total_updates = 0;
52
-        $this->_total_insert_errors = 0;
53
-        $this->_total_update_errors = 0;
54
-    }
55
-
56
-
57
-    /**
58
-     *    @ singleton method used to instantiate class object
59
-     *    @ access public
60
-     *
61
-     * @return EE_Import
62
-     */
63
-    public static function instance()
64
-    {
65
-        // check if class object is instantiated
66
-        if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Import)) {
67
-            self::$_instance = new self();
68
-        }
69
-        return self::$_instance;
70
-    }
71
-
72
-    /**
73
-     * Resets the importer
74
-     *
75
-     * @return EE_Import
76
-     */
77
-    public static function reset()
78
-    {
79
-        self::$_instance = null;
80
-        return self::instance();
81
-    }
82
-
83
-
84
-    /**
85
-     *    @ generates HTML for a file upload input and form
86
-     *    @ access    public
87
-     *
88
-     * @param    string $title  - heading for the form
89
-     * @param    string $intro  - additional text explaing what to do
90
-     * @param    string $page   - EE Admin page to direct form to - in the form "espresso_{pageslug}"
91
-     * @param    string $action - EE Admin page route array "action" that form will direct to
92
-     * @param    string $type   - type of file to import
93
-     *                          @ return    string
94
-     */
95
-    public function upload_form($title, $intro, $form_url, $action, $type)
96
-    {
97
-
98
-        $form_url = EE_Admin_Page::add_query_args_and_nonce(array('action' => $action), $form_url);
99
-
100
-        ob_start();
101
-        ?>
17
+	const do_insert = 'insert';
18
+	const do_update = 'update';
19
+	const do_nothing = 'nothing';
20
+
21
+
22
+	// instance of the EE_Import object
23
+	private static $_instance;
24
+
25
+	private static $_csv_array = array();
26
+
27
+	/**
28
+	 *
29
+	 * @var array of model names
30
+	 */
31
+	private static $_model_list = array();
32
+
33
+	private static $_columns_to_save = array();
34
+
35
+	protected $_total_inserts = 0;
36
+	protected $_total_updates = 0;
37
+	protected $_total_insert_errors = 0;
38
+	protected $_total_update_errors = 0;
39
+
40
+
41
+	/**
42
+	 *        private constructor to prevent direct creation
43
+	 *
44
+	 * @Constructor
45
+	 * @access private
46
+	 * @return void
47
+	 */
48
+	private function __construct()
49
+	{
50
+		$this->_total_inserts = 0;
51
+		$this->_total_updates = 0;
52
+		$this->_total_insert_errors = 0;
53
+		$this->_total_update_errors = 0;
54
+	}
55
+
56
+
57
+	/**
58
+	 *    @ singleton method used to instantiate class object
59
+	 *    @ access public
60
+	 *
61
+	 * @return EE_Import
62
+	 */
63
+	public static function instance()
64
+	{
65
+		// check if class object is instantiated
66
+		if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Import)) {
67
+			self::$_instance = new self();
68
+		}
69
+		return self::$_instance;
70
+	}
71
+
72
+	/**
73
+	 * Resets the importer
74
+	 *
75
+	 * @return EE_Import
76
+	 */
77
+	public static function reset()
78
+	{
79
+		self::$_instance = null;
80
+		return self::instance();
81
+	}
82
+
83
+
84
+	/**
85
+	 *    @ generates HTML for a file upload input and form
86
+	 *    @ access    public
87
+	 *
88
+	 * @param    string $title  - heading for the form
89
+	 * @param    string $intro  - additional text explaing what to do
90
+	 * @param    string $page   - EE Admin page to direct form to - in the form "espresso_{pageslug}"
91
+	 * @param    string $action - EE Admin page route array "action" that form will direct to
92
+	 * @param    string $type   - type of file to import
93
+	 *                          @ return    string
94
+	 */
95
+	public function upload_form($title, $intro, $form_url, $action, $type)
96
+	{
97
+
98
+		$form_url = EE_Admin_Page::add_query_args_and_nonce(array('action' => $action), $form_url);
99
+
100
+		ob_start();
101
+		?>
102 102
         <div class="ee-upload-form-dv">
103 103
             <h3><?php echo $title; ?></h3>
104 104
             <p><?php echo $intro; ?></p>
@@ -114,878 +114,878 @@  discard block
 block discarded – undo
114 114
                 <b><?php _e('Attention', 'event_espresso'); ?></b><br/>
115 115
                 <?php echo sprintf(__('Accepts .%s file types only.', 'event_espresso'), $type); ?>
116 116
                 <?php echo __(
117
-                    'Please only import CSV files exported from Event Espresso, or compatible 3rd-party software.',
118
-                    'event_espresso'
119
-                ); ?>
117
+					'Please only import CSV files exported from Event Espresso, or compatible 3rd-party software.',
118
+					'event_espresso'
119
+				); ?>
120 120
             </p>
121 121
 
122 122
         </div>
123 123
 
124 124
         <?php
125
-        $uploader = ob_get_clean();
126
-        return $uploader;
127
-    }
128
-
129
-
130
-    /**
131
-     * @Import Event Espresso data - some code "borrowed" from event espresso csv_import.php
132
-     * @access public
133
-     * @return boolean success
134
-     */
135
-    public function import()
136
-    {
137
-
138
-        require_once(EE_CLASSES . 'EE_CSV.class.php');
139
-        $this->EE_CSV = EE_CSV::instance();
140
-
141
-        if (isset($_REQUEST['import'])) {
142
-            if (isset($_POST['csv_submitted'])) {
143
-                switch ($_FILES['file']['error'][0]) {
144
-                    case UPLOAD_ERR_OK:
145
-                        $error_msg = false;
146
-                        break;
147
-                    case UPLOAD_ERR_INI_SIZE:
148
-                        $error_msg = __(
149
-                            "'The uploaded file exceeds the upload_max_filesize directive in php.ini.'",
150
-                            "event_espresso"
151
-                        );
152
-                        break;
153
-                    case UPLOAD_ERR_FORM_SIZE:
154
-                        $error_msg = __(
155
-                            'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
156
-                            "event_espresso"
157
-                        );
158
-                        break;
159
-                    case UPLOAD_ERR_PARTIAL:
160
-                        $error_msg = __('The uploaded file was only partially uploaded.', "event_espresso");
161
-                        break;
162
-                    case UPLOAD_ERR_NO_FILE:
163
-                        $error_msg = __('No file was uploaded.', "event_espresso");
164
-                        break;
165
-                    case UPLOAD_ERR_NO_TMP_DIR:
166
-                        $error_msg = __('Missing a temporary folder.', "event_espresso");
167
-                        break;
168
-                    case UPLOAD_ERR_CANT_WRITE:
169
-                        $error_msg = __('Failed to write file to disk.', "event_espresso");
170
-                        break;
171
-                    case UPLOAD_ERR_EXTENSION:
172
-                        $error_msg = __('File upload stopped by extension.', "event_espresso");
173
-                        break;
174
-                    default:
175
-                        $error_msg = __(
176
-                            'An unknown error occurred and the file could not be uploaded',
177
-                            "event_espresso"
178
-                        );
179
-                        break;
180
-                }
181
-
182
-                if (! $error_msg) {
183
-                    $filename = $_FILES['file']['name'][0];
184
-                    $file_ext = substr(strrchr($filename, '.'), 1);
185
-                    $file_type = $_FILES['file']['type'][0];
186
-                    $temp_file = $_FILES['file']['tmp_name'][0];
187
-                    $filesize = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB
188
-
189
-                    if ($file_ext == 'csv') {
190
-                        $max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB
191
-                        if ($filesize < $max_upload || true) {
192
-                            $wp_upload_dir = str_replace(array('\\', '/'), '/', wp_upload_dir());
193
-                            $path_to_file = $wp_upload_dir['basedir'] . '/espresso/' . $filename;
194
-
195
-                            if (move_uploaded_file($temp_file, $path_to_file)) {
196
-                                // convert csv to array
197
-                                $this->csv_array = $this->EE_CSV->import_csv_to_model_data_array($path_to_file);
198
-
199
-                                // was data successfully stored in an array?
200
-                                if (is_array($this->csv_array)) {
201
-                                    $import_what = str_replace('csv_import_', '', $_REQUEST['action']);
202
-                                    $import_what = str_replace('_', ' ', ucwords($import_what));
203
-                                    $processed_data = $this->csv_array;
204
-                                    $this->columns_to_save = false;
205
-
206
-                                    // if any imports require funcky processing, we'll catch them in the switch
207
-                                    switch ($_REQUEST['action']) {
208
-                                        case "import_events":
209
-                                        case "event_list":
210
-                                            $import_what = 'Event Details';
211
-                                            break;
212
-
213
-                                        case 'groupon_import_csv':
214
-                                            $import_what = 'Groupon Codes';
215
-                                            $processed_data = $this->process_groupon_codes();
216
-                                            break;
217
-                                    }
218
-                                    // save processed codes to db
219
-                                    if ($this->save_csv_data_array_to_db($processed_data, $this->columns_to_save)) {
220
-                                        return true;
221
-                                    }
222
-                                } else {
223
-                                    // no array? must be an error
224
-                                    EE_Error::add_error(
225
-                                        sprintf(__("No file seems to have been uploaded", "event_espresso")),
226
-                                        __FILE__,
227
-                                        __FUNCTION__,
228
-                                        __LINE__
229
-                                    );
230
-                                    return false;
231
-                                }
232
-                            } else {
233
-                                EE_Error::add_error(
234
-                                    sprintf(__("%s was not successfully uploaded", "event_espresso"), $filename),
235
-                                    __FILE__,
236
-                                    __FUNCTION__,
237
-                                    __LINE__
238
-                                );
239
-                                return false;
240
-                            }
241
-                        } else {
242
-                            EE_Error::add_error(
243
-                                sprintf(
244
-                                    __(
245
-                                        "%s was too large of a file and could not be uploaded. The max filesize is %s' KB.",
246
-                                        "event_espresso"
247
-                                    ),
248
-                                    $filename,
249
-                                    $max_upload
250
-                                ),
251
-                                __FILE__,
252
-                                __FUNCTION__,
253
-                                __LINE__
254
-                            );
255
-                            return false;
256
-                        }
257
-                    } else {
258
-                        EE_Error::add_error(
259
-                            sprintf(__("%s  had an invalid file extension, not uploaded", "event_espresso"), $filename),
260
-                            __FILE__,
261
-                            __FUNCTION__,
262
-                            __LINE__
263
-                        );
264
-                        return false;
265
-                    }
266
-                } else {
267
-                    EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
268
-                    return false;
269
-                }
270
-            }
271
-        }
272
-        return;
273
-    }
274
-
275
-
276
-    /**
277
-     *    Given an array of data (usually from a CSV import) attempts to save that data to the db.
278
-     *    If $model_name ISN'T provided, assumes that this is a 3d array, with toplevel keys being model names,
279
-     *    next level being numeric indexes adn each value representing a model object, and the last layer down
280
-     *    being keys of model fields and their proposed values.
281
-     *    If $model_name IS provided, assumes a 2d array of the bottom two layers previously mentioned.
282
-     *    If the CSV data says (in the metadata row) that it's from the SAME database,
283
-     *    we treat the IDs in the CSV as the normal IDs, and try to update those records. However, if those
284
-     *    IDs DON'T exist in the database, they're treated as temporary IDs,
285
-     *    which can used elsewhere to refer to the same object. Once an item
286
-     *    with a temporary ID gets inserted, we record its mapping from temporary
287
-     *    ID to real ID, and use the real ID in place of the temporary ID
288
-     *    when that temporary ID was used as a foreign key.
289
-     *    If the CSV data says (in the metadata again) that it's from a DIFFERENT database,
290
-     *    we treat all the IDs in the CSV as temporary ID- eg, if the CSV specifies an event with
291
-     *    ID 1, and the database already has an event with ID 1, we assume that's just a coincidence,
292
-     *    and insert a new event, and map it's temporary ID of 1 over to its new real ID.
293
-     *    An important exception are non-auto-increment primary keys. If one entry in the
294
-     *    CSV file has the same ID as one in the DB, we assume they are meant to be
295
-     *    the same item, and instead update the item in the DB with that same ID.
296
-     *    Also note, we remember the mappings permanently. So the 2nd, 3rd, and 10000th
297
-     *    time you import a CSV from a different site, we remember their mappings, and
298
-     * will try to update the item in the DB instead of inserting another item (eg
299
-     * if we previously imported an event with temporary ID 1, and then it got a
300
-     * real ID of 123, we remember that. So the next time we import an event with
301
-     * temporary ID, from the same site, we know that it's real ID is 123, and will
302
-     * update that event, instead of adding a new event).
303
-     *
304
-     * @access public
305
-     * @param array $csv_data_array - the array containing the csv data produced from
306
-     *                              EE_CSV::import_csv_to_model_data_array()
307
-     * @param array $fields_to_save - an array containing the csv column names as keys with the corresponding db table
308
-     *                              fields they will be saved to
309
-     * @return TRUE on success, FALSE on fail
310
-     * @throws \EE_Error
311
-     */
312
-    public function save_csv_data_array_to_db($csv_data_array, $model_name = false)
313
-    {
314
-        $success = false;
315
-        $error = false;
316
-        // whther to treat this import as if it's data froma different database or not
317
-        // ie, if it IS from a different database, ignore foreign keys whihf
318
-        $export_from_site_a_to_b = true;
319
-        // first level of array is not table information but a table name was passed to the function
320
-        // array is only two levels deep, so let's fix that by adding a level, else the next steps will fail
321
-        if ($model_name) {
322
-            $csv_data_array = array($csv_data_array);
323
-        }
324
-        // begin looking through the $csv_data_array, expecting the toplevel key to be the model's name...
325
-        $old_site_url = 'none-specified';
326
-        // hanlde metadata
327
-        if (isset($csv_data_array[ EE_CSV::metadata_header ])) {
328
-            $csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]);
329
-            // ok so its metadata, dont try to save it to ehte db obviously...
330
-            if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) {
331
-                EE_Error::add_attention(
332
-                    sprintf(
333
-                        __(
334
-                            "CSV Data appears to be from the same database, so attempting to update data",
335
-                            "event_espresso"
336
-                        )
337
-                    )
338
-                );
339
-                $export_from_site_a_to_b = false;
340
-            } else {
341
-                $old_site_url = isset($csv_metadata['site_url']) ? $csv_metadata['site_url'] : $old_site_url;
342
-                EE_Error::add_attention(
343
-                    sprintf(
344
-                        __(
345
-                            "CSV Data appears to be from a different database (%s instead of %s), so we assume IDs in the CSV data DO NOT correspond to IDs in this database",
346
-                            "event_espresso"
347
-                        ),
348
-                        $old_site_url,
349
-                        site_url()
350
-                    )
351
-                );
352
-            };
353
-            unset($csv_data_array[ EE_CSV::metadata_header ]);
354
-        }
355
-        /**
356
-         * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and
357
-         * the value will be the newly-inserted ID.
358
-         * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option
359
-         */
360
-        $old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), array());
361
-        if ($old_db_to_new_db_mapping) {
362
-            EE_Error::add_attention(
363
-                sprintf(
364
-                    __(
365
-                        "We noticed you have imported data via CSV from %s before. Because of this, IDs in your CSV have been mapped to their new IDs in %s",
366
-                        "event_espresso"
367
-                    ),
368
-                    $old_site_url,
369
-                    site_url()
370
-                )
371
-            );
372
-        }
373
-        $old_db_to_new_db_mapping = $this->save_data_rows_to_db(
374
-            $csv_data_array,
375
-            $export_from_site_a_to_b,
376
-            $old_db_to_new_db_mapping
377
-        );
378
-
379
-        // save the mapping from old db to new db in case they try re-importing the same data from the same website again
380
-        update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping);
381
-
382
-        if ($this->_total_updates > 0) {
383
-            EE_Error::add_success(
384
-                sprintf(
385
-                    __("%s existing records in the database were updated.", "event_espresso"),
386
-                    $this->_total_updates
387
-                )
388
-            );
389
-            $success = true;
390
-        }
391
-        if ($this->_total_inserts > 0) {
392
-            EE_Error::add_success(
393
-                sprintf(__("%s new records were added to the database.", "event_espresso"), $this->_total_inserts)
394
-            );
395
-            $success = true;
396
-        }
397
-
398
-        if ($this->_total_update_errors > 0) {
399
-            EE_Error::add_error(
400
-                sprintf(
401
-                    __(
402
-                        "'One or more errors occurred, and a total of %s existing records in the database were <strong>not</strong> updated.'",
403
-                        "event_espresso"
404
-                    ),
405
-                    $this->_total_update_errors
406
-                ),
407
-                __FILE__,
408
-                __FUNCTION__,
409
-                __LINE__
410
-            );
411
-            $error = true;
412
-        }
413
-        if ($this->_total_insert_errors > 0) {
414
-            EE_Error::add_error(
415
-                sprintf(
416
-                    __(
417
-                        "One or more errors occurred, and a total of %s new records were <strong>not</strong> added to the database.'",
418
-                        "event_espresso"
419
-                    ),
420
-                    $this->_total_insert_errors
421
-                ),
422
-                __FILE__,
423
-                __FUNCTION__,
424
-                __LINE__
425
-            );
426
-            $error = true;
427
-        }
428
-
429
-        // lastly, we need to update the datetime and ticket sold amounts
430
-        // as those may have been affected by this
431
-        EEM_Ticket::instance()->update_tickets_sold(EEM_Ticket::instance()->get_all());
432
-
433
-        // if there was at least one success and absolutely no errors
434
-        if ($success && ! $error) {
435
-            return true;
436
-        } else {
437
-            return false;
438
-        }
439
-    }
440
-
441
-
442
-    /**
443
-     * Processes the array of data, given the knowledge that it's from the same database or a different one,
444
-     * and the mapping from temporary IDs to real IDs.
445
-     * If the data is from a different database, we treat the primary keys and their corresponding
446
-     * foreign keys as "temp Ids", basically identifiers that get mapped to real primary keys
447
-     * in the real target database. As items are inserted, their temporary primary keys
448
-     * are mapped to the real IDs in the target database. Also, before doing any update or
449
-     * insert, we replace all the temp ID which are foreign keys with their mapped real IDs.
450
-     * An exception: string primary keys are treated as real IDs, or else we'd need to
451
-     * dynamically generate new string primary keys which would be very awkard for the country table etc.
452
-     * Also, models with no primary key are strange too. We combine use their primar key INDEX (a
453
-     * combination of fields) to create a unique string identifying the row and store
454
-     * those in the mapping.
455
-     *
456
-     * If the data is from the same database, we usually treat primary keys as real IDs.
457
-     * An exception is if there is nothing in the database for that ID. If that's the case,
458
-     * we need to insert a new row for that ID, and then map from the non-existent ID
459
-     * to the newly-inserted real ID.
460
-     *
461
-     * @param type $csv_data_array
462
-     * @param type $export_from_site_a_to_b
463
-     * @param type $old_db_to_new_db_mapping
464
-     * @return array updated $old_db_to_new_db_mapping
465
-     */
466
-    public function save_data_rows_to_db($csv_data_array, $export_from_site_a_to_b, $old_db_to_new_db_mapping)
467
-    {
468
-        foreach ($csv_data_array as $model_name_in_csv_data => $model_data_from_import) {
469
-            // now check that assumption was correct. If
470
-            if (EE_Registry::instance()->is_model_name($model_name_in_csv_data)) {
471
-                $model_name = $model_name_in_csv_data;
472
-            } else {
473
-                // no table info in the array and no table name passed to the function?? FAIL
474
-                EE_Error::add_error(
475
-                    __(
476
-                        'No table information was specified and/or found, therefore the import could not be completed',
477
-                        'event_espresso'
478
-                    ),
479
-                    __FILE__,
480
-                    __FUNCTION__,
481
-                    __LINE__
482
-                );
483
-                return false;
484
-            }
485
-            /* @var $model EEM_Base */
486
-            $model = EE_Registry::instance()->load_model($model_name);
487
-
488
-            // so without further ado, scanning all the data provided for primary keys and their inital values
489
-            foreach ($model_data_from_import as $model_object_data) {
490
-                // before we do ANYTHING, make sure the csv row wasn't just completely blank
491
-                $row_is_completely_empty = true;
492
-                foreach ($model_object_data as $field) {
493
-                    if ($field) {
494
-                        $row_is_completely_empty = false;
495
-                    }
496
-                }
497
-                if ($row_is_completely_empty) {
498
-                    continue;
499
-                }
500
-                // find the PK in the row of data (or a combined key if
501
-                // there is no primary key)
502
-                if ($model->has_primary_key_field()) {
503
-                    $id_in_csv = $model_object_data[ $model->primary_key_name() ];
504
-                } else {
505
-                    $id_in_csv = $model->get_index_primary_key_string($model_object_data);
506
-                }
507
-
508
-
509
-                $model_object_data = $this->_replace_temp_ids_with_mappings(
510
-                    $model_object_data,
511
-                    $model,
512
-                    $old_db_to_new_db_mapping,
513
-                    $export_from_site_a_to_b
514
-                );
515
-                // now we need to decide if we're going to add a new model object given the $model_object_data,
516
-                // or just update.
517
-                if ($export_from_site_a_to_b) {
518
-                    $what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_other_db(
519
-                        $id_in_csv,
520
-                        $model_object_data,
521
-                        $model,
522
-                        $old_db_to_new_db_mapping
523
-                    );
524
-                } else {// this is just a re-import
525
-                    $what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_same_db(
526
-                        $id_in_csv,
527
-                        $model_object_data,
528
-                        $model,
529
-                        $old_db_to_new_db_mapping
530
-                    );
531
-                }
532
-                if ($what_to_do == self::do_nothing) {
533
-                    continue;
534
-                }
535
-
536
-                // double-check we actually want to insert, if that's what we're planning
537
-                // based on whether this item would be unique in the DB or not
538
-                if ($what_to_do == self::do_insert) {
539
-                    // we're supposed to be inserting. But wait, will this thing
540
-                    // be acceptable if inserted?
541
-                    $conflicting = $model->get_one_conflicting($model_object_data, false);
542
-                    if ($conflicting) {
543
-                        // ok, this item would conflict if inserted. Just update the item that it conflicts with.
544
-                        $what_to_do = self::do_update;
545
-                        // and if this model has a primary key, remember its mapping
546
-                        if ($model->has_primary_key_field()) {
547
-                            $old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID();
548
-                            $model_object_data[ $model->primary_key_name() ] = $conflicting->ID();
549
-                        } else {
550
-                            // we want to update this conflicting item, instead of inserting a conflicting item
551
-                            // so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields
552
-                            // for the WHERE conditions in the update). At the time of this comment, there were no models like this
553
-                            foreach ($model->get_combined_primary_key_fields() as $key_field) {
554
-                                $model_object_data[ $key_field->get_name() ] = $conflicting->get(
555
-                                    $key_field->get_name()
556
-                                );
557
-                            }
558
-                        }
559
-                    }
560
-                }
561
-                if ($what_to_do == self::do_insert) {
562
-                    $old_db_to_new_db_mapping = $this->_insert_from_data_array(
563
-                        $id_in_csv,
564
-                        $model_object_data,
565
-                        $model,
566
-                        $old_db_to_new_db_mapping
567
-                    );
568
-                } elseif ($what_to_do == self::do_update) {
569
-                    $old_db_to_new_db_mapping = $this->_update_from_data_array(
570
-                        $id_in_csv,
571
-                        $model_object_data,
572
-                        $model,
573
-                        $old_db_to_new_db_mapping
574
-                    );
575
-                } else {
576
-                    throw new EE_Error(
577
-                        sprintf(
578
-                            __(
579
-                                'Programming error. We shoudl be inserting or updating, but instead we are being told to "%s", whifh is invalid',
580
-                                'event_espresso'
581
-                            ),
582
-                            $what_to_do
583
-                        )
584
-                    );
585
-                }
586
-            }
587
-        }
588
-        return $old_db_to_new_db_mapping;
589
-    }
590
-
591
-
592
-    /**
593
-     * Decides whether or not to insert, given that this data is from another database.
594
-     * So, if the primary key of this $model_object_data already exists in the database,
595
-     * it's just a coincidence and we should still insert. The only time we should
596
-     * update is when we know what it maps to, or there's something that would
597
-     * conflict (and we should instead just update that conflicting thing)
598
-     *
599
-     * @param string   $id_in_csv
600
-     * @param array    $model_object_data        by reference so it can be modified
601
-     * @param EEM_Base $model
602
-     * @param array    $old_db_to_new_db_mapping by reference so it can be modified
603
-     * @return string one of the consts on this class that starts with do_*
604
-     */
605
-    protected function _decide_whether_to_insert_or_update_given_data_from_other_db(
606
-        $id_in_csv,
607
-        $model_object_data,
608
-        $model,
609
-        $old_db_to_new_db_mapping
610
-    ) {
611
-        $model_name = $model->get_this_model_name();
612
-        // if it's a site-to-site export-and-import, see if this modelobject's id
613
-        // in the old data that we know of
614
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) {
615
-            return self::do_update;
616
-        } else {
617
-            return self::do_insert;
618
-        }
619
-    }
620
-
621
-    /**
622
-     * If this thing basically already exists in the database, we want to update it;
623
-     * otherwise insert it (ie, someone tweaked the CSV file, or the item was
624
-     * deleted in the database so it should be re-inserted)
625
-     *
626
-     * @param type     $id_in_csv
627
-     * @param type     $model_object_data
628
-     * @param EEM_Base $model
629
-     * @param type     $old_db_to_new_db_mapping
630
-     * @return
631
-     */
632
-    protected function _decide_whether_to_insert_or_update_given_data_from_same_db(
633
-        $id_in_csv,
634
-        $model_object_data,
635
-        $model
636
-    ) {
637
-        // in this case, check if this thing ACTUALLY exists in the database
638
-        if ($model->get_one_conflicting($model_object_data)) {
639
-            return self::do_update;
640
-        } else {
641
-            return self::do_insert;
642
-        }
643
-    }
644
-
645
-    /**
646
-     * Using the $old_db_to_new_db_mapping array, replaces all the temporary IDs
647
-     * with their mapped real IDs. Eg, if importing from site A to B, the mapping
648
-     * file may indicate that the ID "my_event_id" maps to an actual event ID of 123.
649
-     * So this function searches for any event temp Ids called "my_event_id" and
650
-     * replaces them with 123.
651
-     * Also, if there is no temp ID for the INT foreign keys from another database,
652
-     * replaces them with 0 or the field's default.
653
-     *
654
-     * @param type     $model_object_data
655
-     * @param EEM_Base $model
656
-     * @param type     $old_db_to_new_db_mapping
657
-     * @param boolean  $export_from_site_a_to_b
658
-     * @return array updated model object data with temp IDs removed
659
-     */
660
-    protected function _replace_temp_ids_with_mappings(
661
-        $model_object_data,
662
-        $model,
663
-        $old_db_to_new_db_mapping,
664
-        $export_from_site_a_to_b
665
-    ) {
666
-        // if this model object's primary key is in the mapping, replace it
667
-        if (
668
-            $model->has_primary_key_field() &&
669
-            $model->get_primary_key_field()->is_auto_increment() &&
670
-            isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ]) &&
671
-            isset(
672
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $model_object_data[ $model->primary_key_name() ] ]
673
-            )
674
-        ) {
675
-            $model_object_data[ $model->primary_key_name() ] = $old_db_to_new_db_mapping[ $model->get_this_model_name(
676
-            ) ][ $model_object_data[ $model->primary_key_name() ] ];
677
-        }
678
-
679
-        try {
680
-            $model_name_field = $model->get_field_containing_related_model_name();
681
-            $models_pointed_to_by_model_name_field = $model_name_field->get_model_names_pointed_to();
682
-        } catch (EE_Error $e) {
683
-            $model_name_field = null;
684
-            $models_pointed_to_by_model_name_field = array();
685
-        }
686
-        foreach ($model->field_settings(true) as $field_obj) {
687
-            if ($field_obj instanceof EE_Foreign_Key_Int_Field) {
688
-                $models_pointed_to = $field_obj->get_model_names_pointed_to();
689
-                $found_a_mapping = false;
690
-                foreach ($models_pointed_to as $model_pointed_to_by_fk) {
691
-                    if ($model_name_field) {
692
-                        $value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ];
693
-                        if ($value_of_model_name_field == $model_pointed_to_by_fk) {
694
-                            $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
695
-                                $model_object_data[ $field_obj->get_name() ],
696
-                                $model_pointed_to_by_fk,
697
-                                $old_db_to_new_db_mapping,
698
-                                $export_from_site_a_to_b
699
-                            );
700
-                            $found_a_mapping = true;
701
-                            break;
702
-                        }
703
-                    } else {
704
-                        $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
705
-                            $model_object_data[ $field_obj->get_name() ],
706
-                            $model_pointed_to_by_fk,
707
-                            $old_db_to_new_db_mapping,
708
-                            $export_from_site_a_to_b
709
-                        );
710
-                        $found_a_mapping = true;
711
-                    }
712
-                    // once we've found a mapping for this field no need to continue
713
-                    if ($found_a_mapping) {
714
-                        break;
715
-                    }
716
-                }
717
-            } else {
718
-                // it's a string foreign key (which we leave alone, because those are things
719
-                // like country names, which we'd really rather not make 2 USAs etc (we'd actually
720
-                // prefer to just update one)
721
-                // or it's just a regular value that ought to be replaced
722
-            }
723
-        }
724
-        //
725
-        if ($model instanceof EEM_Term_Taxonomy) {
726
-            $model_object_data = $this->_handle_split_term_ids($model_object_data);
727
-        }
728
-        return $model_object_data;
729
-    }
730
-
731
-    /**
732
-     * If the data was exported PRE-4.2, but then imported POST-4.2, then the term_id
733
-     * this term-taxonomy refers to may be out-of-date so we need to update it.
734
-     * see https://make.wordpress.org/core/2015/02/16/taxonomy-term-splitting-in-4-2-a-developer-guide/
735
-     *
736
-     * @param type $model_object_data
737
-     * @return array new model object data
738
-     */
739
-    protected function _handle_split_term_ids($model_object_data)
740
-    {
741
-        if (
742
-            isset($model_object_data['term_id'])
743
-            && isset($model_object_data['taxonomy'])
744
-            && apply_filters(
745
-                'FHEE__EE_Import__handle_split_term_ids__function_exists',
746
-                function_exists('wp_get_split_term'),
747
-                $model_object_data
748
-            )
749
-        ) {
750
-            $new_term_id = wp_get_split_term($model_object_data['term_id'], $model_object_data['taxonomy']);
751
-            if ($new_term_id) {
752
-                $model_object_data['term_id'] = $new_term_id;
753
-            }
754
-        }
755
-        return $model_object_data;
756
-    }
757
-
758
-    /**
759
-     * Given the object's ID and its model's name, find it int he mapping data,
760
-     * bearing in mind where it came from
761
-     *
762
-     * @param type   $object_id
763
-     * @param string $model_name
764
-     * @param array  $old_db_to_new_db_mapping
765
-     * @param type   $export_from_site_a_to_b
766
-     * @return int
767
-     */
768
-    protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b)
769
-    {
770
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) {
771
-            return $old_db_to_new_db_mapping[ $model_name ][ $object_id ];
772
-        } elseif ($object_id == '0' || $object_id == '') {
773
-            // leave as-is
774
-            return $object_id;
775
-        } elseif ($export_from_site_a_to_b) {
776
-            // we couldn't find a mapping for this, and it's from a different site,
777
-            // so blank it out
778
-            return null;
779
-        } elseif (! $export_from_site_a_to_b) {
780
-            // we coudln't find a mapping for this, but it's from thsi DB anyway
781
-            // so let's just leave it as-is
782
-            return $object_id;
783
-        }
784
-    }
785
-
786
-    /**
787
-     *
788
-     * @param type     $id_in_csv
789
-     * @param type     $model_object_data
790
-     * @param EEM_Base $model
791
-     * @param type     $old_db_to_new_db_mapping
792
-     * @return array updated $old_db_to_new_db_mapping
793
-     */
794
-    protected function _insert_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
795
-    {
796
-        // remove the primary key, if there is one (we don't want it for inserts OR updates)
797
-        // we'll put it back in if we need it
798
-        if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) {
799
-            $effective_id = $model_object_data[ $model->primary_key_name() ];
800
-            unset($model_object_data[ $model->primary_key_name() ]);
801
-        } else {
802
-            $effective_id = $model->get_index_primary_key_string($model_object_data);
803
-        }
804
-        // the model takes care of validating the CSV's input
805
-        try {
806
-            $new_id = $model->insert($model_object_data);
807
-            if ($new_id) {
808
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id;
809
-                $this->_total_inserts++;
810
-                EE_Error::add_success(
811
-                    sprintf(
812
-                        __("Successfully added new %s (with id %s) with csv data %s", "event_espresso"),
813
-                        $model->get_this_model_name(),
814
-                        $new_id,
815
-                        implode(",", $model_object_data)
816
-                    )
817
-                );
818
-            } else {
819
-                $this->_total_insert_errors++;
820
-                // put the ID used back in there for the error message
821
-                if ($model->has_primary_key_field()) {
822
-                    $model_object_data[ $model->primary_key_name() ] = $effective_id;
823
-                }
824
-                EE_Error::add_error(
825
-                    sprintf(
826
-                        __("Could not insert new %s with the csv data: %s", "event_espresso"),
827
-                        $model->get_this_model_name(),
828
-                        http_build_query($model_object_data)
829
-                    ),
830
-                    __FILE__,
831
-                    __FUNCTION__,
832
-                    __LINE__
833
-                );
834
-            }
835
-        } catch (EE_Error $e) {
836
-            $this->_total_insert_errors++;
837
-            if ($model->has_primary_key_field()) {
838
-                $model_object_data[ $model->primary_key_name() ] = $effective_id;
839
-            }
840
-            EE_Error::add_error(
841
-                sprintf(
842
-                    __("Could not insert new %s with the csv data: %s because %s", "event_espresso"),
843
-                    $model->get_this_model_name(),
844
-                    implode(",", $model_object_data),
845
-                    $e->getMessage()
846
-                ),
847
-                __FILE__,
848
-                __FUNCTION__,
849
-                __LINE__
850
-            );
851
-        }
852
-        return $old_db_to_new_db_mapping;
853
-    }
854
-
855
-    /**
856
-     * Given the model object data, finds the row to update and updates it
857
-     *
858
-     * @param string|int $id_in_csv
859
-     * @param array      $model_object_data
860
-     * @param EEM_Base   $model
861
-     * @param array      $old_db_to_new_db_mapping
862
-     * @return array updated $old_db_to_new_db_mapping
863
-     */
864
-    protected function _update_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
865
-    {
866
-        try {
867
-            // let's keep two copies of the model object data:
868
-            // one for performing an update, one for everthing else
869
-            $model_object_data_for_update = $model_object_data;
870
-            if ($model->has_primary_key_field()) {
871
-                $conditions = array($model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]);
872
-                // remove the primary key because we shouldn't use it for updating
873
-                unset($model_object_data_for_update[ $model->primary_key_name() ]);
874
-            } elseif ($model->get_combined_primary_key_fields() > 1) {
875
-                $conditions = array();
876
-                foreach ($model->get_combined_primary_key_fields() as $key_field) {
877
-                    $conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ];
878
-                }
879
-            } else {
880
-                $model->primary_key_name(
881
-                );// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
882
-            }
883
-
884
-            $success = $model->update($model_object_data_for_update, array($conditions));
885
-            if ($success) {
886
-                $this->_total_updates++;
887
-                EE_Error::add_success(
888
-                    sprintf(
889
-                        __("Successfully updated %s with csv data %s", "event_espresso"),
890
-                        $model->get_this_model_name(),
891
-                        implode(",", $model_object_data_for_update)
892
-                    )
893
-                );
894
-                // we should still record the mapping even though it was an update
895
-                // because if we were going to insert somethign but it was going to conflict
896
-                // we would have last-minute decided to update. So we'd like to know what we updated
897
-                // and so we record what record ended up being updated using the mapping
898
-                if ($model->has_primary_key_field()) {
899
-                    $new_key_for_mapping = $model_object_data[ $model->primary_key_name() ];
900
-                } else {
901
-                    // no primary key just a combined key
902
-                    $new_key_for_mapping = $model->get_index_primary_key_string($model_object_data);
903
-                }
904
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping;
905
-            } else {
906
-                $matched_items = $model->get_all(array($conditions));
907
-                if (! $matched_items) {
908
-                    // no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck?
909
-                    $this->_total_update_errors++;
910
-                    EE_Error::add_error(
911
-                        sprintf(
912
-                            __(
913
-                                "Could not update %s with the csv data: '%s' for an unknown reason (using WHERE conditions %s)",
914
-                                "event_espresso"
915
-                            ),
916
-                            $model->get_this_model_name(),
917
-                            http_build_query($model_object_data),
918
-                            http_build_query($conditions)
919
-                        ),
920
-                        __FILE__,
921
-                        __FUNCTION__,
922
-                        __LINE__
923
-                    );
924
-                } else {
925
-                    $this->_total_updates++;
926
-                    EE_Error::add_success(
927
-                        sprintf(
928
-                            __(
929
-                                "%s with csv data '%s' was found in the database and didn't need updating because all the data is identical.",
930
-                                "event_espresso"
931
-                            ),
932
-                            $model->get_this_model_name(),
933
-                            implode(",", $model_object_data)
934
-                        )
935
-                    );
936
-                }
937
-            }
938
-        } catch (EE_Error $e) {
939
-            $this->_total_update_errors++;
940
-            $basic_message = sprintf(
941
-                __("Could not update %s with the csv data: %s because %s", "event_espresso"),
942
-                $model->get_this_model_name(),
943
-                implode(",", $model_object_data),
944
-                $e->getMessage()
945
-            );
946
-            $debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString();
947
-            EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__);
948
-        }
949
-        return $old_db_to_new_db_mapping;
950
-    }
951
-
952
-    /**
953
-     * Gets the number of inserts performed since importer was instantiated or reset
954
-     *
955
-     * @return int
956
-     */
957
-    public function get_total_inserts()
958
-    {
959
-        return $this->_total_inserts;
960
-    }
961
-
962
-    /**
963
-     *  Gets the number of insert errors since importer was instantiated or reset
964
-     *
965
-     * @return int
966
-     */
967
-    public function get_total_insert_errors()
968
-    {
969
-        return $this->_total_insert_errors;
970
-    }
971
-
972
-    /**
973
-     *  Gets the number of updates performed since importer was instantiated or reset
974
-     *
975
-     * @return int
976
-     */
977
-    public function get_total_updates()
978
-    {
979
-        return $this->_total_updates;
980
-    }
981
-
982
-    /**
983
-     *  Gets the number of update errors since importer was instantiated or reset
984
-     *
985
-     * @return int
986
-     */
987
-    public function get_total_update_errors()
988
-    {
989
-        return $this->_total_update_errors;
990
-    }
125
+		$uploader = ob_get_clean();
126
+		return $uploader;
127
+	}
128
+
129
+
130
+	/**
131
+	 * @Import Event Espresso data - some code "borrowed" from event espresso csv_import.php
132
+	 * @access public
133
+	 * @return boolean success
134
+	 */
135
+	public function import()
136
+	{
137
+
138
+		require_once(EE_CLASSES . 'EE_CSV.class.php');
139
+		$this->EE_CSV = EE_CSV::instance();
140
+
141
+		if (isset($_REQUEST['import'])) {
142
+			if (isset($_POST['csv_submitted'])) {
143
+				switch ($_FILES['file']['error'][0]) {
144
+					case UPLOAD_ERR_OK:
145
+						$error_msg = false;
146
+						break;
147
+					case UPLOAD_ERR_INI_SIZE:
148
+						$error_msg = __(
149
+							"'The uploaded file exceeds the upload_max_filesize directive in php.ini.'",
150
+							"event_espresso"
151
+						);
152
+						break;
153
+					case UPLOAD_ERR_FORM_SIZE:
154
+						$error_msg = __(
155
+							'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
156
+							"event_espresso"
157
+						);
158
+						break;
159
+					case UPLOAD_ERR_PARTIAL:
160
+						$error_msg = __('The uploaded file was only partially uploaded.', "event_espresso");
161
+						break;
162
+					case UPLOAD_ERR_NO_FILE:
163
+						$error_msg = __('No file was uploaded.', "event_espresso");
164
+						break;
165
+					case UPLOAD_ERR_NO_TMP_DIR:
166
+						$error_msg = __('Missing a temporary folder.', "event_espresso");
167
+						break;
168
+					case UPLOAD_ERR_CANT_WRITE:
169
+						$error_msg = __('Failed to write file to disk.', "event_espresso");
170
+						break;
171
+					case UPLOAD_ERR_EXTENSION:
172
+						$error_msg = __('File upload stopped by extension.', "event_espresso");
173
+						break;
174
+					default:
175
+						$error_msg = __(
176
+							'An unknown error occurred and the file could not be uploaded',
177
+							"event_espresso"
178
+						);
179
+						break;
180
+				}
181
+
182
+				if (! $error_msg) {
183
+					$filename = $_FILES['file']['name'][0];
184
+					$file_ext = substr(strrchr($filename, '.'), 1);
185
+					$file_type = $_FILES['file']['type'][0];
186
+					$temp_file = $_FILES['file']['tmp_name'][0];
187
+					$filesize = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB
188
+
189
+					if ($file_ext == 'csv') {
190
+						$max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB
191
+						if ($filesize < $max_upload || true) {
192
+							$wp_upload_dir = str_replace(array('\\', '/'), '/', wp_upload_dir());
193
+							$path_to_file = $wp_upload_dir['basedir'] . '/espresso/' . $filename;
194
+
195
+							if (move_uploaded_file($temp_file, $path_to_file)) {
196
+								// convert csv to array
197
+								$this->csv_array = $this->EE_CSV->import_csv_to_model_data_array($path_to_file);
198
+
199
+								// was data successfully stored in an array?
200
+								if (is_array($this->csv_array)) {
201
+									$import_what = str_replace('csv_import_', '', $_REQUEST['action']);
202
+									$import_what = str_replace('_', ' ', ucwords($import_what));
203
+									$processed_data = $this->csv_array;
204
+									$this->columns_to_save = false;
205
+
206
+									// if any imports require funcky processing, we'll catch them in the switch
207
+									switch ($_REQUEST['action']) {
208
+										case "import_events":
209
+										case "event_list":
210
+											$import_what = 'Event Details';
211
+											break;
212
+
213
+										case 'groupon_import_csv':
214
+											$import_what = 'Groupon Codes';
215
+											$processed_data = $this->process_groupon_codes();
216
+											break;
217
+									}
218
+									// save processed codes to db
219
+									if ($this->save_csv_data_array_to_db($processed_data, $this->columns_to_save)) {
220
+										return true;
221
+									}
222
+								} else {
223
+									// no array? must be an error
224
+									EE_Error::add_error(
225
+										sprintf(__("No file seems to have been uploaded", "event_espresso")),
226
+										__FILE__,
227
+										__FUNCTION__,
228
+										__LINE__
229
+									);
230
+									return false;
231
+								}
232
+							} else {
233
+								EE_Error::add_error(
234
+									sprintf(__("%s was not successfully uploaded", "event_espresso"), $filename),
235
+									__FILE__,
236
+									__FUNCTION__,
237
+									__LINE__
238
+								);
239
+								return false;
240
+							}
241
+						} else {
242
+							EE_Error::add_error(
243
+								sprintf(
244
+									__(
245
+										"%s was too large of a file and could not be uploaded. The max filesize is %s' KB.",
246
+										"event_espresso"
247
+									),
248
+									$filename,
249
+									$max_upload
250
+								),
251
+								__FILE__,
252
+								__FUNCTION__,
253
+								__LINE__
254
+							);
255
+							return false;
256
+						}
257
+					} else {
258
+						EE_Error::add_error(
259
+							sprintf(__("%s  had an invalid file extension, not uploaded", "event_espresso"), $filename),
260
+							__FILE__,
261
+							__FUNCTION__,
262
+							__LINE__
263
+						);
264
+						return false;
265
+					}
266
+				} else {
267
+					EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
268
+					return false;
269
+				}
270
+			}
271
+		}
272
+		return;
273
+	}
274
+
275
+
276
+	/**
277
+	 *    Given an array of data (usually from a CSV import) attempts to save that data to the db.
278
+	 *    If $model_name ISN'T provided, assumes that this is a 3d array, with toplevel keys being model names,
279
+	 *    next level being numeric indexes adn each value representing a model object, and the last layer down
280
+	 *    being keys of model fields and their proposed values.
281
+	 *    If $model_name IS provided, assumes a 2d array of the bottom two layers previously mentioned.
282
+	 *    If the CSV data says (in the metadata row) that it's from the SAME database,
283
+	 *    we treat the IDs in the CSV as the normal IDs, and try to update those records. However, if those
284
+	 *    IDs DON'T exist in the database, they're treated as temporary IDs,
285
+	 *    which can used elsewhere to refer to the same object. Once an item
286
+	 *    with a temporary ID gets inserted, we record its mapping from temporary
287
+	 *    ID to real ID, and use the real ID in place of the temporary ID
288
+	 *    when that temporary ID was used as a foreign key.
289
+	 *    If the CSV data says (in the metadata again) that it's from a DIFFERENT database,
290
+	 *    we treat all the IDs in the CSV as temporary ID- eg, if the CSV specifies an event with
291
+	 *    ID 1, and the database already has an event with ID 1, we assume that's just a coincidence,
292
+	 *    and insert a new event, and map it's temporary ID of 1 over to its new real ID.
293
+	 *    An important exception are non-auto-increment primary keys. If one entry in the
294
+	 *    CSV file has the same ID as one in the DB, we assume they are meant to be
295
+	 *    the same item, and instead update the item in the DB with that same ID.
296
+	 *    Also note, we remember the mappings permanently. So the 2nd, 3rd, and 10000th
297
+	 *    time you import a CSV from a different site, we remember their mappings, and
298
+	 * will try to update the item in the DB instead of inserting another item (eg
299
+	 * if we previously imported an event with temporary ID 1, and then it got a
300
+	 * real ID of 123, we remember that. So the next time we import an event with
301
+	 * temporary ID, from the same site, we know that it's real ID is 123, and will
302
+	 * update that event, instead of adding a new event).
303
+	 *
304
+	 * @access public
305
+	 * @param array $csv_data_array - the array containing the csv data produced from
306
+	 *                              EE_CSV::import_csv_to_model_data_array()
307
+	 * @param array $fields_to_save - an array containing the csv column names as keys with the corresponding db table
308
+	 *                              fields they will be saved to
309
+	 * @return TRUE on success, FALSE on fail
310
+	 * @throws \EE_Error
311
+	 */
312
+	public function save_csv_data_array_to_db($csv_data_array, $model_name = false)
313
+	{
314
+		$success = false;
315
+		$error = false;
316
+		// whther to treat this import as if it's data froma different database or not
317
+		// ie, if it IS from a different database, ignore foreign keys whihf
318
+		$export_from_site_a_to_b = true;
319
+		// first level of array is not table information but a table name was passed to the function
320
+		// array is only two levels deep, so let's fix that by adding a level, else the next steps will fail
321
+		if ($model_name) {
322
+			$csv_data_array = array($csv_data_array);
323
+		}
324
+		// begin looking through the $csv_data_array, expecting the toplevel key to be the model's name...
325
+		$old_site_url = 'none-specified';
326
+		// hanlde metadata
327
+		if (isset($csv_data_array[ EE_CSV::metadata_header ])) {
328
+			$csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]);
329
+			// ok so its metadata, dont try to save it to ehte db obviously...
330
+			if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) {
331
+				EE_Error::add_attention(
332
+					sprintf(
333
+						__(
334
+							"CSV Data appears to be from the same database, so attempting to update data",
335
+							"event_espresso"
336
+						)
337
+					)
338
+				);
339
+				$export_from_site_a_to_b = false;
340
+			} else {
341
+				$old_site_url = isset($csv_metadata['site_url']) ? $csv_metadata['site_url'] : $old_site_url;
342
+				EE_Error::add_attention(
343
+					sprintf(
344
+						__(
345
+							"CSV Data appears to be from a different database (%s instead of %s), so we assume IDs in the CSV data DO NOT correspond to IDs in this database",
346
+							"event_espresso"
347
+						),
348
+						$old_site_url,
349
+						site_url()
350
+					)
351
+				);
352
+			};
353
+			unset($csv_data_array[ EE_CSV::metadata_header ]);
354
+		}
355
+		/**
356
+		 * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and
357
+		 * the value will be the newly-inserted ID.
358
+		 * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option
359
+		 */
360
+		$old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), array());
361
+		if ($old_db_to_new_db_mapping) {
362
+			EE_Error::add_attention(
363
+				sprintf(
364
+					__(
365
+						"We noticed you have imported data via CSV from %s before. Because of this, IDs in your CSV have been mapped to their new IDs in %s",
366
+						"event_espresso"
367
+					),
368
+					$old_site_url,
369
+					site_url()
370
+				)
371
+			);
372
+		}
373
+		$old_db_to_new_db_mapping = $this->save_data_rows_to_db(
374
+			$csv_data_array,
375
+			$export_from_site_a_to_b,
376
+			$old_db_to_new_db_mapping
377
+		);
378
+
379
+		// save the mapping from old db to new db in case they try re-importing the same data from the same website again
380
+		update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping);
381
+
382
+		if ($this->_total_updates > 0) {
383
+			EE_Error::add_success(
384
+				sprintf(
385
+					__("%s existing records in the database were updated.", "event_espresso"),
386
+					$this->_total_updates
387
+				)
388
+			);
389
+			$success = true;
390
+		}
391
+		if ($this->_total_inserts > 0) {
392
+			EE_Error::add_success(
393
+				sprintf(__("%s new records were added to the database.", "event_espresso"), $this->_total_inserts)
394
+			);
395
+			$success = true;
396
+		}
397
+
398
+		if ($this->_total_update_errors > 0) {
399
+			EE_Error::add_error(
400
+				sprintf(
401
+					__(
402
+						"'One or more errors occurred, and a total of %s existing records in the database were <strong>not</strong> updated.'",
403
+						"event_espresso"
404
+					),
405
+					$this->_total_update_errors
406
+				),
407
+				__FILE__,
408
+				__FUNCTION__,
409
+				__LINE__
410
+			);
411
+			$error = true;
412
+		}
413
+		if ($this->_total_insert_errors > 0) {
414
+			EE_Error::add_error(
415
+				sprintf(
416
+					__(
417
+						"One or more errors occurred, and a total of %s new records were <strong>not</strong> added to the database.'",
418
+						"event_espresso"
419
+					),
420
+					$this->_total_insert_errors
421
+				),
422
+				__FILE__,
423
+				__FUNCTION__,
424
+				__LINE__
425
+			);
426
+			$error = true;
427
+		}
428
+
429
+		// lastly, we need to update the datetime and ticket sold amounts
430
+		// as those may have been affected by this
431
+		EEM_Ticket::instance()->update_tickets_sold(EEM_Ticket::instance()->get_all());
432
+
433
+		// if there was at least one success and absolutely no errors
434
+		if ($success && ! $error) {
435
+			return true;
436
+		} else {
437
+			return false;
438
+		}
439
+	}
440
+
441
+
442
+	/**
443
+	 * Processes the array of data, given the knowledge that it's from the same database or a different one,
444
+	 * and the mapping from temporary IDs to real IDs.
445
+	 * If the data is from a different database, we treat the primary keys and their corresponding
446
+	 * foreign keys as "temp Ids", basically identifiers that get mapped to real primary keys
447
+	 * in the real target database. As items are inserted, their temporary primary keys
448
+	 * are mapped to the real IDs in the target database. Also, before doing any update or
449
+	 * insert, we replace all the temp ID which are foreign keys with their mapped real IDs.
450
+	 * An exception: string primary keys are treated as real IDs, or else we'd need to
451
+	 * dynamically generate new string primary keys which would be very awkard for the country table etc.
452
+	 * Also, models with no primary key are strange too. We combine use their primar key INDEX (a
453
+	 * combination of fields) to create a unique string identifying the row and store
454
+	 * those in the mapping.
455
+	 *
456
+	 * If the data is from the same database, we usually treat primary keys as real IDs.
457
+	 * An exception is if there is nothing in the database for that ID. If that's the case,
458
+	 * we need to insert a new row for that ID, and then map from the non-existent ID
459
+	 * to the newly-inserted real ID.
460
+	 *
461
+	 * @param type $csv_data_array
462
+	 * @param type $export_from_site_a_to_b
463
+	 * @param type $old_db_to_new_db_mapping
464
+	 * @return array updated $old_db_to_new_db_mapping
465
+	 */
466
+	public function save_data_rows_to_db($csv_data_array, $export_from_site_a_to_b, $old_db_to_new_db_mapping)
467
+	{
468
+		foreach ($csv_data_array as $model_name_in_csv_data => $model_data_from_import) {
469
+			// now check that assumption was correct. If
470
+			if (EE_Registry::instance()->is_model_name($model_name_in_csv_data)) {
471
+				$model_name = $model_name_in_csv_data;
472
+			} else {
473
+				// no table info in the array and no table name passed to the function?? FAIL
474
+				EE_Error::add_error(
475
+					__(
476
+						'No table information was specified and/or found, therefore the import could not be completed',
477
+						'event_espresso'
478
+					),
479
+					__FILE__,
480
+					__FUNCTION__,
481
+					__LINE__
482
+				);
483
+				return false;
484
+			}
485
+			/* @var $model EEM_Base */
486
+			$model = EE_Registry::instance()->load_model($model_name);
487
+
488
+			// so without further ado, scanning all the data provided for primary keys and their inital values
489
+			foreach ($model_data_from_import as $model_object_data) {
490
+				// before we do ANYTHING, make sure the csv row wasn't just completely blank
491
+				$row_is_completely_empty = true;
492
+				foreach ($model_object_data as $field) {
493
+					if ($field) {
494
+						$row_is_completely_empty = false;
495
+					}
496
+				}
497
+				if ($row_is_completely_empty) {
498
+					continue;
499
+				}
500
+				// find the PK in the row of data (or a combined key if
501
+				// there is no primary key)
502
+				if ($model->has_primary_key_field()) {
503
+					$id_in_csv = $model_object_data[ $model->primary_key_name() ];
504
+				} else {
505
+					$id_in_csv = $model->get_index_primary_key_string($model_object_data);
506
+				}
507
+
508
+
509
+				$model_object_data = $this->_replace_temp_ids_with_mappings(
510
+					$model_object_data,
511
+					$model,
512
+					$old_db_to_new_db_mapping,
513
+					$export_from_site_a_to_b
514
+				);
515
+				// now we need to decide if we're going to add a new model object given the $model_object_data,
516
+				// or just update.
517
+				if ($export_from_site_a_to_b) {
518
+					$what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_other_db(
519
+						$id_in_csv,
520
+						$model_object_data,
521
+						$model,
522
+						$old_db_to_new_db_mapping
523
+					);
524
+				} else {// this is just a re-import
525
+					$what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_same_db(
526
+						$id_in_csv,
527
+						$model_object_data,
528
+						$model,
529
+						$old_db_to_new_db_mapping
530
+					);
531
+				}
532
+				if ($what_to_do == self::do_nothing) {
533
+					continue;
534
+				}
535
+
536
+				// double-check we actually want to insert, if that's what we're planning
537
+				// based on whether this item would be unique in the DB or not
538
+				if ($what_to_do == self::do_insert) {
539
+					// we're supposed to be inserting. But wait, will this thing
540
+					// be acceptable if inserted?
541
+					$conflicting = $model->get_one_conflicting($model_object_data, false);
542
+					if ($conflicting) {
543
+						// ok, this item would conflict if inserted. Just update the item that it conflicts with.
544
+						$what_to_do = self::do_update;
545
+						// and if this model has a primary key, remember its mapping
546
+						if ($model->has_primary_key_field()) {
547
+							$old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID();
548
+							$model_object_data[ $model->primary_key_name() ] = $conflicting->ID();
549
+						} else {
550
+							// we want to update this conflicting item, instead of inserting a conflicting item
551
+							// so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields
552
+							// for the WHERE conditions in the update). At the time of this comment, there were no models like this
553
+							foreach ($model->get_combined_primary_key_fields() as $key_field) {
554
+								$model_object_data[ $key_field->get_name() ] = $conflicting->get(
555
+									$key_field->get_name()
556
+								);
557
+							}
558
+						}
559
+					}
560
+				}
561
+				if ($what_to_do == self::do_insert) {
562
+					$old_db_to_new_db_mapping = $this->_insert_from_data_array(
563
+						$id_in_csv,
564
+						$model_object_data,
565
+						$model,
566
+						$old_db_to_new_db_mapping
567
+					);
568
+				} elseif ($what_to_do == self::do_update) {
569
+					$old_db_to_new_db_mapping = $this->_update_from_data_array(
570
+						$id_in_csv,
571
+						$model_object_data,
572
+						$model,
573
+						$old_db_to_new_db_mapping
574
+					);
575
+				} else {
576
+					throw new EE_Error(
577
+						sprintf(
578
+							__(
579
+								'Programming error. We shoudl be inserting or updating, but instead we are being told to "%s", whifh is invalid',
580
+								'event_espresso'
581
+							),
582
+							$what_to_do
583
+						)
584
+					);
585
+				}
586
+			}
587
+		}
588
+		return $old_db_to_new_db_mapping;
589
+	}
590
+
591
+
592
+	/**
593
+	 * Decides whether or not to insert, given that this data is from another database.
594
+	 * So, if the primary key of this $model_object_data already exists in the database,
595
+	 * it's just a coincidence and we should still insert. The only time we should
596
+	 * update is when we know what it maps to, or there's something that would
597
+	 * conflict (and we should instead just update that conflicting thing)
598
+	 *
599
+	 * @param string   $id_in_csv
600
+	 * @param array    $model_object_data        by reference so it can be modified
601
+	 * @param EEM_Base $model
602
+	 * @param array    $old_db_to_new_db_mapping by reference so it can be modified
603
+	 * @return string one of the consts on this class that starts with do_*
604
+	 */
605
+	protected function _decide_whether_to_insert_or_update_given_data_from_other_db(
606
+		$id_in_csv,
607
+		$model_object_data,
608
+		$model,
609
+		$old_db_to_new_db_mapping
610
+	) {
611
+		$model_name = $model->get_this_model_name();
612
+		// if it's a site-to-site export-and-import, see if this modelobject's id
613
+		// in the old data that we know of
614
+		if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) {
615
+			return self::do_update;
616
+		} else {
617
+			return self::do_insert;
618
+		}
619
+	}
620
+
621
+	/**
622
+	 * If this thing basically already exists in the database, we want to update it;
623
+	 * otherwise insert it (ie, someone tweaked the CSV file, or the item was
624
+	 * deleted in the database so it should be re-inserted)
625
+	 *
626
+	 * @param type     $id_in_csv
627
+	 * @param type     $model_object_data
628
+	 * @param EEM_Base $model
629
+	 * @param type     $old_db_to_new_db_mapping
630
+	 * @return
631
+	 */
632
+	protected function _decide_whether_to_insert_or_update_given_data_from_same_db(
633
+		$id_in_csv,
634
+		$model_object_data,
635
+		$model
636
+	) {
637
+		// in this case, check if this thing ACTUALLY exists in the database
638
+		if ($model->get_one_conflicting($model_object_data)) {
639
+			return self::do_update;
640
+		} else {
641
+			return self::do_insert;
642
+		}
643
+	}
644
+
645
+	/**
646
+	 * Using the $old_db_to_new_db_mapping array, replaces all the temporary IDs
647
+	 * with their mapped real IDs. Eg, if importing from site A to B, the mapping
648
+	 * file may indicate that the ID "my_event_id" maps to an actual event ID of 123.
649
+	 * So this function searches for any event temp Ids called "my_event_id" and
650
+	 * replaces them with 123.
651
+	 * Also, if there is no temp ID for the INT foreign keys from another database,
652
+	 * replaces them with 0 or the field's default.
653
+	 *
654
+	 * @param type     $model_object_data
655
+	 * @param EEM_Base $model
656
+	 * @param type     $old_db_to_new_db_mapping
657
+	 * @param boolean  $export_from_site_a_to_b
658
+	 * @return array updated model object data with temp IDs removed
659
+	 */
660
+	protected function _replace_temp_ids_with_mappings(
661
+		$model_object_data,
662
+		$model,
663
+		$old_db_to_new_db_mapping,
664
+		$export_from_site_a_to_b
665
+	) {
666
+		// if this model object's primary key is in the mapping, replace it
667
+		if (
668
+			$model->has_primary_key_field() &&
669
+			$model->get_primary_key_field()->is_auto_increment() &&
670
+			isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ]) &&
671
+			isset(
672
+				$old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $model_object_data[ $model->primary_key_name() ] ]
673
+			)
674
+		) {
675
+			$model_object_data[ $model->primary_key_name() ] = $old_db_to_new_db_mapping[ $model->get_this_model_name(
676
+			) ][ $model_object_data[ $model->primary_key_name() ] ];
677
+		}
678
+
679
+		try {
680
+			$model_name_field = $model->get_field_containing_related_model_name();
681
+			$models_pointed_to_by_model_name_field = $model_name_field->get_model_names_pointed_to();
682
+		} catch (EE_Error $e) {
683
+			$model_name_field = null;
684
+			$models_pointed_to_by_model_name_field = array();
685
+		}
686
+		foreach ($model->field_settings(true) as $field_obj) {
687
+			if ($field_obj instanceof EE_Foreign_Key_Int_Field) {
688
+				$models_pointed_to = $field_obj->get_model_names_pointed_to();
689
+				$found_a_mapping = false;
690
+				foreach ($models_pointed_to as $model_pointed_to_by_fk) {
691
+					if ($model_name_field) {
692
+						$value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ];
693
+						if ($value_of_model_name_field == $model_pointed_to_by_fk) {
694
+							$model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
695
+								$model_object_data[ $field_obj->get_name() ],
696
+								$model_pointed_to_by_fk,
697
+								$old_db_to_new_db_mapping,
698
+								$export_from_site_a_to_b
699
+							);
700
+							$found_a_mapping = true;
701
+							break;
702
+						}
703
+					} else {
704
+						$model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
705
+							$model_object_data[ $field_obj->get_name() ],
706
+							$model_pointed_to_by_fk,
707
+							$old_db_to_new_db_mapping,
708
+							$export_from_site_a_to_b
709
+						);
710
+						$found_a_mapping = true;
711
+					}
712
+					// once we've found a mapping for this field no need to continue
713
+					if ($found_a_mapping) {
714
+						break;
715
+					}
716
+				}
717
+			} else {
718
+				// it's a string foreign key (which we leave alone, because those are things
719
+				// like country names, which we'd really rather not make 2 USAs etc (we'd actually
720
+				// prefer to just update one)
721
+				// or it's just a regular value that ought to be replaced
722
+			}
723
+		}
724
+		//
725
+		if ($model instanceof EEM_Term_Taxonomy) {
726
+			$model_object_data = $this->_handle_split_term_ids($model_object_data);
727
+		}
728
+		return $model_object_data;
729
+	}
730
+
731
+	/**
732
+	 * If the data was exported PRE-4.2, but then imported POST-4.2, then the term_id
733
+	 * this term-taxonomy refers to may be out-of-date so we need to update it.
734
+	 * see https://make.wordpress.org/core/2015/02/16/taxonomy-term-splitting-in-4-2-a-developer-guide/
735
+	 *
736
+	 * @param type $model_object_data
737
+	 * @return array new model object data
738
+	 */
739
+	protected function _handle_split_term_ids($model_object_data)
740
+	{
741
+		if (
742
+			isset($model_object_data['term_id'])
743
+			&& isset($model_object_data['taxonomy'])
744
+			&& apply_filters(
745
+				'FHEE__EE_Import__handle_split_term_ids__function_exists',
746
+				function_exists('wp_get_split_term'),
747
+				$model_object_data
748
+			)
749
+		) {
750
+			$new_term_id = wp_get_split_term($model_object_data['term_id'], $model_object_data['taxonomy']);
751
+			if ($new_term_id) {
752
+				$model_object_data['term_id'] = $new_term_id;
753
+			}
754
+		}
755
+		return $model_object_data;
756
+	}
757
+
758
+	/**
759
+	 * Given the object's ID and its model's name, find it int he mapping data,
760
+	 * bearing in mind where it came from
761
+	 *
762
+	 * @param type   $object_id
763
+	 * @param string $model_name
764
+	 * @param array  $old_db_to_new_db_mapping
765
+	 * @param type   $export_from_site_a_to_b
766
+	 * @return int
767
+	 */
768
+	protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b)
769
+	{
770
+		if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) {
771
+			return $old_db_to_new_db_mapping[ $model_name ][ $object_id ];
772
+		} elseif ($object_id == '0' || $object_id == '') {
773
+			// leave as-is
774
+			return $object_id;
775
+		} elseif ($export_from_site_a_to_b) {
776
+			// we couldn't find a mapping for this, and it's from a different site,
777
+			// so blank it out
778
+			return null;
779
+		} elseif (! $export_from_site_a_to_b) {
780
+			// we coudln't find a mapping for this, but it's from thsi DB anyway
781
+			// so let's just leave it as-is
782
+			return $object_id;
783
+		}
784
+	}
785
+
786
+	/**
787
+	 *
788
+	 * @param type     $id_in_csv
789
+	 * @param type     $model_object_data
790
+	 * @param EEM_Base $model
791
+	 * @param type     $old_db_to_new_db_mapping
792
+	 * @return array updated $old_db_to_new_db_mapping
793
+	 */
794
+	protected function _insert_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
795
+	{
796
+		// remove the primary key, if there is one (we don't want it for inserts OR updates)
797
+		// we'll put it back in if we need it
798
+		if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) {
799
+			$effective_id = $model_object_data[ $model->primary_key_name() ];
800
+			unset($model_object_data[ $model->primary_key_name() ]);
801
+		} else {
802
+			$effective_id = $model->get_index_primary_key_string($model_object_data);
803
+		}
804
+		// the model takes care of validating the CSV's input
805
+		try {
806
+			$new_id = $model->insert($model_object_data);
807
+			if ($new_id) {
808
+				$old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id;
809
+				$this->_total_inserts++;
810
+				EE_Error::add_success(
811
+					sprintf(
812
+						__("Successfully added new %s (with id %s) with csv data %s", "event_espresso"),
813
+						$model->get_this_model_name(),
814
+						$new_id,
815
+						implode(",", $model_object_data)
816
+					)
817
+				);
818
+			} else {
819
+				$this->_total_insert_errors++;
820
+				// put the ID used back in there for the error message
821
+				if ($model->has_primary_key_field()) {
822
+					$model_object_data[ $model->primary_key_name() ] = $effective_id;
823
+				}
824
+				EE_Error::add_error(
825
+					sprintf(
826
+						__("Could not insert new %s with the csv data: %s", "event_espresso"),
827
+						$model->get_this_model_name(),
828
+						http_build_query($model_object_data)
829
+					),
830
+					__FILE__,
831
+					__FUNCTION__,
832
+					__LINE__
833
+				);
834
+			}
835
+		} catch (EE_Error $e) {
836
+			$this->_total_insert_errors++;
837
+			if ($model->has_primary_key_field()) {
838
+				$model_object_data[ $model->primary_key_name() ] = $effective_id;
839
+			}
840
+			EE_Error::add_error(
841
+				sprintf(
842
+					__("Could not insert new %s with the csv data: %s because %s", "event_espresso"),
843
+					$model->get_this_model_name(),
844
+					implode(",", $model_object_data),
845
+					$e->getMessage()
846
+				),
847
+				__FILE__,
848
+				__FUNCTION__,
849
+				__LINE__
850
+			);
851
+		}
852
+		return $old_db_to_new_db_mapping;
853
+	}
854
+
855
+	/**
856
+	 * Given the model object data, finds the row to update and updates it
857
+	 *
858
+	 * @param string|int $id_in_csv
859
+	 * @param array      $model_object_data
860
+	 * @param EEM_Base   $model
861
+	 * @param array      $old_db_to_new_db_mapping
862
+	 * @return array updated $old_db_to_new_db_mapping
863
+	 */
864
+	protected function _update_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
865
+	{
866
+		try {
867
+			// let's keep two copies of the model object data:
868
+			// one for performing an update, one for everthing else
869
+			$model_object_data_for_update = $model_object_data;
870
+			if ($model->has_primary_key_field()) {
871
+				$conditions = array($model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]);
872
+				// remove the primary key because we shouldn't use it for updating
873
+				unset($model_object_data_for_update[ $model->primary_key_name() ]);
874
+			} elseif ($model->get_combined_primary_key_fields() > 1) {
875
+				$conditions = array();
876
+				foreach ($model->get_combined_primary_key_fields() as $key_field) {
877
+					$conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ];
878
+				}
879
+			} else {
880
+				$model->primary_key_name(
881
+				);// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
882
+			}
883
+
884
+			$success = $model->update($model_object_data_for_update, array($conditions));
885
+			if ($success) {
886
+				$this->_total_updates++;
887
+				EE_Error::add_success(
888
+					sprintf(
889
+						__("Successfully updated %s with csv data %s", "event_espresso"),
890
+						$model->get_this_model_name(),
891
+						implode(",", $model_object_data_for_update)
892
+					)
893
+				);
894
+				// we should still record the mapping even though it was an update
895
+				// because if we were going to insert somethign but it was going to conflict
896
+				// we would have last-minute decided to update. So we'd like to know what we updated
897
+				// and so we record what record ended up being updated using the mapping
898
+				if ($model->has_primary_key_field()) {
899
+					$new_key_for_mapping = $model_object_data[ $model->primary_key_name() ];
900
+				} else {
901
+					// no primary key just a combined key
902
+					$new_key_for_mapping = $model->get_index_primary_key_string($model_object_data);
903
+				}
904
+				$old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping;
905
+			} else {
906
+				$matched_items = $model->get_all(array($conditions));
907
+				if (! $matched_items) {
908
+					// no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck?
909
+					$this->_total_update_errors++;
910
+					EE_Error::add_error(
911
+						sprintf(
912
+							__(
913
+								"Could not update %s with the csv data: '%s' for an unknown reason (using WHERE conditions %s)",
914
+								"event_espresso"
915
+							),
916
+							$model->get_this_model_name(),
917
+							http_build_query($model_object_data),
918
+							http_build_query($conditions)
919
+						),
920
+						__FILE__,
921
+						__FUNCTION__,
922
+						__LINE__
923
+					);
924
+				} else {
925
+					$this->_total_updates++;
926
+					EE_Error::add_success(
927
+						sprintf(
928
+							__(
929
+								"%s with csv data '%s' was found in the database and didn't need updating because all the data is identical.",
930
+								"event_espresso"
931
+							),
932
+							$model->get_this_model_name(),
933
+							implode(",", $model_object_data)
934
+						)
935
+					);
936
+				}
937
+			}
938
+		} catch (EE_Error $e) {
939
+			$this->_total_update_errors++;
940
+			$basic_message = sprintf(
941
+				__("Could not update %s with the csv data: %s because %s", "event_espresso"),
942
+				$model->get_this_model_name(),
943
+				implode(",", $model_object_data),
944
+				$e->getMessage()
945
+			);
946
+			$debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString();
947
+			EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__);
948
+		}
949
+		return $old_db_to_new_db_mapping;
950
+	}
951
+
952
+	/**
953
+	 * Gets the number of inserts performed since importer was instantiated or reset
954
+	 *
955
+	 * @return int
956
+	 */
957
+	public function get_total_inserts()
958
+	{
959
+		return $this->_total_inserts;
960
+	}
961
+
962
+	/**
963
+	 *  Gets the number of insert errors since importer was instantiated or reset
964
+	 *
965
+	 * @return int
966
+	 */
967
+	public function get_total_insert_errors()
968
+	{
969
+		return $this->_total_insert_errors;
970
+	}
971
+
972
+	/**
973
+	 *  Gets the number of updates performed since importer was instantiated or reset
974
+	 *
975
+	 * @return int
976
+	 */
977
+	public function get_total_updates()
978
+	{
979
+		return $this->_total_updates;
980
+	}
981
+
982
+	/**
983
+	 *  Gets the number of update errors since importer was instantiated or reset
984
+	 *
985
+	 * @return int
986
+	 */
987
+	public function get_total_update_errors()
988
+	{
989
+		return $this->_total_update_errors;
990
+	}
991 991
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Question.class.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -371,7 +371,7 @@  discard block
 block discarded – undo
371 371
      * Question, that relationship will be overwritten.
372 372
      *
373 373
      * @param EE_Question_Option $option
374
-     * @return boolean success
374
+     * @return EE_Base_Class success
375 375
      */
376 376
     public function add_option(EE_Question_Option $option)
377 377
     {
@@ -396,7 +396,7 @@  discard block
 block discarded – undo
396 396
      * Marks the option as deleted.
397 397
      *
398 398
      * @param EE_Question_Option $option
399
-     * @return boolean success
399
+     * @return EE_Base_Class success
400 400
      */
401 401
     public function remove_option(EE_Question_Option $option)
402 402
     {
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -335,7 +335,7 @@  discard block
 block discarded – undo
335 335
      */
336 336
     public function options($notDeletedOptionsOnly = true, $selected_value_to_always_include = null)
337 337
     {
338
-        if (! $this->ID()) {
338
+        if ( ! $this->ID()) {
339 339
             return array();
340 340
         }
341 341
         $query_params = array();
@@ -509,7 +509,7 @@  discard block
 block discarded – undo
509 509
             ),
510 510
             $input_constructor_args
511 511
         );
512
-        if (! $answer instanceof EE_Answer && $registration instanceof EE_Registration) {
512
+        if ( ! $answer instanceof EE_Answer && $registration instanceof EE_Registration) {
513 513
             $answer = EEM_Answer::instance()->get_registration_question_answer_object($registration, $this->ID());
514 514
         }
515 515
         // has this question been answered ?
@@ -647,7 +647,7 @@  discard block
 block discarded – undo
647 647
                     $this,
648 648
                     $input_constructor_args
649 649
                 );
650
-                if (! $default_input) {
650
+                if ( ! $default_input) {
651 651
                     $default_input = new EE_Text_Input($input_constructor_args);
652 652
                 }
653 653
                 $result = $default_input;
Please login to merge, or discard this patch.
Indentation   +664 added lines, -664 removed lines patch added patch discarded remove patch
@@ -14,668 +14,668 @@
 block discarded – undo
14 14
 class EE_Question extends EE_Soft_Delete_Base_Class implements EEI_Duplicatable
15 15
 {
16 16
 
17
-    /**
18
-     *
19
-     * @param array  $props_n_values          incoming values
20
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
21
-     *                                        used.)
22
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
23
-     *                                        date_format and the second value is the time format
24
-     * @return EE_Question
25
-     */
26
-    public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array())
27
-    {
28
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
29
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
30
-    }
31
-
32
-
33
-    /**
34
-     * @param array  $props_n_values  incoming values from the database
35
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
36
-     *                                the website will be used.
37
-     * @return EE_Question
38
-     */
39
-    public static function new_instance_from_db($props_n_values = array(), $timezone = '')
40
-    {
41
-        return new self($props_n_values, true, $timezone);
42
-    }
43
-
44
-
45
-    /**
46
-     *        Set    Question display text
47
-     *
48
-     * @access        public
49
-     * @param string $QST_display_text
50
-     */
51
-    public function set_display_text($QST_display_text = '')
52
-    {
53
-        $this->set('QST_display_text', $QST_display_text);
54
-    }
55
-
56
-
57
-    /**
58
-     *        Set    Question admin text
59
-     *
60
-     * @access        public
61
-     * @param        string $QST_admin_label
62
-     */
63
-    public function set_admin_label($QST_admin_label = '')
64
-    {
65
-        $this->set('QST_admin_label', $QST_admin_label);
66
-    }
67
-
68
-
69
-    /**
70
-     *        Set    system name
71
-     *
72
-     * @access        public
73
-     * @param        mixed $QST_system
74
-     */
75
-    public function set_system_ID($QST_system = '')
76
-    {
77
-        $this->set('QST_system', $QST_system);
78
-    }
79
-
80
-
81
-    /**
82
-     *        Set    question's type
83
-     *
84
-     * @access        public
85
-     * @param        string $QST_type
86
-     */
87
-    public function set_question_type($QST_type = '')
88
-    {
89
-        $this->set('QST_type', $QST_type);
90
-    }
91
-
92
-
93
-    /**
94
-     *        Sets whether this question must be answered when presented in a form
95
-     *
96
-     * @access        public
97
-     * @param        bool $QST_required
98
-     */
99
-    public function set_required($QST_required = false)
100
-    {
101
-        $this->set('QST_required', $QST_required);
102
-    }
103
-
104
-
105
-    /**
106
-     *        Set    Question display text
107
-     *
108
-     * @access        public
109
-     * @param        string $QST_required_text
110
-     */
111
-    public function set_required_text($QST_required_text = '')
112
-    {
113
-        $this->set('QST_required_text', $QST_required_text);
114
-    }
115
-
116
-
117
-    /**
118
-     *        Sets the order of this question when placed in a sequence of questions
119
-     *
120
-     * @access        public
121
-     * @param        int $QST_order
122
-     */
123
-    public function set_order($QST_order = 0)
124
-    {
125
-        $this->set('QST_order', $QST_order);
126
-    }
127
-
128
-
129
-    /**
130
-     *        Sets whether the question is admin-only
131
-     *
132
-     * @access        public
133
-     * @param        bool $QST_admin_only
134
-     */
135
-    public function set_admin_only($QST_admin_only = false)
136
-    {
137
-        $this->set('QST_admin_only', $QST_admin_only);
138
-    }
139
-
140
-
141
-    /**
142
-     *        Sets the wordpress user ID on the question
143
-     *
144
-     * @access        public
145
-     * @param        int $QST_wp_user
146
-     */
147
-    public function set_wp_user($QST_wp_user = 1)
148
-    {
149
-        $this->set('QST_wp_user', $QST_wp_user);
150
-    }
151
-
152
-
153
-    /**
154
-     *        Sets whether the question has been deleted
155
-     *        (we use this boolean instead of actually
156
-     *        deleting it because when users delete this question
157
-     *        they really want to remove the question from future
158
-     *        forms, BUT keep their old answers which depend
159
-     *        on this record actually existing.
160
-     *
161
-     * @access        public
162
-     * @param    bool $QST_deleted
163
-     */
164
-    public function set_deleted($QST_deleted = false)
165
-    {
166
-        $this->set('QST_deleted', $QST_deleted);
167
-    }
168
-
169
-
170
-    /**
171
-     * returns the text for displaying the question to users
172
-     *
173
-     * @access public
174
-     * @return string
175
-     */
176
-    public function display_text()
177
-    {
178
-        return $this->get('QST_display_text');
179
-    }
180
-
181
-
182
-    /**
183
-     * returns the text for the administrative label
184
-     *
185
-     * @access public
186
-     * @return string
187
-     */
188
-    public function admin_label()
189
-    {
190
-        return $this->get('QST_admin_label');
191
-    }
192
-
193
-
194
-    /**
195
-     * returns the attendee column name for this question
196
-     *
197
-     * @access public
198
-     * @return string
199
-     */
200
-    public function system_ID()
201
-    {
202
-        return $this->get('QST_system');
203
-    }
204
-
205
-
206
-    /**
207
-     * returns either a string of 'text', 'textfield', etc.
208
-     *
209
-     * @access public
210
-     * @return boolean
211
-     */
212
-    public function required()
213
-    {
214
-        return $this->get('QST_required');
215
-    }
216
-
217
-
218
-    /**
219
-     * returns the text which should be displayed when a user
220
-     * doesn't answer this question in a form
221
-     *
222
-     * @access public
223
-     * @return string
224
-     */
225
-    public function required_text()
226
-    {
227
-        return $this->get('QST_required_text');
228
-    }
229
-
230
-
231
-    /**
232
-     * returns the type of this question
233
-     *
234
-     * @access public
235
-     * @return string
236
-     */
237
-    public function type()
238
-    {
239
-        return $this->get('QST_type');
240
-    }
241
-
242
-
243
-    /**
244
-     * returns an integer showing where this question should
245
-     * be placed in a sequence of questions
246
-     *
247
-     * @access public
248
-     * @return int
249
-     */
250
-    public function order()
251
-    {
252
-        return $this->get('QST_order');
253
-    }
254
-
255
-
256
-    /**
257
-     * returns whether this question should only appears to admins,
258
-     * or to everyone
259
-     *
260
-     * @access public
261
-     * @return boolean
262
-     */
263
-    public function admin_only()
264
-    {
265
-        return $this->get('QST_admin_only');
266
-    }
267
-
268
-
269
-    /**
270
-     * returns the id the wordpress user who created this question
271
-     *
272
-     * @access public
273
-     * @return int
274
-     */
275
-    public function wp_user()
276
-    {
277
-        return $this->get('QST_wp_user');
278
-    }
279
-
280
-
281
-    /**
282
-     * returns whether this question has been marked as 'deleted'
283
-     *
284
-     * @access public
285
-     * @return boolean
286
-     */
287
-    public function deleted()
288
-    {
289
-        return $this->get('QST_deleted');
290
-    }
291
-
292
-
293
-    /**
294
-     * Gets an array of related EE_Answer  to this EE_Question
295
-     *
296
-     * @return EE_Answer[]
297
-     */
298
-    public function answers()
299
-    {
300
-        return $this->get_many_related('Answer');
301
-    }
302
-
303
-
304
-    /**
305
-     * Boolean check for if there are answers on this question in th db
306
-     *
307
-     * @return boolean true = has answers, false = no answers.
308
-     */
309
-    public function has_answers()
310
-    {
311
-        return $this->count_related('Answer') > 0 ? true : false;
312
-    }
313
-
314
-
315
-    /**
316
-     * gets an array of EE_Question_Group which relate to this question
317
-     *
318
-     * @return EE_Question_Group[]
319
-     */
320
-    public function question_groups()
321
-    {
322
-        return $this->get_many_related('Question_Group');
323
-    }
324
-
325
-
326
-    /**
327
-     * Returns all the options for this question. By default, it returns only the not-yet-deleted ones.
328
-     *
329
-     * @param boolean      $notDeletedOptionsOnly            1
330
-     *                                                       whether to return ALL options, or only the ones which have
331
-     *                                                       not yet been deleleted
332
-     * @param string|array $selected_value_to_always_include , when retrieving options to an ANSWERED question,
333
-     *                                                       we want to usually only show non-deleted options AND the
334
-     *                                                       value that was selected for the answer, whether it was
335
-     *                                                       trashed or not.
336
-     * @return EE_Question_Option[]
337
-     */
338
-    public function options($notDeletedOptionsOnly = true, $selected_value_to_always_include = null)
339
-    {
340
-        if (! $this->ID()) {
341
-            return array();
342
-        }
343
-        $query_params = array();
344
-        if ($selected_value_to_always_include) {
345
-            if (is_array($selected_value_to_always_include)) {
346
-                $query_params[0]['OR*options-query']['QSO_value'] = array('IN', $selected_value_to_always_include);
347
-            } else {
348
-                $query_params[0]['OR*options-query']['QSO_value'] = $selected_value_to_always_include;
349
-            }
350
-        }
351
-        if ($notDeletedOptionsOnly) {
352
-            $query_params[0]['OR*options-query']['QSO_deleted'] = false;
353
-        }
354
-        // order by QSO_order
355
-        $query_params['order_by'] = array('QSO_order' => 'ASC');
356
-        return $this->get_many_related('Question_Option', $query_params);
357
-    }
358
-
359
-
360
-    /**
361
-     * returns an array of EE_Question_Options which relate to this question
362
-     *
363
-     * @return \EE_Question_Option[]
364
-     */
365
-    public function temp_options()
366
-    {
367
-        return $this->_model_relations['Question_Option'];
368
-    }
369
-
370
-
371
-    /**
372
-     * Adds an option for this question. Note: if the option were previously associated with a different
373
-     * Question, that relationship will be overwritten.
374
-     *
375
-     * @param EE_Question_Option $option
376
-     * @return boolean success
377
-     */
378
-    public function add_option(EE_Question_Option $option)
379
-    {
380
-        return $this->_add_relation_to($option, 'Question_Option');
381
-    }
382
-
383
-
384
-    /**
385
-     * Adds an option directly to this question without saving to the db
386
-     *
387
-     * @param EE_Question_Option $option
388
-     * @return boolean success
389
-     */
390
-    public function add_temp_option(EE_Question_Option $option)
391
-    {
392
-        $this->_model_relations['Question_Option'][] = $option;
393
-        return true;
394
-    }
395
-
396
-
397
-    /**
398
-     * Marks the option as deleted.
399
-     *
400
-     * @param EE_Question_Option $option
401
-     * @return boolean success
402
-     */
403
-    public function remove_option(EE_Question_Option $option)
404
-    {
405
-        return $this->_remove_relation_to($option, 'Question_Option');
406
-    }
407
-
408
-
409
-    /**
410
-     * @return bool
411
-     */
412
-    public function is_system_question()
413
-    {
414
-        $system_ID = $this->get('QST_system');
415
-        return ! empty($system_ID) ? true : false;
416
-    }
417
-
418
-
419
-    /**
420
-     * The purpose of this method is set the question order this question order to be the max out of all questions
421
-     *
422
-     * @access public
423
-     * @return void
424
-     */
425
-    public function set_order_to_latest()
426
-    {
427
-        $latest_order = $this->get_model()->get_latest_question_order();
428
-        $latest_order++;
429
-        $this->set('QST_order', $latest_order);
430
-    }
431
-
432
-
433
-    /**
434
-     * Retrieves the list of allowed question types from the model.
435
-     *
436
-     * @return string[]
437
-     */
438
-    private function _allowed_question_types()
439
-    {
440
-        $questionModel = $this->get_model();
441
-        /* @var $questionModel EEM_Question */
442
-        return $questionModel->allowed_question_types();
443
-    }
444
-
445
-    /**
446
-     * Duplicates this question and its question options
447
-     *
448
-     * @return \EE_Question
449
-     */
450
-    public function duplicate($options = array())
451
-    {
452
-        $new_question = clone $this;
453
-        $new_question->set('QST_ID', null);
454
-        $new_question->set_display_text(sprintf(__('%s **Duplicate**', 'event_espresso'), $this->display_text()));
455
-        $new_question->set_admin_label(sprintf(__('%s **Duplicate**', 'event_espresso'), $this->admin_label()));
456
-        $new_question->set_system_ID(null);
457
-        $new_question->set_wp_user(get_current_user_id());
458
-        // if we're duplicating a trashed question, assume we don't want the new one to be trashed
459
-        $new_question->set_deleted(false);
460
-        $success = $new_question->save();
461
-        if ($success) {
462
-            // we don't totally want to duplicate the question options, because we want them to be for the NEW question
463
-            foreach ($this->options() as $question_option) {
464
-                $question_option->duplicate(array('QST_ID' => $new_question->ID()));
465
-            }
466
-            return $new_question;
467
-        } else {
468
-            return null;
469
-        }
470
-    }
471
-
472
-    /**
473
-     * Returns the question's maximum allowed response size
474
-     *
475
-     * @return int|float
476
-     */
477
-    public function max()
478
-    {
479
-        return $this->get('QST_max');
480
-    }
481
-
482
-    /**
483
-     * Sets the question's maximum allowed response size
484
-     *
485
-     * @param int|float $new_max
486
-     * @return void
487
-     */
488
-    public function set_max($new_max)
489
-    {
490
-        $this->set('QST_max', $new_max);
491
-    }
492
-
493
-
494
-    /**
495
-     * Creates a form input from this question which can be used in HTML forms
496
-     *
497
-     * @param EE_Registration $registration
498
-     * @param EE_Answer       $answer
499
-     * @param array           $input_constructor_args
500
-     * @return EE_Form_Input_Base
501
-     */
502
-    public function generate_form_input($registration = null, $answer = null, $input_constructor_args = array())
503
-    {
504
-        $identifier = $this->is_system_question() ? $this->system_ID() : $this->ID();
505
-
506
-        $input_constructor_args = array_merge(
507
-            array(
508
-                'required'                          => $this->required() ? true : false,
509
-                'html_label_text'                   => $this->display_text(),
510
-                'required_validation_error_message' => $this->required_text(),
511
-            ),
512
-            $input_constructor_args
513
-        );
514
-        if (! $answer instanceof EE_Answer && $registration instanceof EE_Registration) {
515
-            $answer = EEM_Answer::instance()->get_registration_question_answer_object($registration, $this->ID());
516
-        }
517
-        // has this question been answered ?
518
-        if (
519
-            $answer instanceof EE_Answer
520
-            && $answer->value() !== ''
521
-        ) {
522
-            // answer gets htmlspecialchars called on it, undo that please
523
-            // because the form input's display strategy may call esc_attr too
524
-            // which also does html special characters
525
-            $values_with_html_special_chars = $answer->value();
526
-            if (is_array($values_with_html_special_chars)) {
527
-                $default_value = array_map('htmlspecialchars_decode', $values_with_html_special_chars);
528
-            } else {
529
-                $default_value = htmlspecialchars_decode($values_with_html_special_chars);
530
-            }
531
-            $input_constructor_args['default'] = $default_value;
532
-        }
533
-        $max_max_for_question = EEM_Question::instance()->absolute_max_for_system_question($this->system_ID());
534
-        if (
535
-            in_array(
536
-                $this->type(),
537
-                EEM_Question::instance()->questionTypesWithMaxLength(),
538
-                true
539
-            )
540
-        ) {
541
-            $input_constructor_args['validation_strategies'][] = new EE_Max_Length_Validation_Strategy(
542
-                null,
543
-                min($max_max_for_question, $this->max())
544
-            );
545
-        }
546
-        $input_constructor_args = apply_filters(
547
-            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__input_constructor_args',
548
-            $input_constructor_args,
549
-            $registration,
550
-            $this,
551
-            $answer
552
-        );
553
-
554
-        $result = null;
555
-        switch ($this->type()) {
556
-            // Text
557
-            case EEM_Question::QST_type_text:
558
-                $result = new EE_Text_Input($input_constructor_args);
559
-                break;
560
-            // Textarea
561
-            case EEM_Question::QST_type_textarea:
562
-                $result = new EE_Text_Area_Input($input_constructor_args);
563
-                break;
564
-            // Radio Buttons
565
-            case EEM_Question::QST_type_radio:
566
-                $result = new EE_Radio_Button_Input($this->options(), $input_constructor_args);
567
-                break;
568
-            // Dropdown
569
-            case EEM_Question::QST_type_dropdown:
570
-                $result = new EE_Select_Input($this->options(), $input_constructor_args);
571
-                break;
572
-            // State Dropdown
573
-            case EEM_Question::QST_type_state:
574
-                $state_options = apply_filters(
575
-                    'FHEE__EE_Question__generate_form_input__state_options',
576
-                    null,
577
-                    $this,
578
-                    $registration,
579
-                    $answer
580
-                );
581
-                $result = new EE_State_Select_Input($state_options, $input_constructor_args);
582
-                break;
583
-            // Country Dropdown
584
-            case EEM_Question::QST_type_country:
585
-                $country_options = apply_filters(
586
-                    'FHEE__EE_Question__generate_form_input__country_options',
587
-                    null,
588
-                    $this,
589
-                    $registration,
590
-                    $answer
591
-                );
592
-                $result = new EE_Country_Select_Input($country_options, $input_constructor_args);
593
-                break;
594
-            // Checkboxes
595
-            case EEM_Question::QST_type_checkbox:
596
-                $result = new EE_Checkbox_Multi_Input($this->options(), $input_constructor_args);
597
-                break;
598
-            // Date
599
-            case EEM_Question::QST_type_date:
600
-                $result = new EE_Datepicker_Input($input_constructor_args);
601
-                break;
602
-            case EEM_Question::QST_type_html_textarea:
603
-                $input_constructor_args['validation_strategies'][] = new EE_Simple_HTML_Validation_Strategy();
604
-                $result = new EE_Text_Area_Input($input_constructor_args);
605
-                $result->remove_validation_strategy('EE_Plaintext_Validation_Strategy');
606
-                break;
607
-            case EEM_Question::QST_type_email:
608
-                    $result = new EE_Email_Input($input_constructor_args);
609
-                break;
610
-            // Email confirm
611
-            case EEM_Question::QST_type_email_confirm:
612
-                $result = new EE_Email_Confirm_Input($input_constructor_args);
613
-                break;
614
-            case EEM_Question::QST_type_us_phone:
615
-                $result = new EE_Phone_Input($input_constructor_args);
616
-                break;
617
-            case EEM_Question::QST_type_int:
618
-                $result = new EE_Integer_Input($input_constructor_args);
619
-                break;
620
-            case EEM_Question::QST_type_decimal:
621
-                $result = new EE_Float_Input($input_constructor_args);
622
-                break;
623
-            case EEM_Question::QST_type_url:
624
-                $input_constructor_args['validation_strategies'][] = LoaderFactory::getLoader()->getNew('EE_URL_Validation_Strategy');
625
-                $result = new EE_Text_Input($input_constructor_args);
626
-                break;
627
-            case EEM_Question::QST_type_year:
628
-                $result = new EE_Year_Input(
629
-                    $input_constructor_args,
630
-                    apply_filters(
631
-                        'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__year_question__four_digit',
632
-                        true,
633
-                        $this
634
-                    ),
635
-                    apply_filters(
636
-                        'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__year_question__early_range',
637
-                        100,
638
-                        $this
639
-                    ),
640
-                    apply_filters(
641
-                        'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__year_question__end_range',
642
-                        100,
643
-                        $this
644
-                    )
645
-                );
646
-                break;
647
-            case EEM_Question::QST_type_multi_select:
648
-                $result = new EE_Select_Multiple_Input($this->options(), $input_constructor_args);
649
-                break;
650
-            // fallback
651
-            default:
652
-                $default_input = apply_filters(
653
-                    'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__default',
654
-                    null,
655
-                    $this->type(),
656
-                    $this,
657
-                    $input_constructor_args
658
-                );
659
-                if (! $default_input) {
660
-                    $default_input = new EE_Text_Input($input_constructor_args);
661
-                }
662
-                $result = $default_input;
663
-        }
664
-        return apply_filters('FHEE__EE_Question__generate_form_input__return', $result, $registration, $this, $answer);
665
-    }
666
-
667
-
668
-    /**
669
-     * Returns whether or not this question type should have question option entries
670
-     *
671
-     * @return bool
672
-     */
673
-    public function should_have_question_options()
674
-    {
675
-        return in_array(
676
-            $this->type(),
677
-            $this->_model->question_types_with_options(),
678
-            true
679
-        );
680
-    }
17
+	/**
18
+	 *
19
+	 * @param array  $props_n_values          incoming values
20
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
21
+	 *                                        used.)
22
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
23
+	 *                                        date_format and the second value is the time format
24
+	 * @return EE_Question
25
+	 */
26
+	public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array())
27
+	{
28
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
29
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
30
+	}
31
+
32
+
33
+	/**
34
+	 * @param array  $props_n_values  incoming values from the database
35
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
36
+	 *                                the website will be used.
37
+	 * @return EE_Question
38
+	 */
39
+	public static function new_instance_from_db($props_n_values = array(), $timezone = '')
40
+	{
41
+		return new self($props_n_values, true, $timezone);
42
+	}
43
+
44
+
45
+	/**
46
+	 *        Set    Question display text
47
+	 *
48
+	 * @access        public
49
+	 * @param string $QST_display_text
50
+	 */
51
+	public function set_display_text($QST_display_text = '')
52
+	{
53
+		$this->set('QST_display_text', $QST_display_text);
54
+	}
55
+
56
+
57
+	/**
58
+	 *        Set    Question admin text
59
+	 *
60
+	 * @access        public
61
+	 * @param        string $QST_admin_label
62
+	 */
63
+	public function set_admin_label($QST_admin_label = '')
64
+	{
65
+		$this->set('QST_admin_label', $QST_admin_label);
66
+	}
67
+
68
+
69
+	/**
70
+	 *        Set    system name
71
+	 *
72
+	 * @access        public
73
+	 * @param        mixed $QST_system
74
+	 */
75
+	public function set_system_ID($QST_system = '')
76
+	{
77
+		$this->set('QST_system', $QST_system);
78
+	}
79
+
80
+
81
+	/**
82
+	 *        Set    question's type
83
+	 *
84
+	 * @access        public
85
+	 * @param        string $QST_type
86
+	 */
87
+	public function set_question_type($QST_type = '')
88
+	{
89
+		$this->set('QST_type', $QST_type);
90
+	}
91
+
92
+
93
+	/**
94
+	 *        Sets whether this question must be answered when presented in a form
95
+	 *
96
+	 * @access        public
97
+	 * @param        bool $QST_required
98
+	 */
99
+	public function set_required($QST_required = false)
100
+	{
101
+		$this->set('QST_required', $QST_required);
102
+	}
103
+
104
+
105
+	/**
106
+	 *        Set    Question display text
107
+	 *
108
+	 * @access        public
109
+	 * @param        string $QST_required_text
110
+	 */
111
+	public function set_required_text($QST_required_text = '')
112
+	{
113
+		$this->set('QST_required_text', $QST_required_text);
114
+	}
115
+
116
+
117
+	/**
118
+	 *        Sets the order of this question when placed in a sequence of questions
119
+	 *
120
+	 * @access        public
121
+	 * @param        int $QST_order
122
+	 */
123
+	public function set_order($QST_order = 0)
124
+	{
125
+		$this->set('QST_order', $QST_order);
126
+	}
127
+
128
+
129
+	/**
130
+	 *        Sets whether the question is admin-only
131
+	 *
132
+	 * @access        public
133
+	 * @param        bool $QST_admin_only
134
+	 */
135
+	public function set_admin_only($QST_admin_only = false)
136
+	{
137
+		$this->set('QST_admin_only', $QST_admin_only);
138
+	}
139
+
140
+
141
+	/**
142
+	 *        Sets the wordpress user ID on the question
143
+	 *
144
+	 * @access        public
145
+	 * @param        int $QST_wp_user
146
+	 */
147
+	public function set_wp_user($QST_wp_user = 1)
148
+	{
149
+		$this->set('QST_wp_user', $QST_wp_user);
150
+	}
151
+
152
+
153
+	/**
154
+	 *        Sets whether the question has been deleted
155
+	 *        (we use this boolean instead of actually
156
+	 *        deleting it because when users delete this question
157
+	 *        they really want to remove the question from future
158
+	 *        forms, BUT keep their old answers which depend
159
+	 *        on this record actually existing.
160
+	 *
161
+	 * @access        public
162
+	 * @param    bool $QST_deleted
163
+	 */
164
+	public function set_deleted($QST_deleted = false)
165
+	{
166
+		$this->set('QST_deleted', $QST_deleted);
167
+	}
168
+
169
+
170
+	/**
171
+	 * returns the text for displaying the question to users
172
+	 *
173
+	 * @access public
174
+	 * @return string
175
+	 */
176
+	public function display_text()
177
+	{
178
+		return $this->get('QST_display_text');
179
+	}
180
+
181
+
182
+	/**
183
+	 * returns the text for the administrative label
184
+	 *
185
+	 * @access public
186
+	 * @return string
187
+	 */
188
+	public function admin_label()
189
+	{
190
+		return $this->get('QST_admin_label');
191
+	}
192
+
193
+
194
+	/**
195
+	 * returns the attendee column name for this question
196
+	 *
197
+	 * @access public
198
+	 * @return string
199
+	 */
200
+	public function system_ID()
201
+	{
202
+		return $this->get('QST_system');
203
+	}
204
+
205
+
206
+	/**
207
+	 * returns either a string of 'text', 'textfield', etc.
208
+	 *
209
+	 * @access public
210
+	 * @return boolean
211
+	 */
212
+	public function required()
213
+	{
214
+		return $this->get('QST_required');
215
+	}
216
+
217
+
218
+	/**
219
+	 * returns the text which should be displayed when a user
220
+	 * doesn't answer this question in a form
221
+	 *
222
+	 * @access public
223
+	 * @return string
224
+	 */
225
+	public function required_text()
226
+	{
227
+		return $this->get('QST_required_text');
228
+	}
229
+
230
+
231
+	/**
232
+	 * returns the type of this question
233
+	 *
234
+	 * @access public
235
+	 * @return string
236
+	 */
237
+	public function type()
238
+	{
239
+		return $this->get('QST_type');
240
+	}
241
+
242
+
243
+	/**
244
+	 * returns an integer showing where this question should
245
+	 * be placed in a sequence of questions
246
+	 *
247
+	 * @access public
248
+	 * @return int
249
+	 */
250
+	public function order()
251
+	{
252
+		return $this->get('QST_order');
253
+	}
254
+
255
+
256
+	/**
257
+	 * returns whether this question should only appears to admins,
258
+	 * or to everyone
259
+	 *
260
+	 * @access public
261
+	 * @return boolean
262
+	 */
263
+	public function admin_only()
264
+	{
265
+		return $this->get('QST_admin_only');
266
+	}
267
+
268
+
269
+	/**
270
+	 * returns the id the wordpress user who created this question
271
+	 *
272
+	 * @access public
273
+	 * @return int
274
+	 */
275
+	public function wp_user()
276
+	{
277
+		return $this->get('QST_wp_user');
278
+	}
279
+
280
+
281
+	/**
282
+	 * returns whether this question has been marked as 'deleted'
283
+	 *
284
+	 * @access public
285
+	 * @return boolean
286
+	 */
287
+	public function deleted()
288
+	{
289
+		return $this->get('QST_deleted');
290
+	}
291
+
292
+
293
+	/**
294
+	 * Gets an array of related EE_Answer  to this EE_Question
295
+	 *
296
+	 * @return EE_Answer[]
297
+	 */
298
+	public function answers()
299
+	{
300
+		return $this->get_many_related('Answer');
301
+	}
302
+
303
+
304
+	/**
305
+	 * Boolean check for if there are answers on this question in th db
306
+	 *
307
+	 * @return boolean true = has answers, false = no answers.
308
+	 */
309
+	public function has_answers()
310
+	{
311
+		return $this->count_related('Answer') > 0 ? true : false;
312
+	}
313
+
314
+
315
+	/**
316
+	 * gets an array of EE_Question_Group which relate to this question
317
+	 *
318
+	 * @return EE_Question_Group[]
319
+	 */
320
+	public function question_groups()
321
+	{
322
+		return $this->get_many_related('Question_Group');
323
+	}
324
+
325
+
326
+	/**
327
+	 * Returns all the options for this question. By default, it returns only the not-yet-deleted ones.
328
+	 *
329
+	 * @param boolean      $notDeletedOptionsOnly            1
330
+	 *                                                       whether to return ALL options, or only the ones which have
331
+	 *                                                       not yet been deleleted
332
+	 * @param string|array $selected_value_to_always_include , when retrieving options to an ANSWERED question,
333
+	 *                                                       we want to usually only show non-deleted options AND the
334
+	 *                                                       value that was selected for the answer, whether it was
335
+	 *                                                       trashed or not.
336
+	 * @return EE_Question_Option[]
337
+	 */
338
+	public function options($notDeletedOptionsOnly = true, $selected_value_to_always_include = null)
339
+	{
340
+		if (! $this->ID()) {
341
+			return array();
342
+		}
343
+		$query_params = array();
344
+		if ($selected_value_to_always_include) {
345
+			if (is_array($selected_value_to_always_include)) {
346
+				$query_params[0]['OR*options-query']['QSO_value'] = array('IN', $selected_value_to_always_include);
347
+			} else {
348
+				$query_params[0]['OR*options-query']['QSO_value'] = $selected_value_to_always_include;
349
+			}
350
+		}
351
+		if ($notDeletedOptionsOnly) {
352
+			$query_params[0]['OR*options-query']['QSO_deleted'] = false;
353
+		}
354
+		// order by QSO_order
355
+		$query_params['order_by'] = array('QSO_order' => 'ASC');
356
+		return $this->get_many_related('Question_Option', $query_params);
357
+	}
358
+
359
+
360
+	/**
361
+	 * returns an array of EE_Question_Options which relate to this question
362
+	 *
363
+	 * @return \EE_Question_Option[]
364
+	 */
365
+	public function temp_options()
366
+	{
367
+		return $this->_model_relations['Question_Option'];
368
+	}
369
+
370
+
371
+	/**
372
+	 * Adds an option for this question. Note: if the option were previously associated with a different
373
+	 * Question, that relationship will be overwritten.
374
+	 *
375
+	 * @param EE_Question_Option $option
376
+	 * @return boolean success
377
+	 */
378
+	public function add_option(EE_Question_Option $option)
379
+	{
380
+		return $this->_add_relation_to($option, 'Question_Option');
381
+	}
382
+
383
+
384
+	/**
385
+	 * Adds an option directly to this question without saving to the db
386
+	 *
387
+	 * @param EE_Question_Option $option
388
+	 * @return boolean success
389
+	 */
390
+	public function add_temp_option(EE_Question_Option $option)
391
+	{
392
+		$this->_model_relations['Question_Option'][] = $option;
393
+		return true;
394
+	}
395
+
396
+
397
+	/**
398
+	 * Marks the option as deleted.
399
+	 *
400
+	 * @param EE_Question_Option $option
401
+	 * @return boolean success
402
+	 */
403
+	public function remove_option(EE_Question_Option $option)
404
+	{
405
+		return $this->_remove_relation_to($option, 'Question_Option');
406
+	}
407
+
408
+
409
+	/**
410
+	 * @return bool
411
+	 */
412
+	public function is_system_question()
413
+	{
414
+		$system_ID = $this->get('QST_system');
415
+		return ! empty($system_ID) ? true : false;
416
+	}
417
+
418
+
419
+	/**
420
+	 * The purpose of this method is set the question order this question order to be the max out of all questions
421
+	 *
422
+	 * @access public
423
+	 * @return void
424
+	 */
425
+	public function set_order_to_latest()
426
+	{
427
+		$latest_order = $this->get_model()->get_latest_question_order();
428
+		$latest_order++;
429
+		$this->set('QST_order', $latest_order);
430
+	}
431
+
432
+
433
+	/**
434
+	 * Retrieves the list of allowed question types from the model.
435
+	 *
436
+	 * @return string[]
437
+	 */
438
+	private function _allowed_question_types()
439
+	{
440
+		$questionModel = $this->get_model();
441
+		/* @var $questionModel EEM_Question */
442
+		return $questionModel->allowed_question_types();
443
+	}
444
+
445
+	/**
446
+	 * Duplicates this question and its question options
447
+	 *
448
+	 * @return \EE_Question
449
+	 */
450
+	public function duplicate($options = array())
451
+	{
452
+		$new_question = clone $this;
453
+		$new_question->set('QST_ID', null);
454
+		$new_question->set_display_text(sprintf(__('%s **Duplicate**', 'event_espresso'), $this->display_text()));
455
+		$new_question->set_admin_label(sprintf(__('%s **Duplicate**', 'event_espresso'), $this->admin_label()));
456
+		$new_question->set_system_ID(null);
457
+		$new_question->set_wp_user(get_current_user_id());
458
+		// if we're duplicating a trashed question, assume we don't want the new one to be trashed
459
+		$new_question->set_deleted(false);
460
+		$success = $new_question->save();
461
+		if ($success) {
462
+			// we don't totally want to duplicate the question options, because we want them to be for the NEW question
463
+			foreach ($this->options() as $question_option) {
464
+				$question_option->duplicate(array('QST_ID' => $new_question->ID()));
465
+			}
466
+			return $new_question;
467
+		} else {
468
+			return null;
469
+		}
470
+	}
471
+
472
+	/**
473
+	 * Returns the question's maximum allowed response size
474
+	 *
475
+	 * @return int|float
476
+	 */
477
+	public function max()
478
+	{
479
+		return $this->get('QST_max');
480
+	}
481
+
482
+	/**
483
+	 * Sets the question's maximum allowed response size
484
+	 *
485
+	 * @param int|float $new_max
486
+	 * @return void
487
+	 */
488
+	public function set_max($new_max)
489
+	{
490
+		$this->set('QST_max', $new_max);
491
+	}
492
+
493
+
494
+	/**
495
+	 * Creates a form input from this question which can be used in HTML forms
496
+	 *
497
+	 * @param EE_Registration $registration
498
+	 * @param EE_Answer       $answer
499
+	 * @param array           $input_constructor_args
500
+	 * @return EE_Form_Input_Base
501
+	 */
502
+	public function generate_form_input($registration = null, $answer = null, $input_constructor_args = array())
503
+	{
504
+		$identifier = $this->is_system_question() ? $this->system_ID() : $this->ID();
505
+
506
+		$input_constructor_args = array_merge(
507
+			array(
508
+				'required'                          => $this->required() ? true : false,
509
+				'html_label_text'                   => $this->display_text(),
510
+				'required_validation_error_message' => $this->required_text(),
511
+			),
512
+			$input_constructor_args
513
+		);
514
+		if (! $answer instanceof EE_Answer && $registration instanceof EE_Registration) {
515
+			$answer = EEM_Answer::instance()->get_registration_question_answer_object($registration, $this->ID());
516
+		}
517
+		// has this question been answered ?
518
+		if (
519
+			$answer instanceof EE_Answer
520
+			&& $answer->value() !== ''
521
+		) {
522
+			// answer gets htmlspecialchars called on it, undo that please
523
+			// because the form input's display strategy may call esc_attr too
524
+			// which also does html special characters
525
+			$values_with_html_special_chars = $answer->value();
526
+			if (is_array($values_with_html_special_chars)) {
527
+				$default_value = array_map('htmlspecialchars_decode', $values_with_html_special_chars);
528
+			} else {
529
+				$default_value = htmlspecialchars_decode($values_with_html_special_chars);
530
+			}
531
+			$input_constructor_args['default'] = $default_value;
532
+		}
533
+		$max_max_for_question = EEM_Question::instance()->absolute_max_for_system_question($this->system_ID());
534
+		if (
535
+			in_array(
536
+				$this->type(),
537
+				EEM_Question::instance()->questionTypesWithMaxLength(),
538
+				true
539
+			)
540
+		) {
541
+			$input_constructor_args['validation_strategies'][] = new EE_Max_Length_Validation_Strategy(
542
+				null,
543
+				min($max_max_for_question, $this->max())
544
+			);
545
+		}
546
+		$input_constructor_args = apply_filters(
547
+			'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__input_constructor_args',
548
+			$input_constructor_args,
549
+			$registration,
550
+			$this,
551
+			$answer
552
+		);
553
+
554
+		$result = null;
555
+		switch ($this->type()) {
556
+			// Text
557
+			case EEM_Question::QST_type_text:
558
+				$result = new EE_Text_Input($input_constructor_args);
559
+				break;
560
+			// Textarea
561
+			case EEM_Question::QST_type_textarea:
562
+				$result = new EE_Text_Area_Input($input_constructor_args);
563
+				break;
564
+			// Radio Buttons
565
+			case EEM_Question::QST_type_radio:
566
+				$result = new EE_Radio_Button_Input($this->options(), $input_constructor_args);
567
+				break;
568
+			// Dropdown
569
+			case EEM_Question::QST_type_dropdown:
570
+				$result = new EE_Select_Input($this->options(), $input_constructor_args);
571
+				break;
572
+			// State Dropdown
573
+			case EEM_Question::QST_type_state:
574
+				$state_options = apply_filters(
575
+					'FHEE__EE_Question__generate_form_input__state_options',
576
+					null,
577
+					$this,
578
+					$registration,
579
+					$answer
580
+				);
581
+				$result = new EE_State_Select_Input($state_options, $input_constructor_args);
582
+				break;
583
+			// Country Dropdown
584
+			case EEM_Question::QST_type_country:
585
+				$country_options = apply_filters(
586
+					'FHEE__EE_Question__generate_form_input__country_options',
587
+					null,
588
+					$this,
589
+					$registration,
590
+					$answer
591
+				);
592
+				$result = new EE_Country_Select_Input($country_options, $input_constructor_args);
593
+				break;
594
+			// Checkboxes
595
+			case EEM_Question::QST_type_checkbox:
596
+				$result = new EE_Checkbox_Multi_Input($this->options(), $input_constructor_args);
597
+				break;
598
+			// Date
599
+			case EEM_Question::QST_type_date:
600
+				$result = new EE_Datepicker_Input($input_constructor_args);
601
+				break;
602
+			case EEM_Question::QST_type_html_textarea:
603
+				$input_constructor_args['validation_strategies'][] = new EE_Simple_HTML_Validation_Strategy();
604
+				$result = new EE_Text_Area_Input($input_constructor_args);
605
+				$result->remove_validation_strategy('EE_Plaintext_Validation_Strategy');
606
+				break;
607
+			case EEM_Question::QST_type_email:
608
+					$result = new EE_Email_Input($input_constructor_args);
609
+				break;
610
+			// Email confirm
611
+			case EEM_Question::QST_type_email_confirm:
612
+				$result = new EE_Email_Confirm_Input($input_constructor_args);
613
+				break;
614
+			case EEM_Question::QST_type_us_phone:
615
+				$result = new EE_Phone_Input($input_constructor_args);
616
+				break;
617
+			case EEM_Question::QST_type_int:
618
+				$result = new EE_Integer_Input($input_constructor_args);
619
+				break;
620
+			case EEM_Question::QST_type_decimal:
621
+				$result = new EE_Float_Input($input_constructor_args);
622
+				break;
623
+			case EEM_Question::QST_type_url:
624
+				$input_constructor_args['validation_strategies'][] = LoaderFactory::getLoader()->getNew('EE_URL_Validation_Strategy');
625
+				$result = new EE_Text_Input($input_constructor_args);
626
+				break;
627
+			case EEM_Question::QST_type_year:
628
+				$result = new EE_Year_Input(
629
+					$input_constructor_args,
630
+					apply_filters(
631
+						'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__year_question__four_digit',
632
+						true,
633
+						$this
634
+					),
635
+					apply_filters(
636
+						'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__year_question__early_range',
637
+						100,
638
+						$this
639
+					),
640
+					apply_filters(
641
+						'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__year_question__end_range',
642
+						100,
643
+						$this
644
+					)
645
+				);
646
+				break;
647
+			case EEM_Question::QST_type_multi_select:
648
+				$result = new EE_Select_Multiple_Input($this->options(), $input_constructor_args);
649
+				break;
650
+			// fallback
651
+			default:
652
+				$default_input = apply_filters(
653
+					'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__default',
654
+					null,
655
+					$this->type(),
656
+					$this,
657
+					$input_constructor_args
658
+				);
659
+				if (! $default_input) {
660
+					$default_input = new EE_Text_Input($input_constructor_args);
661
+				}
662
+				$result = $default_input;
663
+		}
664
+		return apply_filters('FHEE__EE_Question__generate_form_input__return', $result, $registration, $this, $answer);
665
+	}
666
+
667
+
668
+	/**
669
+	 * Returns whether or not this question type should have question option entries
670
+	 *
671
+	 * @return bool
672
+	 */
673
+	public function should_have_question_options()
674
+	{
675
+		return in_array(
676
+			$this->type(),
677
+			$this->_model->question_types_with_options(),
678
+			true
679
+		);
680
+	}
681 681
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Question_Form_Input.class.php 3 patches
Doc Comments   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -241,7 +241,7 @@  discard block
 block discarded – undo
241 241
      *        generate_question_form_inputs_for_object
242 242
      *
243 243
      * @access    protected
244
-     * @param bool|object $object $object
244
+     * @param EE_Base_Class|null $object $object
245 245
      * @param    array    $input_types
246 246
      * @return        array
247 247
      */
@@ -354,7 +354,7 @@  discard block
 block discarded – undo
354 354
      *
355 355
      * @access public
356 356
      * @param \EE_Question_Option $QSO EE_Question_Option
357
-     * @return boolean
357
+     * @return boolean|null
358 358
      */
359 359
     public function add_temp_option(EE_Question_Option $QSO)
360 360
     {
@@ -367,8 +367,8 @@  discard block
 block discarded – undo
367 367
      *
368 368
      * @access public
369 369
      * @param    string $property
370
-     * @param    mixed  $value
371
-     * @return mixed
370
+     * @param    boolean  $value
371
+     * @return boolean|null
372 372
      */
373 373
     public function set($property = null, $value = null)
374 374
     {
@@ -416,7 +416,7 @@  discard block
 block discarded – undo
416 416
      *    get_meta
417 417
      *
418 418
      * @access public
419
-     * @param mixed $key
419
+     * @param string $key
420 420
      * @return mixed
421 421
      */
422 422
     public function get_meta($key = false)
Please login to merge, or discard this patch.
Indentation   +434 added lines, -434 removed lines patch added patch discarded remove patch
@@ -13,438 +13,438 @@
 block discarded – undo
13 13
 class EE_Question_Form_Input
14 14
 {
15 15
 
16
-    /**
17
-     *    EE_Question object
18
-     *
19
-     * @access private
20
-     * @var object
21
-     */
22
-    private $_QST = null;
23
-
24
-    /**
25
-     *    EE_Answer object
26
-     *
27
-     * @access private
28
-     * @var object
29
-     */
30
-    private $_ANS = null;
31
-
32
-    /**
33
-     *    $_QST_meta
34
-     * @access private
35
-     * @var array
36
-     */
37
-    private $_QST_meta = array();
38
-
39
-    /**
40
-     *    $QST_input_name
41
-     * @access private
42
-     * @var string
43
-     */
44
-    private $QST_input_name = '';
45
-
46
-    /**
47
-     *    $QST_input_id
48
-     * @access private
49
-     * @var string
50
-     */
51
-    private $QST_input_id = '';
52
-
53
-    /**
54
-     *    $QST_input_class
55
-     * @access private
56
-     * @var string
57
-     */
58
-    private $QST_input_class = '';
59
-
60
-    /**
61
-     * @var bool $QST_disabled
62
-     */
63
-    private $QST_disabled = false;
64
-
65
-
66
-    /**
67
-     * constructor for questions
68
-     *
69
-     * @param \EE_Question $QST EE_Question object
70
-     * @param \EE_Answer   $ANS EE_Answer object
71
-     * @param array        $q_meta
72
-     * @access public
73
-     * @return \EE_Question_Form_Input
74
-     */
75
-    public function __construct(EE_Question $QST = null, EE_Answer $ANS = null, $q_meta = array())
76
-    {
77
-        if (empty($QST) || empty($ANS)) {
78
-            EE_Error::add_error(
79
-                __('An error occurred. A valid EE_Question or EE_Answer object was not received.', 'event_espresso'),
80
-                __FILE__,
81
-                __FUNCTION__,
82
-                __LINE__
83
-            );
84
-            return null;
85
-        }
86
-        $this->_QST = $QST;
87
-        $this->_ANS = $ANS;
88
-        $this->set_question_form_input_meta($q_meta);
89
-        $this->set_question_form_input_init();
90
-    }
91
-
92
-
93
-    /**
94
-     * sets meta data for the question form input
95
-     *
96
-     * @access public
97
-     * @param array $q_meta
98
-     * @return void
99
-     */
100
-    public function set_question_form_input_meta($q_meta = array())
101
-    {
102
-        $default_q_meta = array(
103
-            'att_nmbr'       => 1,
104
-            'ticket_id'      => '',
105
-            'date'           => '',
106
-            'time'           => '',
107
-            'input_name'     => '',
108
-            'input_id'       => '',
109
-            'input_class'    => '',
110
-            'input_prefix'   => 'qstn',
111
-            'append_qstn_id' => true,
112
-            'htmlentities'   => true,
113
-            'allow_null'     => false,
114
-        );
115
-        $this->_QST_meta = array_merge($default_q_meta, $q_meta);
116
-    }
117
-
118
-
119
-    /**
120
-     * set_question_form_input_init
121
-     *
122
-     * @access public
123
-     * @return void
124
-     */
125
-    public function set_question_form_input_init()
126
-    {
127
-        $qstn_id = $this->_QST->system_ID() ? $this->_QST->system_ID() : $this->_QST->ID();
128
-        $this->_set_input_name($qstn_id);
129
-        $this->_set_input_id($qstn_id);
130
-        $this->_set_input_class($qstn_id);
131
-        $this->set_question_form_input_answer($qstn_id);
132
-    }
133
-
134
-
135
-    /**
136
-     * set_input_name
137
-     *
138
-     * @access private
139
-     * @param $qstn_id
140
-     * @return void
141
-     */
142
-    private function _set_input_name($qstn_id)
143
-    {
144
-        if (! empty($qstn_id)) {
145
-            $ANS_ID = $this->get('ANS_ID');
146
-            $qstn_id = ! empty($ANS_ID) ? '[' . $qstn_id . '][' . $ANS_ID . ']' : '[' . $qstn_id . ']';
147
-        }
148
-        $this->QST_input_name = $this->_QST_meta['append_qstn_id'] && ! empty($qstn_id)
149
-            ? $this->_QST_meta['input_prefix'] . $this->_QST_meta['input_name'] . $qstn_id
150
-            : $this->_QST_meta['input_prefix'] . $this->_QST_meta['input_name'];
151
-    }
152
-
153
-
154
-    /**
155
-     * get property values for question form input
156
-     *
157
-     * @access public
158
-     * @param    string $property
159
-     * @return mixed
160
-     */
161
-    public function get($property = null)
162
-    {
163
-        if (! empty($property)) {
164
-            if (EEM_Question::instance()->has_field($property)) {
165
-                return $this->_QST->get($property);
166
-            } elseif (EEM_Answer::instance()->has_field($property)) {
167
-                return $this->_ANS->get($property);
168
-            } elseif ($this->_question_form_input_property_exists(__CLASS__, $property)) {
169
-                return $this->{$property};
170
-            }
171
-        }
172
-        return null;
173
-    }
174
-
175
-
176
-    /**
177
-     *    _question_form_input_property_exists
178
-     *
179
-     * @access private
180
-     * @param    string $classname
181
-     * @param    string $property
182
-     * @return boolean
183
-     */
184
-    private function _question_form_input_property_exists($classname, $property)
185
-    {
186
-        // first try regular property exists method which works as expected in PHP 5.3+
187
-        $prop = EEH_Class_Tools::has_property($classname, $property);
188
-        if (! $prop) {
189
-            // use reflection for < PHP 5.3 as a double check when property is not found, possible due to access restriction
190
-            $reflector = new ReflectionClass($classname);
191
-            $prop = $reflector->hasProperty($property);
192
-        }
193
-        return $prop;
194
-    }
195
-
196
-
197
-    /**
198
-     * set_input_id
199
-     *
200
-     * @access private
201
-     * @param $qstn_id
202
-     * @return void
203
-     */
204
-    private function _set_input_id($qstn_id)
205
-    {
206
-        $input_id = isset($this->_QST_meta['input_id']) && ! empty($this->_QST_meta['input_id'])
207
-            ? $this->_QST_meta['input_id']
208
-            : sanitize_key(strip_tags($this->_QST->get('QST_display_text')));
209
-        $this->QST_input_id = $this->_QST_meta['append_qstn_id'] && ! empty($qstn_id)
210
-            ? $input_id . '-' . $qstn_id
211
-            : $input_id;
212
-    }
213
-
214
-
215
-    /**
216
-     * set_input_class
217
-     *
218
-     * @access private
219
-     * @return void
220
-     */
221
-    private function _set_input_class()
222
-    {
223
-        $this->QST_input_class = isset($this->_QST_meta['input_class']) ? $this->_QST_meta['input_class'] : '';
224
-    }
225
-
226
-
227
-    /**
228
-     * set_question_form_input_answer
229
-     *
230
-     * @access public
231
-     * @param mixed    int | string    $qstn_id
232
-     * @return void
233
-     */
234
-    public function set_question_form_input_answer($qstn_id)
235
-    {
236
-        // check for answer in $_REQUEST in case we are reprocessing a form after an error
237
-        if (
238
-            isset($this->_QST_meta['EVT_ID'])
239
-            && isset($this->_QST_meta['att_nmbr'])
240
-            && isset($this->_QST_meta['date'])
241
-            && isset($this->_QST_meta['time'])
242
-            && isset($this->_QST_meta['price_id'])
243
-        ) {
244
-            if (
245
-                isset($_REQUEST['qstn'][ $this->_QST_meta['EVT_ID'] ][ $this->_QST_meta['att_nmbr'] ][ $this->_QST_meta['date'] ][ $this->_QST_meta['time'] ][ $this->_QST_meta['price_id'] ][ $qstn_id ])
246
-            ) {
247
-                $answer = $_REQUEST['qstn'][ $this->_QST_meta['EVT_ID'] ][ $this->_QST_meta['att_nmbr'] ][ $this->_QST_meta['date'] ][ $this->_QST_meta['time'] ][ $this->_QST_meta['price_id'] ][ $qstn_id ];
248
-                $this->_ANS->set('ANS_value', $answer);
249
-            }
250
-        }
251
-    }
252
-
253
-
254
-    /**
255
-     *        generate_question_form_inputs_for_object
256
-     *
257
-     * @access    protected
258
-     * @param bool|object $object $object
259
-     * @param    array    $input_types
260
-     * @return        array
261
-     */
262
-    public static function generate_question_form_inputs_for_object($object = false, $input_types = array())
263
-    {
264
-        if (! is_object($object)) {
265
-            return false;
266
-        }
267
-        $inputs = array();
268
-        $fields = $object->get_model()->field_settings(false);
269
-        // $pk = $object->ID(); <<< NO!
270
-        // EEH_Debug_Tools::printr( $object, get_class( $object ) . '<br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
271
-        // EEH_Debug_Tools::printr( $fields, '$fields  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
272
-        // EEH_Debug_Tools::printr( $input_types, '$input_types  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
273
-        foreach ($fields as $field_ID => $field) {
274
-            if ($field instanceof EE_Model_Field_Base) {
275
-                // echo '<h4>$field_ID : ' . $field_ID . '  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span></h4>';
276
-                // EEH_Debug_Tools::printr( $field, '$field  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
277
-                if (isset($input_types[ $field_ID ])) {
278
-                    // get saved value for field
279
-                    $value = $object->get($field_ID);
280
-                    // echo '<h4>$value : ' . $value . '  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span></h4>';
281
-                    // if no saved value, then use default
282
-                    $value = $value !== null ? $value : $field->get_default_value();
283
-                    // if ( $field_ID == 'CNT_active' )
284
-                    // echo '<h4>$value : ' . $value . '  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span></h4>';
285
-                    // determine question type
286
-                    $type = isset($input_types[ $field_ID ]) ? $input_types[ $field_ID ]['type'] : 'TEXT';
287
-                    // input name
288
-                    $input_name = isset($input_types[ $field_ID ]) && isset($input_types[ $field_ID ]['input_name'])
289
-                        ? $input_types[ $field_ID ]['input_name'] . '[' . $field_ID . ']'
290
-                        : $field_ID;
291
-                    // css class for input
292
-                    $class = isset($input_types[ $field_ID ]['class']) && ! empty($input_types[ $field_ID ]['class'])
293
-                        ? ' ' . $input_types[ $field_ID ]['class']
294
-                        : '';
295
-                    // whether to apply htmlentities to answer
296
-                    $htmlentities = isset($input_types[ $field_ID ]['htmlentities'])
297
-                        ? $input_types[ $field_ID ]['htmlentities']
298
-                        : true;
299
-                    // whether to apply htmlentities to answer
300
-                    $label_b4 = isset($input_types[ $field_ID ]['label_b4'])
301
-                        ? $input_types[ $field_ID ]['label_b4']
302
-                        : false;
303
-                    // whether to apply htmlentities to answer
304
-                    $use_desc_4_label = isset($input_types[ $field_ID ]['use_desc_4_label'])
305
-                        ? $input_types[ $field_ID ]['use_desc_4_label']
306
-                        : false;
307
-                    // whether input is disabled
308
-                    $disabled = isset($input_types[ $field_ID ]['disabled'])
309
-                        ? $input_types[ $field_ID ]['disabled']
310
-                        : false;
311
-
312
-                    // create EE_Question_Form_Input object
313
-                    $QFI = new EE_Question_Form_Input(
314
-                        EE_Question::new_instance(
315
-                            array(
316
-                                'QST_ID'           => 0,
317
-                                'QST_display_text' => $field->get_nicename(),
318
-                                'QST_type'         => $type,
319
-                            )
320
-                        ),
321
-                        EE_Answer::new_instance(
322
-                            array(
323
-                                'ANS_ID'    => 0,
324
-                                'QST_ID'    => 0,
325
-                                'REG_ID'    => 0,
326
-                                'ANS_value' => $value,
327
-                            )
328
-                        ),
329
-                        array(
330
-                            'input_id'         => $field_ID . '-' . $object->ID(),
331
-                            'input_name'       => $input_name,
332
-                            'input_class'      => $field_ID . $class,
333
-                            'input_prefix'     => '',
334
-                            'append_qstn_id'   => false,
335
-                            'htmlentities'     => $htmlentities,
336
-                            'label_b4'         => $label_b4,
337
-                            'use_desc_4_label' => $use_desc_4_label,
338
-                        )
339
-                    );
340
-                    // does question type have options ?
341
-                    if (
342
-                        in_array($type, array('DROPDOWN', 'RADIO_BTN', 'CHECKBOX'))
343
-                        && isset($input_types[ $field_ID ])
344
-                        && isset($input_types[ $field_ID ]['options'])
345
-                    ) {
346
-                        foreach ($input_types[ $field_ID ]['options'] as $option) {
347
-                            $option = stripslashes_deep($option);
348
-                            $option_id = ! empty($option['id']) ? $option['id'] : 0;
349
-                            $QSO = EE_Question_Option::new_instance(
350
-                                array(
351
-                                    'QSO_value'   => (string) $option_id,
352
-                                    'QSO_desc'    => $option['text'],
353
-                                    'QSO_deleted' => false,
354
-                                )
355
-                            );
356
-                            // all QST (and ANS) properties can be accessed indirectly thru QFI
357
-                            $QFI->add_temp_option($QSO);
358
-                        }
359
-                    }
360
-                    // we don't want ppl manually changing primary keys cuz that would just lead to total craziness man
361
-                    if ($disabled || $field_ID == $object->get_model()->primary_key_name()) {
362
-                        $QFI->set('QST_disabled', true);
363
-                    }
364
-                    // EEH_Debug_Tools::printr( $QFI, '$QFI  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
365
-                    $inputs[ $field_ID ] = $QFI;
366
-                    // if ( $field_ID == 'CNT_active' ) {
367
-                    // EEH_Debug_Tools::printr( $QFI, '$QFI  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
368
-                    // }
369
-                }
370
-            }
371
-        }
372
-        return $inputs;
373
-    }
374
-
375
-
376
-    /**
377
-     *    add_temp_option
378
-     *
379
-     * @access public
380
-     * @param \EE_Question_Option $QSO EE_Question_Option
381
-     * @return boolean
382
-     */
383
-    public function add_temp_option(EE_Question_Option $QSO)
384
-    {
385
-        $this->_QST->add_temp_option($QSO);
386
-    }
387
-
388
-
389
-    /**
390
-     * set property values for question form input
391
-     *
392
-     * @access public
393
-     * @param    string $property
394
-     * @param    mixed  $value
395
-     * @return mixed
396
-     */
397
-    public function set($property = null, $value = null)
398
-    {
399
-        if (! empty($property)) {
400
-            if (EEM_Question::instance()->has_field($property)) {
401
-                $this->_QST->set($property, $value);
402
-            } elseif (EEM_Answer::instance()->has_field($property)) {
403
-                $this->_ANS->set($property, $value);
404
-            } elseif ($this->_question_form_input_property_exists(__CLASS__, $property)) {
405
-                // echo "<hr>$property is a prop of QFI";
406
-                $this->{$property} = $value;
407
-                return true;
408
-            }
409
-        }
410
-        return null;
411
-    }
412
-
413
-
414
-    /**
415
-     *    _question_form_input_property_exists
416
-     *
417
-     * @access public
418
-     * @param boolean      $notDeletedOptionsOnly            1
419
-     *                                                       whether to return ALL options, or only the ones which have
420
-     *                                                       not yet been deleted
421
-     * @param string|array $selected_value_to_always_include , when retrieving options to an ANSWERED question,
422
-     *                                                       we want to usually only show non-deleted options AND the
423
-     *                                                       value that was selected for the answer, whether it was
424
-     *                                                       trashed or not.
425
-     * @return EE_Question_Option
426
-     */
427
-    public function options($notDeletedOptionsOnly = true, $selected_value_to_always_include = null)
428
-    {
429
-        $temp_options = $this->_QST->temp_options();
430
-        return ! empty($temp_options)
431
-            ? $temp_options
432
-            : $this->_QST->options(
433
-                $notDeletedOptionsOnly,
434
-                $selected_value_to_always_include
435
-            );
436
-    }
437
-
438
-
439
-    /**
440
-     *    get_meta
441
-     *
442
-     * @access public
443
-     * @param mixed $key
444
-     * @return mixed
445
-     */
446
-    public function get_meta($key = false)
447
-    {
448
-        return $key && isset($this->_QST_meta[ $key ]) ? $this->_QST_meta[ $key ] : false;
449
-    }
16
+	/**
17
+	 *    EE_Question object
18
+	 *
19
+	 * @access private
20
+	 * @var object
21
+	 */
22
+	private $_QST = null;
23
+
24
+	/**
25
+	 *    EE_Answer object
26
+	 *
27
+	 * @access private
28
+	 * @var object
29
+	 */
30
+	private $_ANS = null;
31
+
32
+	/**
33
+	 *    $_QST_meta
34
+	 * @access private
35
+	 * @var array
36
+	 */
37
+	private $_QST_meta = array();
38
+
39
+	/**
40
+	 *    $QST_input_name
41
+	 * @access private
42
+	 * @var string
43
+	 */
44
+	private $QST_input_name = '';
45
+
46
+	/**
47
+	 *    $QST_input_id
48
+	 * @access private
49
+	 * @var string
50
+	 */
51
+	private $QST_input_id = '';
52
+
53
+	/**
54
+	 *    $QST_input_class
55
+	 * @access private
56
+	 * @var string
57
+	 */
58
+	private $QST_input_class = '';
59
+
60
+	/**
61
+	 * @var bool $QST_disabled
62
+	 */
63
+	private $QST_disabled = false;
64
+
65
+
66
+	/**
67
+	 * constructor for questions
68
+	 *
69
+	 * @param \EE_Question $QST EE_Question object
70
+	 * @param \EE_Answer   $ANS EE_Answer object
71
+	 * @param array        $q_meta
72
+	 * @access public
73
+	 * @return \EE_Question_Form_Input
74
+	 */
75
+	public function __construct(EE_Question $QST = null, EE_Answer $ANS = null, $q_meta = array())
76
+	{
77
+		if (empty($QST) || empty($ANS)) {
78
+			EE_Error::add_error(
79
+				__('An error occurred. A valid EE_Question or EE_Answer object was not received.', 'event_espresso'),
80
+				__FILE__,
81
+				__FUNCTION__,
82
+				__LINE__
83
+			);
84
+			return null;
85
+		}
86
+		$this->_QST = $QST;
87
+		$this->_ANS = $ANS;
88
+		$this->set_question_form_input_meta($q_meta);
89
+		$this->set_question_form_input_init();
90
+	}
91
+
92
+
93
+	/**
94
+	 * sets meta data for the question form input
95
+	 *
96
+	 * @access public
97
+	 * @param array $q_meta
98
+	 * @return void
99
+	 */
100
+	public function set_question_form_input_meta($q_meta = array())
101
+	{
102
+		$default_q_meta = array(
103
+			'att_nmbr'       => 1,
104
+			'ticket_id'      => '',
105
+			'date'           => '',
106
+			'time'           => '',
107
+			'input_name'     => '',
108
+			'input_id'       => '',
109
+			'input_class'    => '',
110
+			'input_prefix'   => 'qstn',
111
+			'append_qstn_id' => true,
112
+			'htmlentities'   => true,
113
+			'allow_null'     => false,
114
+		);
115
+		$this->_QST_meta = array_merge($default_q_meta, $q_meta);
116
+	}
117
+
118
+
119
+	/**
120
+	 * set_question_form_input_init
121
+	 *
122
+	 * @access public
123
+	 * @return void
124
+	 */
125
+	public function set_question_form_input_init()
126
+	{
127
+		$qstn_id = $this->_QST->system_ID() ? $this->_QST->system_ID() : $this->_QST->ID();
128
+		$this->_set_input_name($qstn_id);
129
+		$this->_set_input_id($qstn_id);
130
+		$this->_set_input_class($qstn_id);
131
+		$this->set_question_form_input_answer($qstn_id);
132
+	}
133
+
134
+
135
+	/**
136
+	 * set_input_name
137
+	 *
138
+	 * @access private
139
+	 * @param $qstn_id
140
+	 * @return void
141
+	 */
142
+	private function _set_input_name($qstn_id)
143
+	{
144
+		if (! empty($qstn_id)) {
145
+			$ANS_ID = $this->get('ANS_ID');
146
+			$qstn_id = ! empty($ANS_ID) ? '[' . $qstn_id . '][' . $ANS_ID . ']' : '[' . $qstn_id . ']';
147
+		}
148
+		$this->QST_input_name = $this->_QST_meta['append_qstn_id'] && ! empty($qstn_id)
149
+			? $this->_QST_meta['input_prefix'] . $this->_QST_meta['input_name'] . $qstn_id
150
+			: $this->_QST_meta['input_prefix'] . $this->_QST_meta['input_name'];
151
+	}
152
+
153
+
154
+	/**
155
+	 * get property values for question form input
156
+	 *
157
+	 * @access public
158
+	 * @param    string $property
159
+	 * @return mixed
160
+	 */
161
+	public function get($property = null)
162
+	{
163
+		if (! empty($property)) {
164
+			if (EEM_Question::instance()->has_field($property)) {
165
+				return $this->_QST->get($property);
166
+			} elseif (EEM_Answer::instance()->has_field($property)) {
167
+				return $this->_ANS->get($property);
168
+			} elseif ($this->_question_form_input_property_exists(__CLASS__, $property)) {
169
+				return $this->{$property};
170
+			}
171
+		}
172
+		return null;
173
+	}
174
+
175
+
176
+	/**
177
+	 *    _question_form_input_property_exists
178
+	 *
179
+	 * @access private
180
+	 * @param    string $classname
181
+	 * @param    string $property
182
+	 * @return boolean
183
+	 */
184
+	private function _question_form_input_property_exists($classname, $property)
185
+	{
186
+		// first try regular property exists method which works as expected in PHP 5.3+
187
+		$prop = EEH_Class_Tools::has_property($classname, $property);
188
+		if (! $prop) {
189
+			// use reflection for < PHP 5.3 as a double check when property is not found, possible due to access restriction
190
+			$reflector = new ReflectionClass($classname);
191
+			$prop = $reflector->hasProperty($property);
192
+		}
193
+		return $prop;
194
+	}
195
+
196
+
197
+	/**
198
+	 * set_input_id
199
+	 *
200
+	 * @access private
201
+	 * @param $qstn_id
202
+	 * @return void
203
+	 */
204
+	private function _set_input_id($qstn_id)
205
+	{
206
+		$input_id = isset($this->_QST_meta['input_id']) && ! empty($this->_QST_meta['input_id'])
207
+			? $this->_QST_meta['input_id']
208
+			: sanitize_key(strip_tags($this->_QST->get('QST_display_text')));
209
+		$this->QST_input_id = $this->_QST_meta['append_qstn_id'] && ! empty($qstn_id)
210
+			? $input_id . '-' . $qstn_id
211
+			: $input_id;
212
+	}
213
+
214
+
215
+	/**
216
+	 * set_input_class
217
+	 *
218
+	 * @access private
219
+	 * @return void
220
+	 */
221
+	private function _set_input_class()
222
+	{
223
+		$this->QST_input_class = isset($this->_QST_meta['input_class']) ? $this->_QST_meta['input_class'] : '';
224
+	}
225
+
226
+
227
+	/**
228
+	 * set_question_form_input_answer
229
+	 *
230
+	 * @access public
231
+	 * @param mixed    int | string    $qstn_id
232
+	 * @return void
233
+	 */
234
+	public function set_question_form_input_answer($qstn_id)
235
+	{
236
+		// check for answer in $_REQUEST in case we are reprocessing a form after an error
237
+		if (
238
+			isset($this->_QST_meta['EVT_ID'])
239
+			&& isset($this->_QST_meta['att_nmbr'])
240
+			&& isset($this->_QST_meta['date'])
241
+			&& isset($this->_QST_meta['time'])
242
+			&& isset($this->_QST_meta['price_id'])
243
+		) {
244
+			if (
245
+				isset($_REQUEST['qstn'][ $this->_QST_meta['EVT_ID'] ][ $this->_QST_meta['att_nmbr'] ][ $this->_QST_meta['date'] ][ $this->_QST_meta['time'] ][ $this->_QST_meta['price_id'] ][ $qstn_id ])
246
+			) {
247
+				$answer = $_REQUEST['qstn'][ $this->_QST_meta['EVT_ID'] ][ $this->_QST_meta['att_nmbr'] ][ $this->_QST_meta['date'] ][ $this->_QST_meta['time'] ][ $this->_QST_meta['price_id'] ][ $qstn_id ];
248
+				$this->_ANS->set('ANS_value', $answer);
249
+			}
250
+		}
251
+	}
252
+
253
+
254
+	/**
255
+	 *        generate_question_form_inputs_for_object
256
+	 *
257
+	 * @access    protected
258
+	 * @param bool|object $object $object
259
+	 * @param    array    $input_types
260
+	 * @return        array
261
+	 */
262
+	public static function generate_question_form_inputs_for_object($object = false, $input_types = array())
263
+	{
264
+		if (! is_object($object)) {
265
+			return false;
266
+		}
267
+		$inputs = array();
268
+		$fields = $object->get_model()->field_settings(false);
269
+		// $pk = $object->ID(); <<< NO!
270
+		// EEH_Debug_Tools::printr( $object, get_class( $object ) . '<br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
271
+		// EEH_Debug_Tools::printr( $fields, '$fields  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
272
+		// EEH_Debug_Tools::printr( $input_types, '$input_types  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
273
+		foreach ($fields as $field_ID => $field) {
274
+			if ($field instanceof EE_Model_Field_Base) {
275
+				// echo '<h4>$field_ID : ' . $field_ID . '  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span></h4>';
276
+				// EEH_Debug_Tools::printr( $field, '$field  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
277
+				if (isset($input_types[ $field_ID ])) {
278
+					// get saved value for field
279
+					$value = $object->get($field_ID);
280
+					// echo '<h4>$value : ' . $value . '  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span></h4>';
281
+					// if no saved value, then use default
282
+					$value = $value !== null ? $value : $field->get_default_value();
283
+					// if ( $field_ID == 'CNT_active' )
284
+					// echo '<h4>$value : ' . $value . '  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span></h4>';
285
+					// determine question type
286
+					$type = isset($input_types[ $field_ID ]) ? $input_types[ $field_ID ]['type'] : 'TEXT';
287
+					// input name
288
+					$input_name = isset($input_types[ $field_ID ]) && isset($input_types[ $field_ID ]['input_name'])
289
+						? $input_types[ $field_ID ]['input_name'] . '[' . $field_ID . ']'
290
+						: $field_ID;
291
+					// css class for input
292
+					$class = isset($input_types[ $field_ID ]['class']) && ! empty($input_types[ $field_ID ]['class'])
293
+						? ' ' . $input_types[ $field_ID ]['class']
294
+						: '';
295
+					// whether to apply htmlentities to answer
296
+					$htmlentities = isset($input_types[ $field_ID ]['htmlentities'])
297
+						? $input_types[ $field_ID ]['htmlentities']
298
+						: true;
299
+					// whether to apply htmlentities to answer
300
+					$label_b4 = isset($input_types[ $field_ID ]['label_b4'])
301
+						? $input_types[ $field_ID ]['label_b4']
302
+						: false;
303
+					// whether to apply htmlentities to answer
304
+					$use_desc_4_label = isset($input_types[ $field_ID ]['use_desc_4_label'])
305
+						? $input_types[ $field_ID ]['use_desc_4_label']
306
+						: false;
307
+					// whether input is disabled
308
+					$disabled = isset($input_types[ $field_ID ]['disabled'])
309
+						? $input_types[ $field_ID ]['disabled']
310
+						: false;
311
+
312
+					// create EE_Question_Form_Input object
313
+					$QFI = new EE_Question_Form_Input(
314
+						EE_Question::new_instance(
315
+							array(
316
+								'QST_ID'           => 0,
317
+								'QST_display_text' => $field->get_nicename(),
318
+								'QST_type'         => $type,
319
+							)
320
+						),
321
+						EE_Answer::new_instance(
322
+							array(
323
+								'ANS_ID'    => 0,
324
+								'QST_ID'    => 0,
325
+								'REG_ID'    => 0,
326
+								'ANS_value' => $value,
327
+							)
328
+						),
329
+						array(
330
+							'input_id'         => $field_ID . '-' . $object->ID(),
331
+							'input_name'       => $input_name,
332
+							'input_class'      => $field_ID . $class,
333
+							'input_prefix'     => '',
334
+							'append_qstn_id'   => false,
335
+							'htmlentities'     => $htmlentities,
336
+							'label_b4'         => $label_b4,
337
+							'use_desc_4_label' => $use_desc_4_label,
338
+						)
339
+					);
340
+					// does question type have options ?
341
+					if (
342
+						in_array($type, array('DROPDOWN', 'RADIO_BTN', 'CHECKBOX'))
343
+						&& isset($input_types[ $field_ID ])
344
+						&& isset($input_types[ $field_ID ]['options'])
345
+					) {
346
+						foreach ($input_types[ $field_ID ]['options'] as $option) {
347
+							$option = stripslashes_deep($option);
348
+							$option_id = ! empty($option['id']) ? $option['id'] : 0;
349
+							$QSO = EE_Question_Option::new_instance(
350
+								array(
351
+									'QSO_value'   => (string) $option_id,
352
+									'QSO_desc'    => $option['text'],
353
+									'QSO_deleted' => false,
354
+								)
355
+							);
356
+							// all QST (and ANS) properties can be accessed indirectly thru QFI
357
+							$QFI->add_temp_option($QSO);
358
+						}
359
+					}
360
+					// we don't want ppl manually changing primary keys cuz that would just lead to total craziness man
361
+					if ($disabled || $field_ID == $object->get_model()->primary_key_name()) {
362
+						$QFI->set('QST_disabled', true);
363
+					}
364
+					// EEH_Debug_Tools::printr( $QFI, '$QFI  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
365
+					$inputs[ $field_ID ] = $QFI;
366
+					// if ( $field_ID == 'CNT_active' ) {
367
+					// EEH_Debug_Tools::printr( $QFI, '$QFI  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
368
+					// }
369
+				}
370
+			}
371
+		}
372
+		return $inputs;
373
+	}
374
+
375
+
376
+	/**
377
+	 *    add_temp_option
378
+	 *
379
+	 * @access public
380
+	 * @param \EE_Question_Option $QSO EE_Question_Option
381
+	 * @return boolean
382
+	 */
383
+	public function add_temp_option(EE_Question_Option $QSO)
384
+	{
385
+		$this->_QST->add_temp_option($QSO);
386
+	}
387
+
388
+
389
+	/**
390
+	 * set property values for question form input
391
+	 *
392
+	 * @access public
393
+	 * @param    string $property
394
+	 * @param    mixed  $value
395
+	 * @return mixed
396
+	 */
397
+	public function set($property = null, $value = null)
398
+	{
399
+		if (! empty($property)) {
400
+			if (EEM_Question::instance()->has_field($property)) {
401
+				$this->_QST->set($property, $value);
402
+			} elseif (EEM_Answer::instance()->has_field($property)) {
403
+				$this->_ANS->set($property, $value);
404
+			} elseif ($this->_question_form_input_property_exists(__CLASS__, $property)) {
405
+				// echo "<hr>$property is a prop of QFI";
406
+				$this->{$property} = $value;
407
+				return true;
408
+			}
409
+		}
410
+		return null;
411
+	}
412
+
413
+
414
+	/**
415
+	 *    _question_form_input_property_exists
416
+	 *
417
+	 * @access public
418
+	 * @param boolean      $notDeletedOptionsOnly            1
419
+	 *                                                       whether to return ALL options, or only the ones which have
420
+	 *                                                       not yet been deleted
421
+	 * @param string|array $selected_value_to_always_include , when retrieving options to an ANSWERED question,
422
+	 *                                                       we want to usually only show non-deleted options AND the
423
+	 *                                                       value that was selected for the answer, whether it was
424
+	 *                                                       trashed or not.
425
+	 * @return EE_Question_Option
426
+	 */
427
+	public function options($notDeletedOptionsOnly = true, $selected_value_to_always_include = null)
428
+	{
429
+		$temp_options = $this->_QST->temp_options();
430
+		return ! empty($temp_options)
431
+			? $temp_options
432
+			: $this->_QST->options(
433
+				$notDeletedOptionsOnly,
434
+				$selected_value_to_always_include
435
+			);
436
+	}
437
+
438
+
439
+	/**
440
+	 *    get_meta
441
+	 *
442
+	 * @access public
443
+	 * @param mixed $key
444
+	 * @return mixed
445
+	 */
446
+	public function get_meta($key = false)
447
+	{
448
+		return $key && isset($this->_QST_meta[ $key ]) ? $this->_QST_meta[ $key ] : false;
449
+	}
450 450
 }
Please login to merge, or discard this patch.
Spacing   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -141,13 +141,13 @@  discard block
 block discarded – undo
141 141
      */
142 142
     private function _set_input_name($qstn_id)
143 143
     {
144
-        if (! empty($qstn_id)) {
144
+        if ( ! empty($qstn_id)) {
145 145
             $ANS_ID = $this->get('ANS_ID');
146
-            $qstn_id = ! empty($ANS_ID) ? '[' . $qstn_id . '][' . $ANS_ID . ']' : '[' . $qstn_id . ']';
146
+            $qstn_id = ! empty($ANS_ID) ? '['.$qstn_id.']['.$ANS_ID.']' : '['.$qstn_id.']';
147 147
         }
148 148
         $this->QST_input_name = $this->_QST_meta['append_qstn_id'] && ! empty($qstn_id)
149
-            ? $this->_QST_meta['input_prefix'] . $this->_QST_meta['input_name'] . $qstn_id
150
-            : $this->_QST_meta['input_prefix'] . $this->_QST_meta['input_name'];
149
+            ? $this->_QST_meta['input_prefix'].$this->_QST_meta['input_name'].$qstn_id
150
+            : $this->_QST_meta['input_prefix'].$this->_QST_meta['input_name'];
151 151
     }
152 152
 
153 153
 
@@ -160,7 +160,7 @@  discard block
 block discarded – undo
160 160
      */
161 161
     public function get($property = null)
162 162
     {
163
-        if (! empty($property)) {
163
+        if ( ! empty($property)) {
164 164
             if (EEM_Question::instance()->has_field($property)) {
165 165
                 return $this->_QST->get($property);
166 166
             } elseif (EEM_Answer::instance()->has_field($property)) {
@@ -185,7 +185,7 @@  discard block
 block discarded – undo
185 185
     {
186 186
         // first try regular property exists method which works as expected in PHP 5.3+
187 187
         $prop = EEH_Class_Tools::has_property($classname, $property);
188
-        if (! $prop) {
188
+        if ( ! $prop) {
189 189
             // use reflection for < PHP 5.3 as a double check when property is not found, possible due to access restriction
190 190
             $reflector = new ReflectionClass($classname);
191 191
             $prop = $reflector->hasProperty($property);
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
             ? $this->_QST_meta['input_id']
208 208
             : sanitize_key(strip_tags($this->_QST->get('QST_display_text')));
209 209
         $this->QST_input_id = $this->_QST_meta['append_qstn_id'] && ! empty($qstn_id)
210
-            ? $input_id . '-' . $qstn_id
210
+            ? $input_id.'-'.$qstn_id
211 211
             : $input_id;
212 212
     }
213 213
 
@@ -242,9 +242,9 @@  discard block
 block discarded – undo
242 242
             && isset($this->_QST_meta['price_id'])
243 243
         ) {
244 244
             if (
245
-                isset($_REQUEST['qstn'][ $this->_QST_meta['EVT_ID'] ][ $this->_QST_meta['att_nmbr'] ][ $this->_QST_meta['date'] ][ $this->_QST_meta['time'] ][ $this->_QST_meta['price_id'] ][ $qstn_id ])
245
+                isset($_REQUEST['qstn'][$this->_QST_meta['EVT_ID']][$this->_QST_meta['att_nmbr']][$this->_QST_meta['date']][$this->_QST_meta['time']][$this->_QST_meta['price_id']][$qstn_id])
246 246
             ) {
247
-                $answer = $_REQUEST['qstn'][ $this->_QST_meta['EVT_ID'] ][ $this->_QST_meta['att_nmbr'] ][ $this->_QST_meta['date'] ][ $this->_QST_meta['time'] ][ $this->_QST_meta['price_id'] ][ $qstn_id ];
247
+                $answer = $_REQUEST['qstn'][$this->_QST_meta['EVT_ID']][$this->_QST_meta['att_nmbr']][$this->_QST_meta['date']][$this->_QST_meta['time']][$this->_QST_meta['price_id']][$qstn_id];
248 248
                 $this->_ANS->set('ANS_value', $answer);
249 249
             }
250 250
         }
@@ -261,7 +261,7 @@  discard block
 block discarded – undo
261 261
      */
262 262
     public static function generate_question_form_inputs_for_object($object = false, $input_types = array())
263 263
     {
264
-        if (! is_object($object)) {
264
+        if ( ! is_object($object)) {
265 265
             return false;
266 266
         }
267 267
         $inputs = array();
@@ -274,7 +274,7 @@  discard block
 block discarded – undo
274 274
             if ($field instanceof EE_Model_Field_Base) {
275 275
                 // echo '<h4>$field_ID : ' . $field_ID . '  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span></h4>';
276 276
                 // EEH_Debug_Tools::printr( $field, '$field  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
277
-                if (isset($input_types[ $field_ID ])) {
277
+                if (isset($input_types[$field_ID])) {
278 278
                     // get saved value for field
279 279
                     $value = $object->get($field_ID);
280 280
                     // echo '<h4>$value : ' . $value . '  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span></h4>';
@@ -283,30 +283,30 @@  discard block
 block discarded – undo
283 283
                     // if ( $field_ID == 'CNT_active' )
284 284
                     // echo '<h4>$value : ' . $value . '  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span></h4>';
285 285
                     // determine question type
286
-                    $type = isset($input_types[ $field_ID ]) ? $input_types[ $field_ID ]['type'] : 'TEXT';
286
+                    $type = isset($input_types[$field_ID]) ? $input_types[$field_ID]['type'] : 'TEXT';
287 287
                     // input name
288
-                    $input_name = isset($input_types[ $field_ID ]) && isset($input_types[ $field_ID ]['input_name'])
289
-                        ? $input_types[ $field_ID ]['input_name'] . '[' . $field_ID . ']'
288
+                    $input_name = isset($input_types[$field_ID]) && isset($input_types[$field_ID]['input_name'])
289
+                        ? $input_types[$field_ID]['input_name'].'['.$field_ID.']'
290 290
                         : $field_ID;
291 291
                     // css class for input
292
-                    $class = isset($input_types[ $field_ID ]['class']) && ! empty($input_types[ $field_ID ]['class'])
293
-                        ? ' ' . $input_types[ $field_ID ]['class']
292
+                    $class = isset($input_types[$field_ID]['class']) && ! empty($input_types[$field_ID]['class'])
293
+                        ? ' '.$input_types[$field_ID]['class']
294 294
                         : '';
295 295
                     // whether to apply htmlentities to answer
296
-                    $htmlentities = isset($input_types[ $field_ID ]['htmlentities'])
297
-                        ? $input_types[ $field_ID ]['htmlentities']
296
+                    $htmlentities = isset($input_types[$field_ID]['htmlentities'])
297
+                        ? $input_types[$field_ID]['htmlentities']
298 298
                         : true;
299 299
                     // whether to apply htmlentities to answer
300
-                    $label_b4 = isset($input_types[ $field_ID ]['label_b4'])
301
-                        ? $input_types[ $field_ID ]['label_b4']
300
+                    $label_b4 = isset($input_types[$field_ID]['label_b4'])
301
+                        ? $input_types[$field_ID]['label_b4']
302 302
                         : false;
303 303
                     // whether to apply htmlentities to answer
304
-                    $use_desc_4_label = isset($input_types[ $field_ID ]['use_desc_4_label'])
305
-                        ? $input_types[ $field_ID ]['use_desc_4_label']
304
+                    $use_desc_4_label = isset($input_types[$field_ID]['use_desc_4_label'])
305
+                        ? $input_types[$field_ID]['use_desc_4_label']
306 306
                         : false;
307 307
                     // whether input is disabled
308
-                    $disabled = isset($input_types[ $field_ID ]['disabled'])
309
-                        ? $input_types[ $field_ID ]['disabled']
308
+                    $disabled = isset($input_types[$field_ID]['disabled'])
309
+                        ? $input_types[$field_ID]['disabled']
310 310
                         : false;
311 311
 
312 312
                     // create EE_Question_Form_Input object
@@ -327,9 +327,9 @@  discard block
 block discarded – undo
327 327
                             )
328 328
                         ),
329 329
                         array(
330
-                            'input_id'         => $field_ID . '-' . $object->ID(),
330
+                            'input_id'         => $field_ID.'-'.$object->ID(),
331 331
                             'input_name'       => $input_name,
332
-                            'input_class'      => $field_ID . $class,
332
+                            'input_class'      => $field_ID.$class,
333 333
                             'input_prefix'     => '',
334 334
                             'append_qstn_id'   => false,
335 335
                             'htmlentities'     => $htmlentities,
@@ -340,10 +340,10 @@  discard block
 block discarded – undo
340 340
                     // does question type have options ?
341 341
                     if (
342 342
                         in_array($type, array('DROPDOWN', 'RADIO_BTN', 'CHECKBOX'))
343
-                        && isset($input_types[ $field_ID ])
344
-                        && isset($input_types[ $field_ID ]['options'])
343
+                        && isset($input_types[$field_ID])
344
+                        && isset($input_types[$field_ID]['options'])
345 345
                     ) {
346
-                        foreach ($input_types[ $field_ID ]['options'] as $option) {
346
+                        foreach ($input_types[$field_ID]['options'] as $option) {
347 347
                             $option = stripslashes_deep($option);
348 348
                             $option_id = ! empty($option['id']) ? $option['id'] : 0;
349 349
                             $QSO = EE_Question_Option::new_instance(
@@ -362,7 +362,7 @@  discard block
 block discarded – undo
362 362
                         $QFI->set('QST_disabled', true);
363 363
                     }
364 364
                     // EEH_Debug_Tools::printr( $QFI, '$QFI  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
365
-                    $inputs[ $field_ID ] = $QFI;
365
+                    $inputs[$field_ID] = $QFI;
366 366
                     // if ( $field_ID == 'CNT_active' ) {
367 367
                     // EEH_Debug_Tools::printr( $QFI, '$QFI  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
368 368
                     // }
@@ -396,7 +396,7 @@  discard block
 block discarded – undo
396 396
      */
397 397
     public function set($property = null, $value = null)
398 398
     {
399
-        if (! empty($property)) {
399
+        if ( ! empty($property)) {
400 400
             if (EEM_Question::instance()->has_field($property)) {
401 401
                 $this->_QST->set($property, $value);
402 402
             } elseif (EEM_Answer::instance()->has_field($property)) {
@@ -445,6 +445,6 @@  discard block
 block discarded – undo
445 445
      */
446 446
     public function get_meta($key = false)
447 447
     {
448
-        return $key && isset($this->_QST_meta[ $key ]) ? $this->_QST_meta[ $key ] : false;
448
+        return $key && isset($this->_QST_meta[$key]) ? $this->_QST_meta[$key] : false;
449 449
     }
450 450
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Status.class.php 3 patches
Doc Comments   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -52,7 +52,7 @@  discard block
 block discarded – undo
52 52
      * Sets code
53 53
      *
54 54
      * @param string $code
55
-     * @return boolean
55
+     * @return boolean|null
56 56
      */
57 57
     public function set_code($code)
58 58
     {
@@ -75,7 +75,7 @@  discard block
 block discarded – undo
75 75
      * Sets desc
76 76
      *
77 77
      * @param string $desc
78
-     * @return boolean
78
+     * @return boolean|null
79 79
      */
80 80
     public function set_desc($desc)
81 81
     {
@@ -98,7 +98,7 @@  discard block
 block discarded – undo
98 98
      * Sets type
99 99
      *
100 100
      * @param string $type
101
-     * @return boolean
101
+     * @return boolean|null
102 102
      */
103 103
     public function set_type($type)
104 104
     {
@@ -121,7 +121,7 @@  discard block
 block discarded – undo
121 121
      * Sets can_edit
122 122
      *
123 123
      * @param boolean $can_edit
124
-     * @return boolean
124
+     * @return boolean|null
125 125
      */
126 126
     public function set_can_edit($can_edit)
127 127
     {
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
      * Sets open
145 145
      *
146 146
      * @param boolean $open
147
-     * @return boolean
147
+     * @return boolean|null
148 148
      */
149 149
     public function set_open($open)
150 150
     {
Please login to merge, or discard this patch.
Indentation   +138 added lines, -138 removed lines patch added patch discarded remove patch
@@ -12,142 +12,142 @@
 block discarded – undo
12 12
 class EE_Status extends EE_Base_Class
13 13
 {
14 14
 
15
-    /**
16
-     * @param array $props_n_values
17
-     * @return EE_Status
18
-     */
19
-    public static function new_instance($props_n_values = array())
20
-    {
21
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
22
-        return $has_object ? $has_object : new self($props_n_values);
23
-    }
24
-
25
-
26
-    /**
27
-     * @param array $props_n_values
28
-     * @return EE_Status
29
-     */
30
-    public static function new_instance_from_db($props_n_values = array())
31
-    {
32
-        return new self($props_n_values, true);
33
-    }
34
-
35
-
36
-    /**
37
-     * Gets code
38
-     *
39
-     * @param bool   $plural
40
-     * @param string $schema
41
-     * @return string
42
-     */
43
-    public function code($plural = false, $schema = 'upper')
44
-    {
45
-        $id = $this->get('STS_ID');
46
-        $code = EEM_Status::instance()->localized_status(array($id => $this->get('STS_code')), $plural, $schema);
47
-        return $code[ $id ];
48
-    }
49
-
50
-
51
-    /**
52
-     * Sets code
53
-     *
54
-     * @param string $code
55
-     * @return boolean
56
-     */
57
-    public function set_code($code)
58
-    {
59
-        $this->set('STS_code', $code);
60
-    }
61
-
62
-
63
-    /**
64
-     * Gets desc
65
-     *
66
-     * @return string
67
-     */
68
-    public function desc()
69
-    {
70
-        return $this->get('STS_desc');
71
-    }
72
-
73
-
74
-    /**
75
-     * Sets desc
76
-     *
77
-     * @param string $desc
78
-     * @return boolean
79
-     */
80
-    public function set_desc($desc)
81
-    {
82
-        $this->set('STS_desc', $desc);
83
-    }
84
-
85
-
86
-    /**
87
-     * Gets type
88
-     *
89
-     * @return string
90
-     */
91
-    public function type()
92
-    {
93
-        return $this->get('STS_type');
94
-    }
95
-
96
-
97
-    /**
98
-     * Sets type
99
-     *
100
-     * @param string $type
101
-     * @return boolean
102
-     */
103
-    public function set_type($type)
104
-    {
105
-        $this->set('STS_type', $type);
106
-    }
107
-
108
-
109
-    /**
110
-     * Gets can_edit
111
-     *
112
-     * @return boolean
113
-     */
114
-    public function can_edit()
115
-    {
116
-        return $this->get('STS_can_edit');
117
-    }
118
-
119
-
120
-    /**
121
-     * Sets can_edit
122
-     *
123
-     * @param boolean $can_edit
124
-     * @return boolean
125
-     */
126
-    public function set_can_edit($can_edit)
127
-    {
128
-        $this->set('STS_can_edit', $can_edit);
129
-    }
130
-
131
-
132
-    /**
133
-     * Gets open
134
-     *
135
-     * @return boolean
136
-     */
137
-    public function open()
138
-    {
139
-        return $this->get('STS_open');
140
-    }
141
-
142
-
143
-    /**
144
-     * Sets open
145
-     *
146
-     * @param boolean $open
147
-     * @return boolean
148
-     */
149
-    public function set_open($open)
150
-    {
151
-        $this->set('STS_open', $open);
152
-    }
15
+	/**
16
+	 * @param array $props_n_values
17
+	 * @return EE_Status
18
+	 */
19
+	public static function new_instance($props_n_values = array())
20
+	{
21
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
22
+		return $has_object ? $has_object : new self($props_n_values);
23
+	}
24
+
25
+
26
+	/**
27
+	 * @param array $props_n_values
28
+	 * @return EE_Status
29
+	 */
30
+	public static function new_instance_from_db($props_n_values = array())
31
+	{
32
+		return new self($props_n_values, true);
33
+	}
34
+
35
+
36
+	/**
37
+	 * Gets code
38
+	 *
39
+	 * @param bool   $plural
40
+	 * @param string $schema
41
+	 * @return string
42
+	 */
43
+	public function code($plural = false, $schema = 'upper')
44
+	{
45
+		$id = $this->get('STS_ID');
46
+		$code = EEM_Status::instance()->localized_status(array($id => $this->get('STS_code')), $plural, $schema);
47
+		return $code[ $id ];
48
+	}
49
+
50
+
51
+	/**
52
+	 * Sets code
53
+	 *
54
+	 * @param string $code
55
+	 * @return boolean
56
+	 */
57
+	public function set_code($code)
58
+	{
59
+		$this->set('STS_code', $code);
60
+	}
61
+
62
+
63
+	/**
64
+	 * Gets desc
65
+	 *
66
+	 * @return string
67
+	 */
68
+	public function desc()
69
+	{
70
+		return $this->get('STS_desc');
71
+	}
72
+
73
+
74
+	/**
75
+	 * Sets desc
76
+	 *
77
+	 * @param string $desc
78
+	 * @return boolean
79
+	 */
80
+	public function set_desc($desc)
81
+	{
82
+		$this->set('STS_desc', $desc);
83
+	}
84
+
85
+
86
+	/**
87
+	 * Gets type
88
+	 *
89
+	 * @return string
90
+	 */
91
+	public function type()
92
+	{
93
+		return $this->get('STS_type');
94
+	}
95
+
96
+
97
+	/**
98
+	 * Sets type
99
+	 *
100
+	 * @param string $type
101
+	 * @return boolean
102
+	 */
103
+	public function set_type($type)
104
+	{
105
+		$this->set('STS_type', $type);
106
+	}
107
+
108
+
109
+	/**
110
+	 * Gets can_edit
111
+	 *
112
+	 * @return boolean
113
+	 */
114
+	public function can_edit()
115
+	{
116
+		return $this->get('STS_can_edit');
117
+	}
118
+
119
+
120
+	/**
121
+	 * Sets can_edit
122
+	 *
123
+	 * @param boolean $can_edit
124
+	 * @return boolean
125
+	 */
126
+	public function set_can_edit($can_edit)
127
+	{
128
+		$this->set('STS_can_edit', $can_edit);
129
+	}
130
+
131
+
132
+	/**
133
+	 * Gets open
134
+	 *
135
+	 * @return boolean
136
+	 */
137
+	public function open()
138
+	{
139
+		return $this->get('STS_open');
140
+	}
141
+
142
+
143
+	/**
144
+	 * Sets open
145
+	 *
146
+	 * @param boolean $open
147
+	 * @return boolean
148
+	 */
149
+	public function set_open($open)
150
+	{
151
+		$this->set('STS_open', $open);
152
+	}
153 153
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -44,7 +44,7 @@
 block discarded – undo
44 44
     {
45 45
         $id = $this->get('STS_ID');
46 46
         $code = EEM_Status::instance()->localized_status(array($id => $this->get('STS_code')), $plural, $schema);
47
-        return $code[ $id ];
47
+        return $code[$id];
48 48
     }
49 49
 
50 50
 
Please login to merge, or discard this patch.
core/db_classes/EE_Term_Taxonomy.class.php 2 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -47,7 +47,7 @@  discard block
 block discarded – undo
47 47
      * Sets taxonomy
48 48
      *
49 49
      * @param string $taxonomy
50
-     * @return boolean
50
+     * @return boolean|null
51 51
      */
52 52
     public function set_taxonomy($taxonomy)
53 53
     {
@@ -70,7 +70,7 @@  discard block
 block discarded – undo
70 70
      * Sets term_count
71 71
      *
72 72
      * @param int $term_count
73
-     * @return boolean
73
+     * @return boolean|null
74 74
      */
75 75
     public function set_count($term_count)
76 76
     {
Please login to merge, or discard this patch.
Indentation   +64 added lines, -64 removed lines patch added patch discarded remove patch
@@ -11,80 +11,80 @@
 block discarded – undo
11 11
 class EE_Term_Taxonomy extends EE_Base_Class
12 12
 {
13 13
 
14
-    /**
15
-     * @param array $props_n_values
16
-     * @return EE_Term_Taxonomy
17
-     */
18
-    public static function new_instance($props_n_values = array())
19
-    {
20
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
21
-        return $has_object ? $has_object : new self($props_n_values);
22
-    }
14
+	/**
15
+	 * @param array $props_n_values
16
+	 * @return EE_Term_Taxonomy
17
+	 */
18
+	public static function new_instance($props_n_values = array())
19
+	{
20
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
21
+		return $has_object ? $has_object : new self($props_n_values);
22
+	}
23 23
 
24 24
 
25
-    /**
26
-     * @param array $props_n_values
27
-     * @return EE_Term_Taxonomy
28
-     */
29
-    public static function new_instance_from_db($props_n_values = array())
30
-    {
31
-        return new self($props_n_values, true);
32
-    }
25
+	/**
26
+	 * @param array $props_n_values
27
+	 * @return EE_Term_Taxonomy
28
+	 */
29
+	public static function new_instance_from_db($props_n_values = array())
30
+	{
31
+		return new self($props_n_values, true);
32
+	}
33 33
 
34 34
 
35
-    /**
36
-     * Gets taxonomy
37
-     *
38
-     * @return string
39
-     */
40
-    public function taxonomy()
41
-    {
42
-        return $this->get('taxonomy');
43
-    }
35
+	/**
36
+	 * Gets taxonomy
37
+	 *
38
+	 * @return string
39
+	 */
40
+	public function taxonomy()
41
+	{
42
+		return $this->get('taxonomy');
43
+	}
44 44
 
45 45
 
46
-    /**
47
-     * Sets taxonomy
48
-     *
49
-     * @param string $taxonomy
50
-     * @return boolean
51
-     */
52
-    public function set_taxonomy($taxonomy)
53
-    {
54
-        $this->set('taxonomy', $taxonomy);
55
-    }
46
+	/**
47
+	 * Sets taxonomy
48
+	 *
49
+	 * @param string $taxonomy
50
+	 * @return boolean
51
+	 */
52
+	public function set_taxonomy($taxonomy)
53
+	{
54
+		$this->set('taxonomy', $taxonomy);
55
+	}
56 56
 
57 57
 
58
-    /**
59
-     * Gets term_count
60
-     *
61
-     * @return int
62
-     */
63
-    public function count()
64
-    {
65
-        return $this->get('term_count');
66
-    }
58
+	/**
59
+	 * Gets term_count
60
+	 *
61
+	 * @return int
62
+	 */
63
+	public function count()
64
+	{
65
+		return $this->get('term_count');
66
+	}
67 67
 
68 68
 
69
-    /**
70
-     * Sets term_count
71
-     *
72
-     * @param int $term_count
73
-     * @return boolean
74
-     */
75
-    public function set_count($term_count)
76
-    {
77
-        $this->set('term_count', $term_count);
78
-    }
69
+	/**
70
+	 * Sets term_count
71
+	 *
72
+	 * @param int $term_count
73
+	 * @return boolean
74
+	 */
75
+	public function set_count($term_count)
76
+	{
77
+		$this->set('term_count', $term_count);
78
+	}
79 79
 
80 80
 
81
-    /**
82
-     * Gets the term for this term taxonomy
83
-     *
84
-     * @return EE_Term
85
-     */
86
-    public function term()
87
-    {
88
-        return $this->get_first_related('Term');
89
-    }
81
+	/**
82
+	 * Gets the term for this term taxonomy
83
+	 *
84
+	 * @return EE_Term
85
+	 */
86
+	public function term()
87
+	{
88
+		return $this->get_first_related('Term');
89
+	}
90 90
 }
Please login to merge, or discard this patch.
modules/single_page_checkout/inc/EE_Checkout.class.php 3 patches
Doc Comments   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -319,7 +319,7 @@  discard block
 block discarded – undo
319 319
 
320 320
     /**
321 321
      * @param $REG_ID
322
-     * @param $reg_status
322
+     * @param boolean $reg_status
323 323
      */
324 324
     public function set_reg_status_updated($REG_ID, $reg_status)
325 325
     {
@@ -1237,6 +1237,7 @@  discard block
 block discarded – undo
1237 1237
      *
1238 1238
      * @param    string | int    $reg_cache_ID
1239 1239
      * @param    EE_Registration $registration
1240
+     * @param integer $reg_cache_ID
1240 1241
      * @return void
1241 1242
      * @throws \EE_Error
1242 1243
      */
Please login to merge, or discard this patch.
Spacing   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -313,7 +313,7 @@  discard block
 block discarded – undo
313 313
      */
314 314
     public function reg_status_updated($REG_ID)
315 315
     {
316
-        return isset($this->reg_status_updated[ $REG_ID ]) ? $this->reg_status_updated[ $REG_ID ] : false;
316
+        return isset($this->reg_status_updated[$REG_ID]) ? $this->reg_status_updated[$REG_ID] : false;
317 317
     }
318 318
 
319 319
 
@@ -323,7 +323,7 @@  discard block
 block discarded – undo
323 323
      */
324 324
     public function set_reg_status_updated($REG_ID, $reg_status)
325 325
     {
326
-        $this->reg_status_updated[ $REG_ID ] = filter_var($reg_status, FILTER_VALIDATE_BOOLEAN);
326
+        $this->reg_status_updated[$REG_ID] = filter_var($reg_status, FILTER_VALIDATE_BOOLEAN);
327 327
     }
328 328
 
329 329
 
@@ -382,7 +382,7 @@  discard block
 block discarded – undo
382 382
      */
383 383
     public function add_reg_step(EE_SPCO_Reg_Step $reg_step_obj)
384 384
     {
385
-        $this->reg_steps[ $reg_step_obj->slug() ] = $reg_step_obj;
385
+        $this->reg_steps[$reg_step_obj->slug()] = $reg_step_obj;
386 386
     }
387 387
 
388 388
 
@@ -428,7 +428,7 @@  discard block
 block discarded – undo
428 428
      */
429 429
     public function remove_reg_step($reg_step_slug = '', $reset = true)
430 430
     {
431
-        unset($this->reg_steps[ $reg_step_slug ]);
431
+        unset($this->reg_steps[$reg_step_slug]);
432 432
         if ($this->transaction instanceof EE_Transaction) {
433 433
             // now remove reg step from TXN and save
434 434
             $this->transaction->remove_reg_step($reg_step_slug);
@@ -450,8 +450,8 @@  discard block
 block discarded – undo
450 450
      */
451 451
     public function set_reg_step_order($reg_step_slug = '', $order = 100)
452 452
     {
453
-        if (isset($this->reg_steps[ $reg_step_slug ])) {
454
-            $this->reg_steps[ $reg_step_slug ]->set_order($order);
453
+        if (isset($this->reg_steps[$reg_step_slug])) {
454
+            $this->reg_steps[$reg_step_slug]->set_order($order);
455 455
         }
456 456
     }
457 457
 
@@ -466,8 +466,8 @@  discard block
 block discarded – undo
466 466
     public function set_current_step($current_step)
467 467
     {
468 468
         // grab what step we're on
469
-        $this->current_step = isset($this->reg_steps[ $current_step ])
470
-            ? $this->reg_steps[ $current_step ]
469
+        $this->current_step = isset($this->reg_steps[$current_step])
470
+            ? $this->reg_steps[$current_step]
471 471
             : reset(
472 472
                 $this->reg_steps
473 473
             );
@@ -578,7 +578,7 @@  discard block
 block discarded – undo
578 578
      */
579 579
     public function find_reg_step($reg_step_slug = '')
580 580
     {
581
-        if (! empty($reg_step_slug)) {
581
+        if ( ! empty($reg_step_slug)) {
582 582
             // copy reg step array
583 583
             $reg_steps = $this->reg_steps;
584 584
             // set pointer to start of array
@@ -639,7 +639,7 @@  discard block
 block discarded – undo
639 639
             )
640 640
         ) {
641 641
             // set the start time for this reg step
642
-            if (! $this->transaction->set_reg_step_initiated($reg_step->slug())) {
642
+            if ( ! $this->transaction->set_reg_step_initiated($reg_step->slug())) {
643 643
                 if (WP_DEBUG) {
644 644
                     EE_Error::add_error(
645 645
                         sprintf(
@@ -742,7 +742,7 @@  discard block
 block discarded – undo
742 742
         $session = EE_Registry::instance()->load_core('Session');
743 743
         $cart = $transaction instanceof EE_Transaction ? EE_Cart::get_cart_from_txn($transaction, $session) : null;
744 744
         // verify cart
745
-        if (! $cart instanceof EE_Cart) {
745
+        if ( ! $cart instanceof EE_Cart) {
746 746
             $cart = EE_Registry::instance()->load_core('Cart');
747 747
         }
748 748
 
@@ -760,7 +760,7 @@  discard block
 block discarded – undo
760 760
     {
761 761
         $txn_reg_steps_array = array();
762 762
         foreach ($this->reg_steps as $reg_step) {
763
-            $txn_reg_steps_array[ $reg_step->slug() ] = false;
763
+            $txn_reg_steps_array[$reg_step->slug()] = false;
764 764
         }
765 765
         return $txn_reg_steps_array;
766 766
     }
@@ -799,7 +799,7 @@  discard block
 block discarded – undo
799 799
      */
800 800
     public function stash_transaction_and_checkout()
801 801
     {
802
-        if (! $this->revisit) {
802
+        if ( ! $this->revisit) {
803 803
             $this->update_txn_reg_steps_array();
804 804
         }
805 805
         $this->track_transaction_and_registration_status_updates();
@@ -926,7 +926,7 @@  discard block
 block discarded – undo
926 926
             // should this registration be processed during this visit ?
927 927
             if ($this->visit_allows_processing_of_this_registration($registration)) {
928 928
                 // set TXN ID
929
-                if (! $registration->transaction_ID()) {
929
+                if ( ! $registration->transaction_ID()) {
930 930
                     $registration->set_transaction_id($this->transaction->ID());
931 931
                 }
932 932
                 // verify and save the attendee
@@ -936,7 +936,7 @@  discard block
 block discarded – undo
936 936
                 // save changes
937 937
                 $registration->save();
938 938
                 // update txn cache
939
-                if (! $this->transaction->update_cache_after_object_save('Registration', $registration)) {
939
+                if ( ! $this->transaction->update_cache_after_object_save('Registration', $registration)) {
940 940
                     if ($show_errors) {
941 941
                         EE_Error::add_error(
942 942
                             __(
@@ -979,7 +979,7 @@  discard block
 block discarded – undo
979 979
         if ($registration->attendee() instanceof EE_Attendee) {
980 980
             // save so that ATT has ID
981 981
             $registration->attendee()->save();
982
-            if (! $registration->update_cache_after_object_save('Attendee', $registration->attendee())) {
982
+            if ( ! $registration->update_cache_after_object_save('Attendee', $registration->attendee())) {
983 983
                 if ($show_errors) {
984 984
                     EE_Error::add_error(
985 985
                         __(
@@ -1028,7 +1028,7 @@  discard block
 block discarded – undo
1028 1028
             if ($answer instanceof EE_Answer) {
1029 1029
                 $answer->set_registration($registration->ID());
1030 1030
                 $answer->save();
1031
-                if (! $registration->update_cache_after_object_save('Answer', $answer, $cache_key)) {
1031
+                if ( ! $registration->update_cache_after_object_save('Answer', $answer, $cache_key)) {
1032 1032
                     if ($show_errors) {
1033 1033
                         EE_Error::add_error(
1034 1034
                             __(
@@ -1349,11 +1349,11 @@  discard block
 block discarded – undo
1349 1349
      */
1350 1350
     public function __wakeup()
1351 1351
     {
1352
-        if (! $this->primary_attendee_obj instanceof EE_Attendee && absint($this->primary_attendee_obj) !== 0) {
1352
+        if ( ! $this->primary_attendee_obj instanceof EE_Attendee && absint($this->primary_attendee_obj) !== 0) {
1353 1353
             // $this->primary_attendee_obj is actually just an ID, so use it to get the object from the db
1354 1354
             $this->primary_attendee_obj = EEM_Attendee::instance()->get_one_by_ID($this->primary_attendee_obj);
1355 1355
         }
1356
-        if (! $this->transaction instanceof EE_Transaction && absint($this->transaction) !== 0) {
1356
+        if ( ! $this->transaction instanceof EE_Transaction && absint($this->transaction) !== 0) {
1357 1357
             // $this->transaction is actually just an ID, so use it to get the object from the db
1358 1358
             $this->transaction = EEM_Transaction::instance()->get_one_by_ID($this->transaction);
1359 1359
         }
@@ -1377,9 +1377,9 @@  discard block
 block discarded – undo
1377 1377
     {
1378 1378
         $disabled = true;
1379 1379
         if (WP_DEBUG && ! $disabled) {
1380
-            $debug_data = get_option('EE_DEBUG_SPCO_' . EE_Session::instance()->id(), array());
1380
+            $debug_data = get_option('EE_DEBUG_SPCO_'.EE_Session::instance()->id(), array());
1381 1381
             $default_data = array(
1382
-                $class                    => $func . '() : ' . $line,
1382
+                $class                    => $func.'() : '.$line,
1383 1383
                 'request->step'           => $this->step,
1384 1384
                 'request->action'         => $this->action,
1385 1385
                 'current_step->slug'      => $this->current_step instanceof EE_SPCO_Reg_Step ?
@@ -1395,20 +1395,20 @@  discard block
 block discarded – undo
1395 1395
                 $default_data['TXN_status'] = $this->transaction->status_ID();
1396 1396
                 $default_data['TXN_reg_steps'] = $this->transaction->reg_steps();
1397 1397
                 foreach ($this->transaction->registrations($this->reg_cache_where_params) as $REG_ID => $registration) {
1398
-                    $default_data['registrations'][ $REG_ID ] = $registration->status_ID();
1398
+                    $default_data['registrations'][$REG_ID] = $registration->status_ID();
1399 1399
                 }
1400 1400
                 if ($this->transaction->ID()) {
1401
-                    $TXN_ID = 'EE_Transaction: ' . $this->transaction->ID();
1401
+                    $TXN_ID = 'EE_Transaction: '.$this->transaction->ID();
1402 1402
                     // don't serialize objects
1403 1403
                     $info = $this->_strip_objects($info);
1404
-                    if (! isset($debug_data[ $TXN_ID ])) {
1405
-                        $debug_data[ $TXN_ID ] = array();
1404
+                    if ( ! isset($debug_data[$TXN_ID])) {
1405
+                        $debug_data[$TXN_ID] = array();
1406 1406
                     }
1407
-                    $debug_data[ $TXN_ID ][ microtime() ] = array_merge(
1407
+                    $debug_data[$TXN_ID][microtime()] = array_merge(
1408 1408
                         $default_data,
1409 1409
                         $info
1410 1410
                     );
1411
-                    update_option('EE_DEBUG_SPCO_' . EE_Session::instance()->id(), $debug_data);
1411
+                    update_option('EE_DEBUG_SPCO_'.EE_Session::instance()->id(), $debug_data);
1412 1412
                 }
1413 1413
             }
1414 1414
         }
@@ -1425,17 +1425,17 @@  discard block
 block discarded – undo
1425 1425
     {
1426 1426
         foreach ((array) $info as $key => $value) {
1427 1427
             if (is_array($value)) {
1428
-                $info[ $key ] = $this->_strip_objects($value);
1428
+                $info[$key] = $this->_strip_objects($value);
1429 1429
             } elseif (is_object($value)) {
1430 1430
                 $object_class = get_class($value);
1431
-                $info[ $object_class ] = array();
1432
-                $info[ $object_class ]['ID'] = method_exists($value, 'ID') ? $value->ID() : 0;
1431
+                $info[$object_class] = array();
1432
+                $info[$object_class]['ID'] = method_exists($value, 'ID') ? $value->ID() : 0;
1433 1433
                 if (method_exists($value, 'status')) {
1434
-                    $info[ $object_class ]['status'] = $value->status();
1434
+                    $info[$object_class]['status'] = $value->status();
1435 1435
                 } elseif (method_exists($value, 'status_ID')) {
1436
-                    $info[ $object_class ]['status'] = $value->status_ID();
1436
+                    $info[$object_class]['status'] = $value->status_ID();
1437 1437
                 }
1438
-                unset($info[ $key ]);
1438
+                unset($info[$key]);
1439 1439
             }
1440 1440
         }
1441 1441
         return (array) $info;
Please login to merge, or discard this patch.
Indentation   +1425 added lines, -1425 removed lines patch added patch discarded remove patch
@@ -15,1430 +15,1430 @@
 block discarded – undo
15 15
 class EE_Checkout
16 16
 {
17 17
 
18
-    /**
19
-     *    whether current request originated from the EE admin
20
-     *
21
-     * @type bool
22
-     */
23
-    public $admin_request = false;
24
-
25
-    /**
26
-     * whether returning to edit attendee information or to retry a payment
27
-     *
28
-     * @type bool
29
-     */
30
-    public $revisit = false;
31
-
32
-    /**
33
-     * whether the primary registrant is returning to edit attendee information or to retry a payment
34
-     *
35
-     * @type bool
36
-     */
37
-    public $primary_revisit = false;
38
-
39
-    /**
40
-     * is registration allowed to progress or halted for some reason such as failing to pass recaptcha?
41
-     *
42
-     * @type bool
43
-     */
44
-    public $continue_reg = true;
45
-
46
-    /**
47
-     * redirect to thank you page ?
48
-     *
49
-     * @type bool
50
-     */
51
-    public $redirect = false;
52
-
53
-    /**
54
-     * generate the reg form or not ?
55
-     *
56
-     * @type bool
57
-     */
58
-    public $generate_reg_form = true;
59
-
60
-    /**
61
-     * process a reg form submission or not ?
62
-     *
63
-     * @type bool
64
-     */
65
-    public $process_form_submission = false;
66
-
67
-    /**
68
-     * tracks whether the TXN status modified during this checkout
69
-     *
70
-     * @type bool
71
-     */
72
-    public $txn_status_updated = false;
73
-
74
-    /**
75
-     * only triggered to true after absolutely everything has finished.
76
-     *
77
-     * @type bool
78
-     */
79
-    protected $exit_spco = false;
80
-
81
-    /**
82
-     * tracks whether any of the TXN's Registrations statuses modified during this checkout
83
-     * indexed by registration ID
84
-     *
85
-     * @type array
86
-     */
87
-    protected $reg_status_updated = array();
88
-
89
-    /**
90
-     * timestamp when redirected from Ticket Selector to the checkout
91
-     *
92
-     * @type int
93
-     */
94
-    public $uts = 0;
95
-
96
-    /**
97
-     * total number of tickets that were in the cart
98
-     *
99
-     * @type int
100
-     */
101
-    public $total_ticket_count = 0;
102
-
103
-    /**
104
-     * corresponds loosely to EE_Transaction::remaining()
105
-     * but can be modified by SPCO
106
-     *
107
-     * @type float
108
-     */
109
-    public $amount_owing = 0;
110
-
111
-    /**
112
-     * the reg step slug from the incoming request
113
-     *
114
-     * @type string
115
-     */
116
-    public $step = '';
117
-
118
-    /**
119
-     * the reg step slug for a step being edited
120
-     *
121
-     * @type string
122
-     */
123
-    public $edit_step = '';
124
-
125
-    /**
126
-     * the action being performed on the current step
127
-     *
128
-     * @type string
129
-     */
130
-    public $action = '';
131
-
132
-    /**
133
-     * reg_url_link for a previously saved registration
134
-     *
135
-     * @type string
136
-     */
137
-    public $reg_url_link = '';
138
-
139
-    /**
140
-     * string slug for the payment method that was selected during the payment options step
141
-     *
142
-     * @type string
143
-     */
144
-    public $selected_method_of_payment = '';
145
-
146
-    /**
147
-     * base url for the site's registration checkout page - additional url params will be added to this
148
-     *
149
-     * @type string
150
-     */
151
-    public $reg_page_base_url = '';
152
-
153
-    /**
154
-     * base url for the site's registration cancelled page - additional url params will be added to this
155
-     *
156
-     * @type string
157
-     */
158
-    public $cancel_page_url = '';
159
-
160
-    /**
161
-     * base url for the site's thank you page - additional url params will be added to this
162
-     *
163
-     * @type string
164
-     */
165
-    public $thank_you_page_url = '';
166
-
167
-    /**
168
-     * base url for any redirects - additional url params will be added to this
169
-     *
170
-     * @type string
171
-     */
172
-    public $redirect_url = '';
173
-
174
-    /**
175
-     * form of POST data for use with off-site gateways
176
-     *
177
-     * @type string
178
-     */
179
-    public $redirect_form = '';
180
-
181
-    /**
182
-     * array of query where params to use when retrieving cached registrations from $this->checkout->transaction
183
-     *
184
-     * @type array
185
-     */
186
-    public $reg_cache_where_params = array();
187
-
188
-    /**
189
-     * a class for managing and creating the JSON encoded array of data that gets passed back to the client during AJAX
190
-     * requests
191
-     *
192
-     * @type EE_SPCO_JSON_Response
193
-     */
194
-    public $json_response;
195
-
196
-    /**
197
-     * where we are going next in the reg process
198
-     *
199
-     * @type EE_SPCO_Reg_Step
200
-     */
201
-    public $next_step;
202
-
203
-    /**
204
-     * where we are in the reg process
205
-     *
206
-     * @type EE_SPCO_Reg_Step
207
-     */
208
-    public $current_step;
209
-
210
-    /**
211
-     *    $_cart - the current cart object
212
-     *
213
-     * @var EE_CART
214
-     */
215
-    public $cart;
216
-
217
-    /**
218
-     *    $_transaction - the current transaction object
219
-     *
220
-     * @var EE_Transaction
221
-     */
222
-    public $transaction;
223
-
224
-    /**
225
-     *    the related attendee object for the primary registrant
226
-     *
227
-     * @type EE_Attendee
228
-     */
229
-    public $primary_attendee_obj;
230
-
231
-    /**
232
-     *    $payment_method - the payment method object for the selected method of payment
233
-     *
234
-     * @type EE_Payment_Method
235
-     */
236
-    public $payment_method;
237
-
238
-    /**
239
-     *    $payment - if a payment was successfully made during the reg process,
240
-     *    then here it is !!!
241
-     *
242
-     * @type EE_Payment
243
-     */
244
-    public $payment;
245
-
246
-    /**
247
-     *    if a payment method was selected that uses an on-site gateway, then this is the billing form
248
-     *
249
-     * @type EE_Billing_Info_Form | EE_Billing_Attendee_Info_Form
250
-     */
251
-    public $billing_form;
252
-
253
-    /**
254
-     *    the entire registration form composed of ALL of the subsections generated by the various reg steps
255
-     *
256
-     * @type EE_Form_Section_Proper
257
-     */
258
-    public $registration_form;
259
-
260
-    /**
261
-     * array of EE_SPCO_Reg_Step objects
262
-     *
263
-     * @type EE_SPCO_Reg_Step[]
264
-     */
265
-    public $reg_steps = array();
266
-
267
-    /**
268
-     * array of EE_Payment_Method objects
269
-     *
270
-     * @type EE_Payment_Method[]
271
-     */
272
-    public $available_payment_methods = array();
273
-
274
-
275
-    /**
276
-     *    class constructor
277
-     *
278
-     * @access    public
279
-     */
280
-    public function __construct()
281
-    {
282
-        $this->reg_page_base_url = EE_Registry::instance()->CFG->core->reg_page_url();
283
-        $this->thank_you_page_url = EE_Registry::instance()->CFG->core->thank_you_page_url();
284
-        $this->cancel_page_url = EE_Registry::instance()->CFG->core->cancel_page_url();
285
-        $this->continue_reg = apply_filters('FHEE__EE_Checkout___construct___continue_reg', true);
286
-        $this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->ajax;
287
-        $this->reg_cache_where_params = array(
288
-            0          => array('REG_deleted' => false),
289
-            'order_by' => array('REG_count' => 'ASC'),
290
-        );
291
-    }
292
-
293
-
294
-    /**
295
-     * returns true if ANY reg status was updated during checkout
296
-     *
297
-     * @return boolean
298
-     */
299
-    public function any_reg_status_updated()
300
-    {
301
-        foreach ($this->reg_status_updated as $reg_status) {
302
-            if ($reg_status) {
303
-                return true;
304
-            }
305
-        }
306
-        return false;
307
-    }
308
-
309
-
310
-    /**
311
-     * @param $REG_ID
312
-     * @return boolean
313
-     */
314
-    public function reg_status_updated($REG_ID)
315
-    {
316
-        return isset($this->reg_status_updated[ $REG_ID ]) ? $this->reg_status_updated[ $REG_ID ] : false;
317
-    }
318
-
319
-
320
-    /**
321
-     * @param $REG_ID
322
-     * @param $reg_status
323
-     */
324
-    public function set_reg_status_updated($REG_ID, $reg_status)
325
-    {
326
-        $this->reg_status_updated[ $REG_ID ] = filter_var($reg_status, FILTER_VALIDATE_BOOLEAN);
327
-    }
328
-
329
-
330
-    /**
331
-     * exit_spco
332
-     *
333
-     * @return bool
334
-     */
335
-    public function exit_spco()
336
-    {
337
-        return $this->exit_spco;
338
-    }
339
-
340
-
341
-    /**
342
-     * set_exit_spco
343
-     * can ONLY be set by the  Finalize_Registration reg step
344
-     */
345
-    public function set_exit_spco()
346
-    {
347
-        if ($this->current_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
348
-            $this->exit_spco = true;
349
-        }
350
-    }
351
-
352
-
353
-    /**
354
-     *    reset_for_current_request
355
-     *
356
-     * @access    public
357
-     * @return    void
358
-     */
359
-    public function reset_for_current_request()
360
-    {
361
-        $this->process_form_submission = false;
362
-        $this->continue_reg = apply_filters('FHEE__EE_Checkout___construct___continue_reg', true);
363
-        $this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->front_ajax;
364
-        $this->continue_reg = true;
365
-        $this->redirect = false;
366
-        // don't reset the cached redirect form if we're about to be asked to display it !!!
367
-        if (EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step') !== 'redirect_form') {
368
-            $this->redirect_form = '';
369
-        }
370
-        $this->redirect_url = '';
371
-        $this->json_response = new EE_SPCO_JSON_Response();
372
-        EE_Form_Section_Proper::reset_js_localization();
373
-    }
374
-
375
-
376
-    /**
377
-     *    add_reg_step
378
-     *
379
-     * @access    public
380
-     * @param EE_SPCO_Reg_Step $reg_step_obj
381
-     * @return    void
382
-     */
383
-    public function add_reg_step(EE_SPCO_Reg_Step $reg_step_obj)
384
-    {
385
-        $this->reg_steps[ $reg_step_obj->slug() ] = $reg_step_obj;
386
-    }
387
-
388
-
389
-    /**
390
-     * skip_reg_step
391
-     * if the current reg step does not need to run for some reason,
392
-     * then this will advance SPCO to the next reg step,
393
-     * and mark the skipped step as completed
394
-     *
395
-     * @access    public
396
-     * @param string $reg_step_slug
397
-     * @return    void
398
-     * @throws \EE_Error
399
-     */
400
-    public function skip_reg_step($reg_step_slug = '')
401
-    {
402
-        $step_to_skip = $this->find_reg_step($reg_step_slug);
403
-        if ($step_to_skip instanceof EE_SPCO_Reg_Step && $step_to_skip->is_current_step()) {
404
-            $step_to_skip->set_is_current_step(false);
405
-            $step_to_skip->set_completed();
406
-            // advance to the next step
407
-            $this->set_current_step($this->next_step->slug());
408
-            // also reset the step param in the request in case any other code references that directly
409
-            EE_Registry::instance()->REQ->set('step', $this->current_step->slug());
410
-            // since we are skipping a step and setting the current step to be what was previously the next step,
411
-            // we need to check that the next step is now correct, and not still set to the current step.
412
-            if ($this->current_step->slug() === $this->next_step->slug()) {
413
-                // correctly setup the next step
414
-                $this->set_next_step();
415
-            }
416
-            $this->set_reg_step_initiated($this->current_step);
417
-        }
418
-    }
419
-
420
-
421
-    /**
422
-     *    remove_reg_step
423
-     *
424
-     * @access    public
425
-     * @param string $reg_step_slug
426
-     * @param bool   $reset whether to reset reg steps after removal
427
-     * @throws EE_Error
428
-     */
429
-    public function remove_reg_step($reg_step_slug = '', $reset = true)
430
-    {
431
-        unset($this->reg_steps[ $reg_step_slug ]);
432
-        if ($this->transaction instanceof EE_Transaction) {
433
-            // now remove reg step from TXN and save
434
-            $this->transaction->remove_reg_step($reg_step_slug);
435
-            $this->transaction->save();
436
-        }
437
-        if ($reset) {
438
-            $this->reset_reg_steps();
439
-        }
440
-    }
441
-
442
-
443
-    /**
444
-     *    set_reg_step_order
445
-     *
446
-     * @access    public
447
-     * @param string $reg_step_slug
448
-     * @param int    $order
449
-     * @return    void
450
-     */
451
-    public function set_reg_step_order($reg_step_slug = '', $order = 100)
452
-    {
453
-        if (isset($this->reg_steps[ $reg_step_slug ])) {
454
-            $this->reg_steps[ $reg_step_slug ]->set_order($order);
455
-        }
456
-    }
457
-
458
-
459
-    /**
460
-     *    set_current_step
461
-     *
462
-     * @access    public
463
-     * @param string $current_step
464
-     * @return    void
465
-     */
466
-    public function set_current_step($current_step)
467
-    {
468
-        // grab what step we're on
469
-        $this->current_step = isset($this->reg_steps[ $current_step ])
470
-            ? $this->reg_steps[ $current_step ]
471
-            : reset(
472
-                $this->reg_steps
473
-            );
474
-        // verify instance
475
-        if ($this->current_step instanceof EE_SPCO_Reg_Step) {
476
-            // we don't want to repeat completed steps if this is the first time through SPCO
477
-            if ($this->continue_reg && ! $this->revisit && $this->current_step->completed()) {
478
-                // so advance to the next step
479
-                $this->set_next_step();
480
-                if ($this->next_step instanceof EE_SPCO_Reg_Step) {
481
-                    // and attempt to set it as the current step
482
-                    $this->set_current_step($this->next_step->slug());
483
-                }
484
-                return;
485
-            }
486
-            $this->current_step->set_is_current_step(true);
487
-        } else {
488
-            EE_Error::add_error(
489
-                __('The current step could not be set.', 'event_espresso'),
490
-                __FILE__,
491
-                __FUNCTION__,
492
-                __LINE__
493
-            );
494
-        }
495
-    }
496
-
497
-
498
-    /**
499
-     *    set_next_step
500
-     * advances the reg_steps array pointer and sets the next step, then reverses pointer back to the current step
501
-     *
502
-     * @access    public
503
-     * @return    void
504
-     */
505
-    public function set_next_step()
506
-    {
507
-        // set pointer to start of array
508
-        reset($this->reg_steps);
509
-        // if there is more than one step
510
-        if (count($this->reg_steps) > 1) {
511
-            // advance to the current step and set pointer
512
-            while (key($this->reg_steps) !== $this->current_step->slug() && key($this->reg_steps) !== '') {
513
-                next($this->reg_steps);
514
-            }
515
-        }
516
-        // advance one more spot ( if it exists )
517
-        $this->next_step = next($this->reg_steps);
518
-        // verify instance
519
-        $this->next_step = $this->next_step instanceof EE_SPCO_Reg_Step ? $this->next_step : null;
520
-        // then back to current step to reset
521
-        prev($this->reg_steps);
522
-    }
523
-
524
-
525
-    /**
526
-     *    get_next_reg_step
527
-     *    this simply returns the next step from reg_steps array
528
-     *
529
-     * @access    public
530
-     * @return    EE_SPCO_Reg_Step | null
531
-     */
532
-    public function get_next_reg_step()
533
-    {
534
-        $next = next($this->reg_steps);
535
-        prev($this->reg_steps);
536
-        return $next instanceof EE_SPCO_Reg_Step ? $next : null;
537
-    }
538
-
539
-
540
-    /**
541
-     * get_prev_reg_step
542
-     *    this simply returns the previous step from reg_steps array
543
-     *
544
-     * @access    public
545
-     * @return    EE_SPCO_Reg_Step | null
546
-     */
547
-    public function get_prev_reg_step()
548
-    {
549
-        $prev = prev($this->reg_steps);
550
-        next($this->reg_steps);
551
-        return $prev instanceof EE_SPCO_Reg_Step ? $prev : null;
552
-    }
553
-
554
-
555
-    /**
556
-     * sort_reg_steps
557
-     *
558
-     * @access public
559
-     * @return void
560
-     */
561
-    public function sort_reg_steps()
562
-    {
563
-        $reg_step_sorting_callback = apply_filters(
564
-            'FHEE__EE_Checkout__sort_reg_steps__reg_step_sorting_callback',
565
-            'reg_step_sorting_callback'
566
-        );
567
-        uasort($this->reg_steps, array($this, $reg_step_sorting_callback));
568
-    }
569
-
570
-
571
-    /**
572
-     * find_reg_step
573
-     * finds a reg step by the given slug
574
-     *
575
-     * @access    public
576
-     * @param string $reg_step_slug
577
-     * @return EE_SPCO_Reg_Step|null
578
-     */
579
-    public function find_reg_step($reg_step_slug = '')
580
-    {
581
-        if (! empty($reg_step_slug)) {
582
-            // copy reg step array
583
-            $reg_steps = $this->reg_steps;
584
-            // set pointer to start of array
585
-            reset($reg_steps);
586
-            // if there is more than one step
587
-            if (count($reg_steps) > 1) {
588
-                // advance to the current step and set pointer
589
-                while (key($reg_steps) !== $reg_step_slug && key($reg_steps) !== '') {
590
-                    next($reg_steps);
591
-                }
592
-                return current($reg_steps);
593
-            }
594
-        }
595
-        return null;
596
-    }
597
-
598
-
599
-    /**
600
-     * reg_step_sorting_callback
601
-     *
602
-     * @access public
603
-     * @param EE_SPCO_Reg_Step $reg_step_A
604
-     * @param EE_SPCO_Reg_Step $reg_step_B
605
-     * @return int
606
-     */
607
-    public function reg_step_sorting_callback(EE_SPCO_Reg_Step $reg_step_A, EE_SPCO_Reg_Step $reg_step_B)
608
-    {
609
-        // send finalize_registration step to the end of the array
610
-        if ($reg_step_A->slug() === 'finalize_registration') {
611
-            return 1;
612
-        } elseif ($reg_step_B->slug() === 'finalize_registration') {
613
-            return -1;
614
-        }
615
-        if ($reg_step_A->order() === $reg_step_B->order()) {
616
-            return 0;
617
-        }
618
-        return ($reg_step_A->order() > $reg_step_B->order()) ? 1 : -1;
619
-    }
620
-
621
-
622
-    /**
623
-     * set_reg_step_initiated
624
-     *
625
-     * @access    public
626
-     * @param    EE_SPCO_Reg_Step $reg_step
627
-     * @throws \EE_Error
628
-     */
629
-    public function set_reg_step_initiated(EE_SPCO_Reg_Step $reg_step)
630
-    {
631
-        // call set_reg_step_initiated ???
632
-        if (
18
+	/**
19
+	 *    whether current request originated from the EE admin
20
+	 *
21
+	 * @type bool
22
+	 */
23
+	public $admin_request = false;
24
+
25
+	/**
26
+	 * whether returning to edit attendee information or to retry a payment
27
+	 *
28
+	 * @type bool
29
+	 */
30
+	public $revisit = false;
31
+
32
+	/**
33
+	 * whether the primary registrant is returning to edit attendee information or to retry a payment
34
+	 *
35
+	 * @type bool
36
+	 */
37
+	public $primary_revisit = false;
38
+
39
+	/**
40
+	 * is registration allowed to progress or halted for some reason such as failing to pass recaptcha?
41
+	 *
42
+	 * @type bool
43
+	 */
44
+	public $continue_reg = true;
45
+
46
+	/**
47
+	 * redirect to thank you page ?
48
+	 *
49
+	 * @type bool
50
+	 */
51
+	public $redirect = false;
52
+
53
+	/**
54
+	 * generate the reg form or not ?
55
+	 *
56
+	 * @type bool
57
+	 */
58
+	public $generate_reg_form = true;
59
+
60
+	/**
61
+	 * process a reg form submission or not ?
62
+	 *
63
+	 * @type bool
64
+	 */
65
+	public $process_form_submission = false;
66
+
67
+	/**
68
+	 * tracks whether the TXN status modified during this checkout
69
+	 *
70
+	 * @type bool
71
+	 */
72
+	public $txn_status_updated = false;
73
+
74
+	/**
75
+	 * only triggered to true after absolutely everything has finished.
76
+	 *
77
+	 * @type bool
78
+	 */
79
+	protected $exit_spco = false;
80
+
81
+	/**
82
+	 * tracks whether any of the TXN's Registrations statuses modified during this checkout
83
+	 * indexed by registration ID
84
+	 *
85
+	 * @type array
86
+	 */
87
+	protected $reg_status_updated = array();
88
+
89
+	/**
90
+	 * timestamp when redirected from Ticket Selector to the checkout
91
+	 *
92
+	 * @type int
93
+	 */
94
+	public $uts = 0;
95
+
96
+	/**
97
+	 * total number of tickets that were in the cart
98
+	 *
99
+	 * @type int
100
+	 */
101
+	public $total_ticket_count = 0;
102
+
103
+	/**
104
+	 * corresponds loosely to EE_Transaction::remaining()
105
+	 * but can be modified by SPCO
106
+	 *
107
+	 * @type float
108
+	 */
109
+	public $amount_owing = 0;
110
+
111
+	/**
112
+	 * the reg step slug from the incoming request
113
+	 *
114
+	 * @type string
115
+	 */
116
+	public $step = '';
117
+
118
+	/**
119
+	 * the reg step slug for a step being edited
120
+	 *
121
+	 * @type string
122
+	 */
123
+	public $edit_step = '';
124
+
125
+	/**
126
+	 * the action being performed on the current step
127
+	 *
128
+	 * @type string
129
+	 */
130
+	public $action = '';
131
+
132
+	/**
133
+	 * reg_url_link for a previously saved registration
134
+	 *
135
+	 * @type string
136
+	 */
137
+	public $reg_url_link = '';
138
+
139
+	/**
140
+	 * string slug for the payment method that was selected during the payment options step
141
+	 *
142
+	 * @type string
143
+	 */
144
+	public $selected_method_of_payment = '';
145
+
146
+	/**
147
+	 * base url for the site's registration checkout page - additional url params will be added to this
148
+	 *
149
+	 * @type string
150
+	 */
151
+	public $reg_page_base_url = '';
152
+
153
+	/**
154
+	 * base url for the site's registration cancelled page - additional url params will be added to this
155
+	 *
156
+	 * @type string
157
+	 */
158
+	public $cancel_page_url = '';
159
+
160
+	/**
161
+	 * base url for the site's thank you page - additional url params will be added to this
162
+	 *
163
+	 * @type string
164
+	 */
165
+	public $thank_you_page_url = '';
166
+
167
+	/**
168
+	 * base url for any redirects - additional url params will be added to this
169
+	 *
170
+	 * @type string
171
+	 */
172
+	public $redirect_url = '';
173
+
174
+	/**
175
+	 * form of POST data for use with off-site gateways
176
+	 *
177
+	 * @type string
178
+	 */
179
+	public $redirect_form = '';
180
+
181
+	/**
182
+	 * array of query where params to use when retrieving cached registrations from $this->checkout->transaction
183
+	 *
184
+	 * @type array
185
+	 */
186
+	public $reg_cache_where_params = array();
187
+
188
+	/**
189
+	 * a class for managing and creating the JSON encoded array of data that gets passed back to the client during AJAX
190
+	 * requests
191
+	 *
192
+	 * @type EE_SPCO_JSON_Response
193
+	 */
194
+	public $json_response;
195
+
196
+	/**
197
+	 * where we are going next in the reg process
198
+	 *
199
+	 * @type EE_SPCO_Reg_Step
200
+	 */
201
+	public $next_step;
202
+
203
+	/**
204
+	 * where we are in the reg process
205
+	 *
206
+	 * @type EE_SPCO_Reg_Step
207
+	 */
208
+	public $current_step;
209
+
210
+	/**
211
+	 *    $_cart - the current cart object
212
+	 *
213
+	 * @var EE_CART
214
+	 */
215
+	public $cart;
216
+
217
+	/**
218
+	 *    $_transaction - the current transaction object
219
+	 *
220
+	 * @var EE_Transaction
221
+	 */
222
+	public $transaction;
223
+
224
+	/**
225
+	 *    the related attendee object for the primary registrant
226
+	 *
227
+	 * @type EE_Attendee
228
+	 */
229
+	public $primary_attendee_obj;
230
+
231
+	/**
232
+	 *    $payment_method - the payment method object for the selected method of payment
233
+	 *
234
+	 * @type EE_Payment_Method
235
+	 */
236
+	public $payment_method;
237
+
238
+	/**
239
+	 *    $payment - if a payment was successfully made during the reg process,
240
+	 *    then here it is !!!
241
+	 *
242
+	 * @type EE_Payment
243
+	 */
244
+	public $payment;
245
+
246
+	/**
247
+	 *    if a payment method was selected that uses an on-site gateway, then this is the billing form
248
+	 *
249
+	 * @type EE_Billing_Info_Form | EE_Billing_Attendee_Info_Form
250
+	 */
251
+	public $billing_form;
252
+
253
+	/**
254
+	 *    the entire registration form composed of ALL of the subsections generated by the various reg steps
255
+	 *
256
+	 * @type EE_Form_Section_Proper
257
+	 */
258
+	public $registration_form;
259
+
260
+	/**
261
+	 * array of EE_SPCO_Reg_Step objects
262
+	 *
263
+	 * @type EE_SPCO_Reg_Step[]
264
+	 */
265
+	public $reg_steps = array();
266
+
267
+	/**
268
+	 * array of EE_Payment_Method objects
269
+	 *
270
+	 * @type EE_Payment_Method[]
271
+	 */
272
+	public $available_payment_methods = array();
273
+
274
+
275
+	/**
276
+	 *    class constructor
277
+	 *
278
+	 * @access    public
279
+	 */
280
+	public function __construct()
281
+	{
282
+		$this->reg_page_base_url = EE_Registry::instance()->CFG->core->reg_page_url();
283
+		$this->thank_you_page_url = EE_Registry::instance()->CFG->core->thank_you_page_url();
284
+		$this->cancel_page_url = EE_Registry::instance()->CFG->core->cancel_page_url();
285
+		$this->continue_reg = apply_filters('FHEE__EE_Checkout___construct___continue_reg', true);
286
+		$this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->ajax;
287
+		$this->reg_cache_where_params = array(
288
+			0          => array('REG_deleted' => false),
289
+			'order_by' => array('REG_count' => 'ASC'),
290
+		);
291
+	}
292
+
293
+
294
+	/**
295
+	 * returns true if ANY reg status was updated during checkout
296
+	 *
297
+	 * @return boolean
298
+	 */
299
+	public function any_reg_status_updated()
300
+	{
301
+		foreach ($this->reg_status_updated as $reg_status) {
302
+			if ($reg_status) {
303
+				return true;
304
+			}
305
+		}
306
+		return false;
307
+	}
308
+
309
+
310
+	/**
311
+	 * @param $REG_ID
312
+	 * @return boolean
313
+	 */
314
+	public function reg_status_updated($REG_ID)
315
+	{
316
+		return isset($this->reg_status_updated[ $REG_ID ]) ? $this->reg_status_updated[ $REG_ID ] : false;
317
+	}
318
+
319
+
320
+	/**
321
+	 * @param $REG_ID
322
+	 * @param $reg_status
323
+	 */
324
+	public function set_reg_status_updated($REG_ID, $reg_status)
325
+	{
326
+		$this->reg_status_updated[ $REG_ID ] = filter_var($reg_status, FILTER_VALIDATE_BOOLEAN);
327
+	}
328
+
329
+
330
+	/**
331
+	 * exit_spco
332
+	 *
333
+	 * @return bool
334
+	 */
335
+	public function exit_spco()
336
+	{
337
+		return $this->exit_spco;
338
+	}
339
+
340
+
341
+	/**
342
+	 * set_exit_spco
343
+	 * can ONLY be set by the  Finalize_Registration reg step
344
+	 */
345
+	public function set_exit_spco()
346
+	{
347
+		if ($this->current_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
348
+			$this->exit_spco = true;
349
+		}
350
+	}
351
+
352
+
353
+	/**
354
+	 *    reset_for_current_request
355
+	 *
356
+	 * @access    public
357
+	 * @return    void
358
+	 */
359
+	public function reset_for_current_request()
360
+	{
361
+		$this->process_form_submission = false;
362
+		$this->continue_reg = apply_filters('FHEE__EE_Checkout___construct___continue_reg', true);
363
+		$this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->front_ajax;
364
+		$this->continue_reg = true;
365
+		$this->redirect = false;
366
+		// don't reset the cached redirect form if we're about to be asked to display it !!!
367
+		if (EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step') !== 'redirect_form') {
368
+			$this->redirect_form = '';
369
+		}
370
+		$this->redirect_url = '';
371
+		$this->json_response = new EE_SPCO_JSON_Response();
372
+		EE_Form_Section_Proper::reset_js_localization();
373
+	}
374
+
375
+
376
+	/**
377
+	 *    add_reg_step
378
+	 *
379
+	 * @access    public
380
+	 * @param EE_SPCO_Reg_Step $reg_step_obj
381
+	 * @return    void
382
+	 */
383
+	public function add_reg_step(EE_SPCO_Reg_Step $reg_step_obj)
384
+	{
385
+		$this->reg_steps[ $reg_step_obj->slug() ] = $reg_step_obj;
386
+	}
387
+
388
+
389
+	/**
390
+	 * skip_reg_step
391
+	 * if the current reg step does not need to run for some reason,
392
+	 * then this will advance SPCO to the next reg step,
393
+	 * and mark the skipped step as completed
394
+	 *
395
+	 * @access    public
396
+	 * @param string $reg_step_slug
397
+	 * @return    void
398
+	 * @throws \EE_Error
399
+	 */
400
+	public function skip_reg_step($reg_step_slug = '')
401
+	{
402
+		$step_to_skip = $this->find_reg_step($reg_step_slug);
403
+		if ($step_to_skip instanceof EE_SPCO_Reg_Step && $step_to_skip->is_current_step()) {
404
+			$step_to_skip->set_is_current_step(false);
405
+			$step_to_skip->set_completed();
406
+			// advance to the next step
407
+			$this->set_current_step($this->next_step->slug());
408
+			// also reset the step param in the request in case any other code references that directly
409
+			EE_Registry::instance()->REQ->set('step', $this->current_step->slug());
410
+			// since we are skipping a step and setting the current step to be what was previously the next step,
411
+			// we need to check that the next step is now correct, and not still set to the current step.
412
+			if ($this->current_step->slug() === $this->next_step->slug()) {
413
+				// correctly setup the next step
414
+				$this->set_next_step();
415
+			}
416
+			$this->set_reg_step_initiated($this->current_step);
417
+		}
418
+	}
419
+
420
+
421
+	/**
422
+	 *    remove_reg_step
423
+	 *
424
+	 * @access    public
425
+	 * @param string $reg_step_slug
426
+	 * @param bool   $reset whether to reset reg steps after removal
427
+	 * @throws EE_Error
428
+	 */
429
+	public function remove_reg_step($reg_step_slug = '', $reset = true)
430
+	{
431
+		unset($this->reg_steps[ $reg_step_slug ]);
432
+		if ($this->transaction instanceof EE_Transaction) {
433
+			// now remove reg step from TXN and save
434
+			$this->transaction->remove_reg_step($reg_step_slug);
435
+			$this->transaction->save();
436
+		}
437
+		if ($reset) {
438
+			$this->reset_reg_steps();
439
+		}
440
+	}
441
+
442
+
443
+	/**
444
+	 *    set_reg_step_order
445
+	 *
446
+	 * @access    public
447
+	 * @param string $reg_step_slug
448
+	 * @param int    $order
449
+	 * @return    void
450
+	 */
451
+	public function set_reg_step_order($reg_step_slug = '', $order = 100)
452
+	{
453
+		if (isset($this->reg_steps[ $reg_step_slug ])) {
454
+			$this->reg_steps[ $reg_step_slug ]->set_order($order);
455
+		}
456
+	}
457
+
458
+
459
+	/**
460
+	 *    set_current_step
461
+	 *
462
+	 * @access    public
463
+	 * @param string $current_step
464
+	 * @return    void
465
+	 */
466
+	public function set_current_step($current_step)
467
+	{
468
+		// grab what step we're on
469
+		$this->current_step = isset($this->reg_steps[ $current_step ])
470
+			? $this->reg_steps[ $current_step ]
471
+			: reset(
472
+				$this->reg_steps
473
+			);
474
+		// verify instance
475
+		if ($this->current_step instanceof EE_SPCO_Reg_Step) {
476
+			// we don't want to repeat completed steps if this is the first time through SPCO
477
+			if ($this->continue_reg && ! $this->revisit && $this->current_step->completed()) {
478
+				// so advance to the next step
479
+				$this->set_next_step();
480
+				if ($this->next_step instanceof EE_SPCO_Reg_Step) {
481
+					// and attempt to set it as the current step
482
+					$this->set_current_step($this->next_step->slug());
483
+				}
484
+				return;
485
+			}
486
+			$this->current_step->set_is_current_step(true);
487
+		} else {
488
+			EE_Error::add_error(
489
+				__('The current step could not be set.', 'event_espresso'),
490
+				__FILE__,
491
+				__FUNCTION__,
492
+				__LINE__
493
+			);
494
+		}
495
+	}
496
+
497
+
498
+	/**
499
+	 *    set_next_step
500
+	 * advances the reg_steps array pointer and sets the next step, then reverses pointer back to the current step
501
+	 *
502
+	 * @access    public
503
+	 * @return    void
504
+	 */
505
+	public function set_next_step()
506
+	{
507
+		// set pointer to start of array
508
+		reset($this->reg_steps);
509
+		// if there is more than one step
510
+		if (count($this->reg_steps) > 1) {
511
+			// advance to the current step and set pointer
512
+			while (key($this->reg_steps) !== $this->current_step->slug() && key($this->reg_steps) !== '') {
513
+				next($this->reg_steps);
514
+			}
515
+		}
516
+		// advance one more spot ( if it exists )
517
+		$this->next_step = next($this->reg_steps);
518
+		// verify instance
519
+		$this->next_step = $this->next_step instanceof EE_SPCO_Reg_Step ? $this->next_step : null;
520
+		// then back to current step to reset
521
+		prev($this->reg_steps);
522
+	}
523
+
524
+
525
+	/**
526
+	 *    get_next_reg_step
527
+	 *    this simply returns the next step from reg_steps array
528
+	 *
529
+	 * @access    public
530
+	 * @return    EE_SPCO_Reg_Step | null
531
+	 */
532
+	public function get_next_reg_step()
533
+	{
534
+		$next = next($this->reg_steps);
535
+		prev($this->reg_steps);
536
+		return $next instanceof EE_SPCO_Reg_Step ? $next : null;
537
+	}
538
+
539
+
540
+	/**
541
+	 * get_prev_reg_step
542
+	 *    this simply returns the previous step from reg_steps array
543
+	 *
544
+	 * @access    public
545
+	 * @return    EE_SPCO_Reg_Step | null
546
+	 */
547
+	public function get_prev_reg_step()
548
+	{
549
+		$prev = prev($this->reg_steps);
550
+		next($this->reg_steps);
551
+		return $prev instanceof EE_SPCO_Reg_Step ? $prev : null;
552
+	}
553
+
554
+
555
+	/**
556
+	 * sort_reg_steps
557
+	 *
558
+	 * @access public
559
+	 * @return void
560
+	 */
561
+	public function sort_reg_steps()
562
+	{
563
+		$reg_step_sorting_callback = apply_filters(
564
+			'FHEE__EE_Checkout__sort_reg_steps__reg_step_sorting_callback',
565
+			'reg_step_sorting_callback'
566
+		);
567
+		uasort($this->reg_steps, array($this, $reg_step_sorting_callback));
568
+	}
569
+
570
+
571
+	/**
572
+	 * find_reg_step
573
+	 * finds a reg step by the given slug
574
+	 *
575
+	 * @access    public
576
+	 * @param string $reg_step_slug
577
+	 * @return EE_SPCO_Reg_Step|null
578
+	 */
579
+	public function find_reg_step($reg_step_slug = '')
580
+	{
581
+		if (! empty($reg_step_slug)) {
582
+			// copy reg step array
583
+			$reg_steps = $this->reg_steps;
584
+			// set pointer to start of array
585
+			reset($reg_steps);
586
+			// if there is more than one step
587
+			if (count($reg_steps) > 1) {
588
+				// advance to the current step and set pointer
589
+				while (key($reg_steps) !== $reg_step_slug && key($reg_steps) !== '') {
590
+					next($reg_steps);
591
+				}
592
+				return current($reg_steps);
593
+			}
594
+		}
595
+		return null;
596
+	}
597
+
598
+
599
+	/**
600
+	 * reg_step_sorting_callback
601
+	 *
602
+	 * @access public
603
+	 * @param EE_SPCO_Reg_Step $reg_step_A
604
+	 * @param EE_SPCO_Reg_Step $reg_step_B
605
+	 * @return int
606
+	 */
607
+	public function reg_step_sorting_callback(EE_SPCO_Reg_Step $reg_step_A, EE_SPCO_Reg_Step $reg_step_B)
608
+	{
609
+		// send finalize_registration step to the end of the array
610
+		if ($reg_step_A->slug() === 'finalize_registration') {
611
+			return 1;
612
+		} elseif ($reg_step_B->slug() === 'finalize_registration') {
613
+			return -1;
614
+		}
615
+		if ($reg_step_A->order() === $reg_step_B->order()) {
616
+			return 0;
617
+		}
618
+		return ($reg_step_A->order() > $reg_step_B->order()) ? 1 : -1;
619
+	}
620
+
621
+
622
+	/**
623
+	 * set_reg_step_initiated
624
+	 *
625
+	 * @access    public
626
+	 * @param    EE_SPCO_Reg_Step $reg_step
627
+	 * @throws \EE_Error
628
+	 */
629
+	public function set_reg_step_initiated(EE_SPCO_Reg_Step $reg_step)
630
+	{
631
+		// call set_reg_step_initiated ???
632
+		if (
633 633
 // first time visiting SPCO ?
634
-            ! $this->revisit
635
-            && (
636
-                // and displaying the reg step form for the first time ?
637
-                $this->action === 'display_spco_reg_step'
638
-                // or initializing the final step
639
-                || $reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration
640
-            )
641
-        ) {
642
-            // set the start time for this reg step
643
-            if (! $this->transaction->set_reg_step_initiated($reg_step->slug())) {
644
-                if (WP_DEBUG) {
645
-                    EE_Error::add_error(
646
-                        sprintf(
647
-                            __('The "%1$s" registration step was not initialized properly.', 'event_espresso'),
648
-                            $reg_step->name()
649
-                        ),
650
-                        __FILE__,
651
-                        __FUNCTION__,
652
-                        __LINE__
653
-                    );
654
-                }
655
-            }
656
-        }
657
-    }
658
-
659
-
660
-    /**
661
-     *    set_reg_step_JSON_info
662
-     *
663
-     * @access public
664
-     * @return    void
665
-     */
666
-    public function set_reg_step_JSON_info()
667
-    {
668
-        EE_Registry::$i18n_js_strings['reg_steps'] = array();
669
-        // pass basic reg step data to JS
670
-        foreach ($this->reg_steps as $reg_step) {
671
-            EE_Registry::$i18n_js_strings['reg_steps'][] = $reg_step->slug();
672
-        }
673
-        // reset reg step html
674
-        // $this->json_response->set_reg_step_html('');
675
-    }
676
-
677
-
678
-    /**
679
-     *    reset_reg_steps
680
-     *
681
-     * @access public
682
-     * @return void
683
-     */
684
-    public function reset_reg_steps()
685
-    {
686
-        $this->sort_reg_steps();
687
-        $this->set_current_step(EE_Registry::instance()->REQ->get('step'));
688
-        $this->set_next_step();
689
-        // the text that appears on the reg step form submit button
690
-        $this->current_step->set_submit_button_text();
691
-        $this->set_reg_step_JSON_info();
692
-    }
693
-
694
-
695
-    /**
696
-     *    get_registration_time_limit
697
-     *
698
-     * @access    public
699
-     * @return        string
700
-     */
701
-    public function get_registration_time_limit()
702
-    {
703
-
704
-        $registration_time_limit = (float) (EE_Registry::instance()->SSN->expiration() - time());
705
-        $time_limit_format = $registration_time_limit > 60 * MINUTE_IN_SECONDS ? 'H:i:s' : 'i:s';
706
-        $registration_time_limit = date($time_limit_format, $registration_time_limit);
707
-        return apply_filters(
708
-            'FHEE__EE_Checkout__get_registration_time_limit__registration_time_limit',
709
-            $registration_time_limit
710
-        );
711
-    }
712
-
713
-
714
-    /**
715
-     * payment_required
716
-     *
717
-     * @return boolean
718
-     */
719
-    public function payment_required()
720
-    {
721
-        // if NOT:
722
-        //     registration via admin
723
-        //      completed TXN
724
-        //      overpaid TXN
725
-        //      free TXN(total = 0.00)
726
-        //      then payment required is TRUE
727
-        return ! ($this->admin_request
728
-                  || $this->transaction->is_completed()
729
-                  || $this->transaction->is_overpaid()
730
-                  || $this->transaction->is_free()) ? true : false;
731
-    }
732
-
733
-
734
-    /**
735
-     * get_cart_for_transaction
736
-     *
737
-     * @access public
738
-     * @param EE_Transaction $transaction
739
-     * @return EE_Cart
740
-     */
741
-    public function get_cart_for_transaction($transaction)
742
-    {
743
-        $session = EE_Registry::instance()->load_core('Session');
744
-        $cart = $transaction instanceof EE_Transaction ? EE_Cart::get_cart_from_txn($transaction, $session) : null;
745
-        // verify cart
746
-        if (! $cart instanceof EE_Cart) {
747
-            $cart = EE_Registry::instance()->load_core('Cart');
748
-        }
749
-
750
-        return $cart;
751
-    }
752
-
753
-
754
-    /**
755
-     *    initialize_txn_reg_steps_array
756
-     *
757
-     * @access public
758
-     * @return    array
759
-     */
760
-    public function initialize_txn_reg_steps_array()
761
-    {
762
-        $txn_reg_steps_array = array();
763
-        foreach ($this->reg_steps as $reg_step) {
764
-            $txn_reg_steps_array[ $reg_step->slug() ] = false;
765
-        }
766
-        return $txn_reg_steps_array;
767
-    }
768
-
769
-
770
-    /**
771
-     *    update_txn_reg_steps_array
772
-     *
773
-     * @access public
774
-     * @return    bool
775
-     * @throws \EE_Error
776
-     */
777
-    public function update_txn_reg_steps_array()
778
-    {
779
-        $updated = false;
780
-        foreach ($this->reg_steps as $reg_step) {
781
-            if ($reg_step->completed()) {
782
-                $updated = $this->transaction->set_reg_step_completed($reg_step->slug())
783
-                    ? true
784
-                    : $updated;
785
-            }
786
-        }
787
-        if ($updated) {
788
-            $this->transaction->save();
789
-        }
790
-        return $updated;
791
-    }
792
-
793
-
794
-    /**
795
-     *    stash_transaction_and_checkout
796
-     *
797
-     * @access public
798
-     * @return    void
799
-     * @throws \EE_Error
800
-     */
801
-    public function stash_transaction_and_checkout()
802
-    {
803
-        if (! $this->revisit) {
804
-            $this->update_txn_reg_steps_array();
805
-        }
806
-        $this->track_transaction_and_registration_status_updates();
807
-        // save all data to the db, but suppress errors
808
-        // $this->save_all_data( FALSE );
809
-        // cache the checkout in the session
810
-        EE_Registry::instance()->SSN->set_checkout($this);
811
-    }
812
-
813
-
814
-    /**
815
-     *    track_transaction_and_registration_status_updates
816
-     *    stores whether any updates were made to the TXN or it's related registrations
817
-     *
818
-     * @access public
819
-     * @return void
820
-     * @throws \EE_Error
821
-     */
822
-    public function track_transaction_and_registration_status_updates()
823
-    {
824
-        // verify the transaction
825
-        if ($this->transaction instanceof EE_Transaction) {
826
-            // has there been a TXN status change during this checkout?
827
-            $this->txn_status_updated = $this->transaction->txn_status_updated();
828
-            /** @type EE_Registration_Processor $registration_processor */
829
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
830
-            // grab the saved registrations from the transaction
831
-            foreach ($this->transaction->registrations($this->reg_cache_where_params) as $registration) {
832
-                if ($registration_processor->reg_status_updated($registration->ID())) {
833
-                    $this->set_reg_status_updated($registration->ID(), true);
834
-                }
835
-            }
836
-        }
837
-    }
838
-
839
-
840
-    /**
841
-     *    visit_allows_processing_of_this_registration
842
-     *    determines if the current SPCO visit should allow the passed EE_Registration to be used in processing.
843
-     *    one of the following conditions must be met:
844
-     *        EITHER:    A) first time thru SPCO -> process ALL registrations ( NOT a revisit )
845
-     *        OR :        B) primary registrant is editing info -> process ALL registrations ( primary_revisit )
846
-     *        OR :        C) another registrant is editing info -> ONLY process their registration ( revisit AND their
847
-     *        reg_url_link matches )
848
-     *
849
-     * @access public
850
-     * @param    EE_Registration $registration
851
-     * @return    bool
852
-     * @throws \EE_Error
853
-     */
854
-    public function visit_allows_processing_of_this_registration(EE_Registration $registration)
855
-    {
856
-        return ! $this->revisit
857
-               || $this->primary_revisit
858
-               || (
859
-                   $this->revisit && $this->reg_url_link === $registration->reg_url_link()
860
-               )
861
-            ? true
862
-            : false;
863
-    }
864
-
865
-
866
-    /**
867
-     *    _transaction_has_primary_registration
868
-     *
869
-     * @access        private
870
-     * @return        bool
871
-     */
872
-    public function transaction_has_primary_registrant()
873
-    {
874
-        return $this->primary_attendee_obj instanceof EE_Attendee ? true : false;
875
-    }
876
-
877
-
878
-    /**
879
-     *    save_all_data
880
-     *    simply loops through the current transaction and saves all data for each registration
881
-     *
882
-     * @access public
883
-     * @param bool $show_errors
884
-     * @return bool
885
-     * @throws \EE_Error
886
-     */
887
-    public function save_all_data($show_errors = true)
888
-    {
889
-        // verify the transaction
890
-        if ($this->transaction instanceof EE_Transaction) {
891
-            // save to ensure that TXN has ID
892
-            $this->transaction->save();
893
-            // grab the saved registrations from the transaction
894
-            foreach ($this->transaction->registrations($this->reg_cache_where_params) as $registration) {
895
-                $this->_save_registration($registration, $show_errors);
896
-            }
897
-        } else {
898
-            if ($show_errors) {
899
-                EE_Error::add_error(
900
-                    __(
901
-                        'A valid Transaction was not found when attempting to save your registration information.',
902
-                        'event_espresso'
903
-                    ),
904
-                    __FILE__,
905
-                    __FUNCTION__,
906
-                    __LINE__
907
-                );
908
-            }
909
-            return false;
910
-        }
911
-        return true;
912
-    }
913
-
914
-
915
-    /**
916
-     * _save_registration_attendee
917
-     *
918
-     * @param    EE_Registration $registration
919
-     * @param bool               $show_errors
920
-     * @return void
921
-     * @throws \EE_Error
922
-     */
923
-    private function _save_registration($registration, $show_errors = true)
924
-    {
925
-        // verify object
926
-        if ($registration instanceof EE_Registration) {
927
-            // should this registration be processed during this visit ?
928
-            if ($this->visit_allows_processing_of_this_registration($registration)) {
929
-                // set TXN ID
930
-                if (! $registration->transaction_ID()) {
931
-                    $registration->set_transaction_id($this->transaction->ID());
932
-                }
933
-                // verify and save the attendee
934
-                $this->_save_registration_attendee($registration, $show_errors);
935
-                // save answers to reg form questions
936
-                $this->_save_registration_answers($registration, $show_errors);
937
-                // save changes
938
-                $registration->save();
939
-                // update txn cache
940
-                if (! $this->transaction->update_cache_after_object_save('Registration', $registration)) {
941
-                    if ($show_errors) {
942
-                        EE_Error::add_error(
943
-                            __(
944
-                                'The newly saved Registration object could not be cached on the Transaction.',
945
-                                'event_espresso'
946
-                            ),
947
-                            __FILE__,
948
-                            __FUNCTION__,
949
-                            __LINE__
950
-                        );
951
-                    }
952
-                }
953
-            }
954
-        } else {
955
-            if ($show_errors) {
956
-                EE_Error::add_error(
957
-                    __(
958
-                        'An invalid Registration object was discovered when attempting to save your registration information.',
959
-                        'event_espresso'
960
-                    ),
961
-                    __FILE__,
962
-                    __FUNCTION__,
963
-                    __LINE__
964
-                );
965
-            }
966
-        }
967
-    }
968
-
969
-
970
-    /**
971
-     * _save_registration_attendee
972
-     *
973
-     * @param    EE_Registration $registration
974
-     * @param bool               $show_errors
975
-     * @return void
976
-     * @throws \EE_Error
977
-     */
978
-    private function _save_registration_attendee($registration, $show_errors = true)
979
-    {
980
-        if ($registration->attendee() instanceof EE_Attendee) {
981
-            // save so that ATT has ID
982
-            $registration->attendee()->save();
983
-            if (! $registration->update_cache_after_object_save('Attendee', $registration->attendee())) {
984
-                if ($show_errors) {
985
-                    EE_Error::add_error(
986
-                        __(
987
-                            'The newly saved Attendee object could not be cached on the registration.',
988
-                            'event_espresso'
989
-                        ),
990
-                        __FILE__,
991
-                        __FUNCTION__,
992
-                        __LINE__
993
-                    );
994
-                }
995
-            }
996
-        } else {
997
-            if ($show_errors) {
998
-                EE_Error::add_error(
999
-                    sprintf(
1000
-                        '%1$s||%1$s $attendee = %2$s',
1001
-                        __(
1002
-                            'Either no Attendee information was found, or an invalid Attendee object was discovered when attempting to save your registration information.',
1003
-                            'event_espresso'
1004
-                        ),
1005
-                        var_export($registration->attendee(), true)
1006
-                    ),
1007
-                    __FILE__,
1008
-                    __FUNCTION__,
1009
-                    __LINE__
1010
-                );
1011
-            }
1012
-        }
1013
-    }
1014
-
1015
-
1016
-    /**
1017
-     * _save_question_answers
1018
-     *
1019
-     * @param    EE_Registration $registration
1020
-     * @param bool               $show_errors
1021
-     * @return void
1022
-     * @throws \EE_Error
1023
-     */
1024
-    private function _save_registration_answers($registration, $show_errors = true)
1025
-    {
1026
-        // now save the answers
1027
-        foreach ($registration->answers() as $cache_key => $answer) {
1028
-            // verify object
1029
-            if ($answer instanceof EE_Answer) {
1030
-                $answer->set_registration($registration->ID());
1031
-                $answer->save();
1032
-                if (! $registration->update_cache_after_object_save('Answer', $answer, $cache_key)) {
1033
-                    if ($show_errors) {
1034
-                        EE_Error::add_error(
1035
-                            __(
1036
-                                'The newly saved Answer object could not be cached on the registration.',
1037
-                                'event_espresso'
1038
-                            ),
1039
-                            __FILE__,
1040
-                            __FUNCTION__,
1041
-                            __LINE__
1042
-                        );
1043
-                    }
1044
-                }
1045
-            } else {
1046
-                if ($show_errors) {
1047
-                    EE_Error::add_error(
1048
-                        __(
1049
-                            'An invalid Answer object was discovered when attempting to save your registration information.',
1050
-                            'event_espresso'
1051
-                        ),
1052
-                        __FILE__,
1053
-                        __FUNCTION__,
1054
-                        __LINE__
1055
-                    );
1056
-                }
1057
-            }
1058
-        }
1059
-    }
1060
-
1061
-
1062
-    /**
1063
-     *    refresh_all_entities
1064
-     *   will either refresh the entity map with objects form the db or from the checkout cache
1065
-     *
1066
-     * @access public
1067
-     * @param bool $from_db
1068
-     * @return bool
1069
-     * @throws \EE_Error
1070
-     */
1071
-    public function refresh_all_entities($from_db = false)
1072
-    {
1073
-        $from_db = $this->current_step->is_final_step() || $this->action === 'process_gateway_response'
1074
-            ? true
1075
-            : $from_db;
1076
-        // $this->log(
1077
-        //     __CLASS__,
1078
-        //     __FUNCTION__,
1079
-        //     __LINE__,
1080
-        //     array('from_db' => $from_db)
1081
-        // );
1082
-        return $from_db ? $this->refresh_from_db() : $this->refresh_entity_map();
1083
-    }
1084
-
1085
-
1086
-    /**
1087
-     *  refresh_entity_map
1088
-     *  simply loops through the current transaction and updates each
1089
-     *  model's entity map using EEM_Base::refresh_entity_map_from_db()
1090
-     *
1091
-     * @access public
1092
-     * @return bool
1093
-     * @throws \EE_Error
1094
-     */
1095
-    protected function refresh_from_db()
1096
-    {
1097
-        // verify the transaction
1098
-        if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1099
-            // pull fresh TXN data from the db
1100
-            $this->transaction = $this->transaction->get_model()->refresh_entity_map_from_db($this->transaction->ID());
1101
-            // update EE_Checkout's cached primary_attendee object
1102
-            $this->primary_attendee_obj = $this->_refresh_primary_attendee_obj_from_db($this->transaction);
1103
-            // update EE_Checkout's cached payment object
1104
-            $payment = $this->transaction->last_payment();
1105
-            $this->payment = $payment instanceof EE_Payment ? $payment : $this->payment;
1106
-            // update EE_Checkout's cached payment_method object
1107
-            $payment_method = $this->payment instanceof EE_Payment ? $this->payment->payment_method() : null;
1108
-            $this->payment_method = $payment_method instanceof EE_Payment_Method ? $payment_method
1109
-                : $this->payment_method;
1110
-            // now refresh the cart, based on the TXN
1111
-            $this->cart = $this->get_cart_for_transaction($this->transaction);
1112
-        } else {
1113
-            EE_Error::add_error(
1114
-                __(
1115
-                    'A valid Transaction was not found when attempting to update the model entity mapper.',
1116
-                    'event_espresso'
1117
-                ),
1118
-                __FILE__,
1119
-                __FUNCTION__,
1120
-                __LINE__
1121
-            );
1122
-            return false;
1123
-        }
1124
-        return true;
1125
-    }
1126
-
1127
-
1128
-    /**
1129
-     * _refresh_primary_attendee_obj_from_db
1130
-     *
1131
-     * @param   EE_Transaction $transaction
1132
-     * @return  EE_Attendee | null
1133
-     * @throws \EE_Error
1134
-     */
1135
-    protected function _refresh_primary_attendee_obj_from_db(EE_Transaction $transaction)
1136
-    {
1137
-
1138
-        $primary_attendee_obj = null;
1139
-        // grab the saved registrations from the transaction
1140
-        foreach ($transaction->registrations($this->reg_cache_where_params, true) as $registration) {
1141
-            // verify object
1142
-            if ($registration instanceof EE_Registration) {
1143
-                $attendee = $registration->attendee();
1144
-                // verify object && maybe cache primary_attendee_obj ?
1145
-                if ($attendee instanceof EE_Attendee && $registration->is_primary_registrant()) {
1146
-                    $primary_attendee_obj = $attendee;
1147
-                }
1148
-            } else {
1149
-                EE_Error::add_error(
1150
-                    __(
1151
-                        'An invalid Registration object was discovered when attempting to update the model entity mapper.',
1152
-                        'event_espresso'
1153
-                    ),
1154
-                    __FILE__,
1155
-                    __FUNCTION__,
1156
-                    __LINE__
1157
-                );
1158
-            }
1159
-        }
1160
-        return $primary_attendee_obj;
1161
-    }
1162
-
1163
-
1164
-    /**
1165
-     *  refresh_entity_map
1166
-     *  simply loops through the current transaction and updates
1167
-     *  each model's entity map using EEM_Base::refresh_entity_map_with()
1168
-     *
1169
-     * @access public
1170
-     * @return bool
1171
-     * @throws \EE_Error
1172
-     */
1173
-    protected function refresh_entity_map()
1174
-    {
1175
-        // verify the transaction
1176
-        if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1177
-            // never cache payment info
1178
-            $this->transaction->clear_cache('Payment');
1179
-            // is the Payment Options Reg Step completed ?
1180
-            if ($this->transaction->reg_step_completed('payment_options')) {
1181
-                // then check for payments and update TXN accordingly
1182
-                /** @type EE_Transaction_Payments $transaction_payments */
1183
-                $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1184
-                $transaction_payments->calculate_total_payments_and_update_status($this->transaction);
1185
-            }
1186
-            // grab the saved registrations from the transaction
1187
-            foreach ($this->transaction->registrations($this->reg_cache_where_params) as $reg_cache_ID => $registration) {
1188
-                $this->_refresh_registration($reg_cache_ID, $registration);
1189
-            }
1190
-            // make sure our cached TXN is added to the model entity mapper
1191
-            $this->transaction = $this->transaction->get_model()->refresh_entity_map_with(
1192
-                $this->transaction->ID(),
1193
-                $this->transaction
1194
-            );
1195
-        } else {
1196
-            EE_Error::add_error(
1197
-                __(
1198
-                    'A valid Transaction was not found when attempting to update the model entity mapper.',
1199
-                    'event_espresso'
1200
-                ),
1201
-                __FILE__,
1202
-                __FUNCTION__,
1203
-                __LINE__
1204
-            );
1205
-            return false;
1206
-        }
1207
-        // verify and update the cart because inaccurate totals are not so much fun
1208
-        if ($this->cart instanceof EE_Cart) {
1209
-            $grand_total = $this->cart->get_grand_total();
1210
-            if ($grand_total instanceof EE_Line_Item && $grand_total->ID()) {
1211
-                $grand_total->recalculate_total_including_taxes();
1212
-                $grand_total = $grand_total->get_model()->refresh_entity_map_with(
1213
-                    $this->cart->get_grand_total()->ID(),
1214
-                    $this->cart->get_grand_total()
1215
-                );
1216
-            }
1217
-            if ($grand_total instanceof EE_Line_Item) {
1218
-                $this->cart = EE_Cart::instance($grand_total);
1219
-            } else {
1220
-                EE_Error::add_error(
1221
-                    __(
1222
-                        'A valid Cart was not found when attempting to update the model entity mapper.',
1223
-                        'event_espresso'
1224
-                    ),
1225
-                    __FILE__,
1226
-                    __FUNCTION__,
1227
-                    __LINE__
1228
-                );
1229
-                return false;
1230
-            }
1231
-        }
1232
-        return true;
1233
-    }
1234
-
1235
-
1236
-    /**
1237
-     * _refresh_registration
1238
-     *
1239
-     * @param    string | int    $reg_cache_ID
1240
-     * @param    EE_Registration $registration
1241
-     * @return void
1242
-     * @throws \EE_Error
1243
-     */
1244
-    protected function _refresh_registration($reg_cache_ID, $registration)
1245
-    {
1246
-
1247
-        // verify object
1248
-        if ($registration instanceof EE_Registration) {
1249
-            // update the entity mapper attendee
1250
-            $this->_refresh_registration_attendee($registration);
1251
-            // update the entity mapper answers for reg form questions
1252
-            $this->_refresh_registration_answers($registration);
1253
-            // make sure the cached registration is added to the model entity mapper
1254
-            $registration->get_model()->refresh_entity_map_with($reg_cache_ID, $registration);
1255
-        } else {
1256
-            EE_Error::add_error(
1257
-                __(
1258
-                    'An invalid Registration object was discovered when attempting to update the model entity mapper.',
1259
-                    'event_espresso'
1260
-                ),
1261
-                __FILE__,
1262
-                __FUNCTION__,
1263
-                __LINE__
1264
-            );
1265
-        }
1266
-    }
1267
-
1268
-
1269
-    /**
1270
-     * _save_registration_attendee
1271
-     *
1272
-     * @param    EE_Registration $registration
1273
-     * @return void
1274
-     * @throws \EE_Error
1275
-     */
1276
-    protected function _refresh_registration_attendee($registration)
1277
-    {
1278
-
1279
-        $attendee = $registration->attendee();
1280
-        // verify object
1281
-        if ($attendee instanceof EE_Attendee && $attendee->ID()) {
1282
-            // make sure the cached attendee is added to the model entity mapper
1283
-            $registration->attendee()->get_model()->refresh_entity_map_with($attendee->ID(), $attendee);
1284
-            // maybe cache primary_attendee_obj ?
1285
-            if ($registration->is_primary_registrant()) {
1286
-                $this->primary_attendee_obj = $attendee;
1287
-            }
1288
-        }
1289
-    }
1290
-
1291
-
1292
-    /**
1293
-     * _refresh_registration_answers
1294
-     *
1295
-     * @param    EE_Registration $registration
1296
-     * @return void
1297
-     * @throws \EE_Error
1298
-     */
1299
-    protected function _refresh_registration_answers($registration)
1300
-    {
1301
-
1302
-        // now update the answers
1303
-        foreach ($registration->answers() as $cache_key => $answer) {
1304
-            // verify object
1305
-            if ($answer instanceof EE_Answer) {
1306
-                if ($answer->ID()) {
1307
-                    // make sure the cached answer is added to the model entity mapper
1308
-                    $answer->get_model()->refresh_entity_map_with($answer->ID(), $answer);
1309
-                }
1310
-            } else {
1311
-                EE_Error::add_error(
1312
-                    __(
1313
-                        'An invalid Answer object was discovered when attempting to update the model entity mapper.',
1314
-                        'event_espresso'
1315
-                    ),
1316
-                    __FILE__,
1317
-                    __FUNCTION__,
1318
-                    __LINE__
1319
-                );
1320
-            }
1321
-        }
1322
-    }
1323
-
1324
-
1325
-    /**
1326
-     *    __sleep
1327
-     * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon
1328
-     * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the
1329
-     * reg form, because if needed, it will be regenerated anyways
1330
-     *
1331
-     * @return array
1332
-     * @throws \EE_Error
1333
-     */
1334
-    public function __sleep()
1335
-    {
1336
-        if ($this->primary_attendee_obj instanceof EE_Attendee && $this->primary_attendee_obj->ID()) {
1337
-            $this->primary_attendee_obj = $this->primary_attendee_obj->ID();
1338
-        }        // remove the reg form and the checkout
1339
-        if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1340
-            $this->transaction = $this->transaction->ID();
1341
-        }        // remove the reg form and the checkout
1342
-        return array_diff(array_keys(get_object_vars($this)), array('billing_form', 'registration_form'));
1343
-    }
1344
-
1345
-
1346
-    /**
1347
-     *    __wakeup
1348
-     * to conserve db space, we are removing the EE_Checkout object from EE_SPCO_Reg_Step objects upon serialization
1349
-     * this will reinstate the EE_Checkout object on each EE_SPCO_Reg_Step object
1350
-     */
1351
-    public function __wakeup()
1352
-    {
1353
-        if (! $this->primary_attendee_obj instanceof EE_Attendee && absint($this->primary_attendee_obj) !== 0) {
1354
-            // $this->primary_attendee_obj is actually just an ID, so use it to get the object from the db
1355
-            $this->primary_attendee_obj = EEM_Attendee::instance()->get_one_by_ID($this->primary_attendee_obj);
1356
-        }
1357
-        if (! $this->transaction instanceof EE_Transaction && absint($this->transaction) !== 0) {
1358
-            // $this->transaction is actually just an ID, so use it to get the object from the db
1359
-            $this->transaction = EEM_Transaction::instance()->get_one_by_ID($this->transaction);
1360
-        }
1361
-        foreach ($this->reg_steps as $reg_step) {
1362
-            $reg_step->checkout = $this;
1363
-        }
1364
-    }
1365
-
1366
-
1367
-    /**
1368
-     * debug
1369
-     *
1370
-     * @param string $class
1371
-     * @param string $func
1372
-     * @param string $line
1373
-     * @param array  $info
1374
-     * @param bool   $display_request
1375
-     * @throws \EE_Error
1376
-     */
1377
-    public function log($class = '', $func = '', $line = '', $info = array(), $display_request = false)
1378
-    {
1379
-        $disabled = true;
1380
-        if (WP_DEBUG && ! $disabled) {
1381
-            $debug_data = get_option('EE_DEBUG_SPCO_' . EE_Session::instance()->id(), array());
1382
-            $default_data = array(
1383
-                $class                    => $func . '() : ' . $line,
1384
-                'request->step'           => $this->step,
1385
-                'request->action'         => $this->action,
1386
-                'current_step->slug'      => $this->current_step instanceof EE_SPCO_Reg_Step ?
1387
-                    $this->current_step->slug() : '',
1388
-                'current_step->completed' => $this->current_step instanceof EE_SPCO_Reg_Step ?
1389
-                    $this->current_step->completed() : '',
1390
-                'txn_status_updated'      => $this->transaction->txn_status_updated(),
1391
-                'reg_status_updated'      => $this->reg_status_updated,
1392
-                'reg_url_link'            => $this->reg_url_link,
1393
-                'REQ'                     => $display_request ? $_REQUEST : '',
1394
-            );
1395
-            if ($this->transaction instanceof EE_Transaction) {
1396
-                $default_data['TXN_status'] = $this->transaction->status_ID();
1397
-                $default_data['TXN_reg_steps'] = $this->transaction->reg_steps();
1398
-                foreach ($this->transaction->registrations($this->reg_cache_where_params) as $REG_ID => $registration) {
1399
-                    $default_data['registrations'][ $REG_ID ] = $registration->status_ID();
1400
-                }
1401
-                if ($this->transaction->ID()) {
1402
-                    $TXN_ID = 'EE_Transaction: ' . $this->transaction->ID();
1403
-                    // don't serialize objects
1404
-                    $info = $this->_strip_objects($info);
1405
-                    if (! isset($debug_data[ $TXN_ID ])) {
1406
-                        $debug_data[ $TXN_ID ] = array();
1407
-                    }
1408
-                    $debug_data[ $TXN_ID ][ microtime() ] = array_merge(
1409
-                        $default_data,
1410
-                        $info
1411
-                    );
1412
-                    update_option('EE_DEBUG_SPCO_' . EE_Session::instance()->id(), $debug_data);
1413
-                }
1414
-            }
1415
-        }
1416
-    }
1417
-
1418
-
1419
-    /**
1420
-     * _strip_objects
1421
-     *
1422
-     * @param array $info
1423
-     * @return array
1424
-     */
1425
-    public function _strip_objects($info = array())
1426
-    {
1427
-        foreach ((array) $info as $key => $value) {
1428
-            if (is_array($value)) {
1429
-                $info[ $key ] = $this->_strip_objects($value);
1430
-            } elseif (is_object($value)) {
1431
-                $object_class = get_class($value);
1432
-                $info[ $object_class ] = array();
1433
-                $info[ $object_class ]['ID'] = method_exists($value, 'ID') ? $value->ID() : 0;
1434
-                if (method_exists($value, 'status')) {
1435
-                    $info[ $object_class ]['status'] = $value->status();
1436
-                } elseif (method_exists($value, 'status_ID')) {
1437
-                    $info[ $object_class ]['status'] = $value->status_ID();
1438
-                }
1439
-                unset($info[ $key ]);
1440
-            }
1441
-        }
1442
-        return (array) $info;
1443
-    }
634
+			! $this->revisit
635
+			&& (
636
+				// and displaying the reg step form for the first time ?
637
+				$this->action === 'display_spco_reg_step'
638
+				// or initializing the final step
639
+				|| $reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration
640
+			)
641
+		) {
642
+			// set the start time for this reg step
643
+			if (! $this->transaction->set_reg_step_initiated($reg_step->slug())) {
644
+				if (WP_DEBUG) {
645
+					EE_Error::add_error(
646
+						sprintf(
647
+							__('The "%1$s" registration step was not initialized properly.', 'event_espresso'),
648
+							$reg_step->name()
649
+						),
650
+						__FILE__,
651
+						__FUNCTION__,
652
+						__LINE__
653
+					);
654
+				}
655
+			}
656
+		}
657
+	}
658
+
659
+
660
+	/**
661
+	 *    set_reg_step_JSON_info
662
+	 *
663
+	 * @access public
664
+	 * @return    void
665
+	 */
666
+	public function set_reg_step_JSON_info()
667
+	{
668
+		EE_Registry::$i18n_js_strings['reg_steps'] = array();
669
+		// pass basic reg step data to JS
670
+		foreach ($this->reg_steps as $reg_step) {
671
+			EE_Registry::$i18n_js_strings['reg_steps'][] = $reg_step->slug();
672
+		}
673
+		// reset reg step html
674
+		// $this->json_response->set_reg_step_html('');
675
+	}
676
+
677
+
678
+	/**
679
+	 *    reset_reg_steps
680
+	 *
681
+	 * @access public
682
+	 * @return void
683
+	 */
684
+	public function reset_reg_steps()
685
+	{
686
+		$this->sort_reg_steps();
687
+		$this->set_current_step(EE_Registry::instance()->REQ->get('step'));
688
+		$this->set_next_step();
689
+		// the text that appears on the reg step form submit button
690
+		$this->current_step->set_submit_button_text();
691
+		$this->set_reg_step_JSON_info();
692
+	}
693
+
694
+
695
+	/**
696
+	 *    get_registration_time_limit
697
+	 *
698
+	 * @access    public
699
+	 * @return        string
700
+	 */
701
+	public function get_registration_time_limit()
702
+	{
703
+
704
+		$registration_time_limit = (float) (EE_Registry::instance()->SSN->expiration() - time());
705
+		$time_limit_format = $registration_time_limit > 60 * MINUTE_IN_SECONDS ? 'H:i:s' : 'i:s';
706
+		$registration_time_limit = date($time_limit_format, $registration_time_limit);
707
+		return apply_filters(
708
+			'FHEE__EE_Checkout__get_registration_time_limit__registration_time_limit',
709
+			$registration_time_limit
710
+		);
711
+	}
712
+
713
+
714
+	/**
715
+	 * payment_required
716
+	 *
717
+	 * @return boolean
718
+	 */
719
+	public function payment_required()
720
+	{
721
+		// if NOT:
722
+		//     registration via admin
723
+		//      completed TXN
724
+		//      overpaid TXN
725
+		//      free TXN(total = 0.00)
726
+		//      then payment required is TRUE
727
+		return ! ($this->admin_request
728
+				  || $this->transaction->is_completed()
729
+				  || $this->transaction->is_overpaid()
730
+				  || $this->transaction->is_free()) ? true : false;
731
+	}
732
+
733
+
734
+	/**
735
+	 * get_cart_for_transaction
736
+	 *
737
+	 * @access public
738
+	 * @param EE_Transaction $transaction
739
+	 * @return EE_Cart
740
+	 */
741
+	public function get_cart_for_transaction($transaction)
742
+	{
743
+		$session = EE_Registry::instance()->load_core('Session');
744
+		$cart = $transaction instanceof EE_Transaction ? EE_Cart::get_cart_from_txn($transaction, $session) : null;
745
+		// verify cart
746
+		if (! $cart instanceof EE_Cart) {
747
+			$cart = EE_Registry::instance()->load_core('Cart');
748
+		}
749
+
750
+		return $cart;
751
+	}
752
+
753
+
754
+	/**
755
+	 *    initialize_txn_reg_steps_array
756
+	 *
757
+	 * @access public
758
+	 * @return    array
759
+	 */
760
+	public function initialize_txn_reg_steps_array()
761
+	{
762
+		$txn_reg_steps_array = array();
763
+		foreach ($this->reg_steps as $reg_step) {
764
+			$txn_reg_steps_array[ $reg_step->slug() ] = false;
765
+		}
766
+		return $txn_reg_steps_array;
767
+	}
768
+
769
+
770
+	/**
771
+	 *    update_txn_reg_steps_array
772
+	 *
773
+	 * @access public
774
+	 * @return    bool
775
+	 * @throws \EE_Error
776
+	 */
777
+	public function update_txn_reg_steps_array()
778
+	{
779
+		$updated = false;
780
+		foreach ($this->reg_steps as $reg_step) {
781
+			if ($reg_step->completed()) {
782
+				$updated = $this->transaction->set_reg_step_completed($reg_step->slug())
783
+					? true
784
+					: $updated;
785
+			}
786
+		}
787
+		if ($updated) {
788
+			$this->transaction->save();
789
+		}
790
+		return $updated;
791
+	}
792
+
793
+
794
+	/**
795
+	 *    stash_transaction_and_checkout
796
+	 *
797
+	 * @access public
798
+	 * @return    void
799
+	 * @throws \EE_Error
800
+	 */
801
+	public function stash_transaction_and_checkout()
802
+	{
803
+		if (! $this->revisit) {
804
+			$this->update_txn_reg_steps_array();
805
+		}
806
+		$this->track_transaction_and_registration_status_updates();
807
+		// save all data to the db, but suppress errors
808
+		// $this->save_all_data( FALSE );
809
+		// cache the checkout in the session
810
+		EE_Registry::instance()->SSN->set_checkout($this);
811
+	}
812
+
813
+
814
+	/**
815
+	 *    track_transaction_and_registration_status_updates
816
+	 *    stores whether any updates were made to the TXN or it's related registrations
817
+	 *
818
+	 * @access public
819
+	 * @return void
820
+	 * @throws \EE_Error
821
+	 */
822
+	public function track_transaction_and_registration_status_updates()
823
+	{
824
+		// verify the transaction
825
+		if ($this->transaction instanceof EE_Transaction) {
826
+			// has there been a TXN status change during this checkout?
827
+			$this->txn_status_updated = $this->transaction->txn_status_updated();
828
+			/** @type EE_Registration_Processor $registration_processor */
829
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
830
+			// grab the saved registrations from the transaction
831
+			foreach ($this->transaction->registrations($this->reg_cache_where_params) as $registration) {
832
+				if ($registration_processor->reg_status_updated($registration->ID())) {
833
+					$this->set_reg_status_updated($registration->ID(), true);
834
+				}
835
+			}
836
+		}
837
+	}
838
+
839
+
840
+	/**
841
+	 *    visit_allows_processing_of_this_registration
842
+	 *    determines if the current SPCO visit should allow the passed EE_Registration to be used in processing.
843
+	 *    one of the following conditions must be met:
844
+	 *        EITHER:    A) first time thru SPCO -> process ALL registrations ( NOT a revisit )
845
+	 *        OR :        B) primary registrant is editing info -> process ALL registrations ( primary_revisit )
846
+	 *        OR :        C) another registrant is editing info -> ONLY process their registration ( revisit AND their
847
+	 *        reg_url_link matches )
848
+	 *
849
+	 * @access public
850
+	 * @param    EE_Registration $registration
851
+	 * @return    bool
852
+	 * @throws \EE_Error
853
+	 */
854
+	public function visit_allows_processing_of_this_registration(EE_Registration $registration)
855
+	{
856
+		return ! $this->revisit
857
+			   || $this->primary_revisit
858
+			   || (
859
+				   $this->revisit && $this->reg_url_link === $registration->reg_url_link()
860
+			   )
861
+			? true
862
+			: false;
863
+	}
864
+
865
+
866
+	/**
867
+	 *    _transaction_has_primary_registration
868
+	 *
869
+	 * @access        private
870
+	 * @return        bool
871
+	 */
872
+	public function transaction_has_primary_registrant()
873
+	{
874
+		return $this->primary_attendee_obj instanceof EE_Attendee ? true : false;
875
+	}
876
+
877
+
878
+	/**
879
+	 *    save_all_data
880
+	 *    simply loops through the current transaction and saves all data for each registration
881
+	 *
882
+	 * @access public
883
+	 * @param bool $show_errors
884
+	 * @return bool
885
+	 * @throws \EE_Error
886
+	 */
887
+	public function save_all_data($show_errors = true)
888
+	{
889
+		// verify the transaction
890
+		if ($this->transaction instanceof EE_Transaction) {
891
+			// save to ensure that TXN has ID
892
+			$this->transaction->save();
893
+			// grab the saved registrations from the transaction
894
+			foreach ($this->transaction->registrations($this->reg_cache_where_params) as $registration) {
895
+				$this->_save_registration($registration, $show_errors);
896
+			}
897
+		} else {
898
+			if ($show_errors) {
899
+				EE_Error::add_error(
900
+					__(
901
+						'A valid Transaction was not found when attempting to save your registration information.',
902
+						'event_espresso'
903
+					),
904
+					__FILE__,
905
+					__FUNCTION__,
906
+					__LINE__
907
+				);
908
+			}
909
+			return false;
910
+		}
911
+		return true;
912
+	}
913
+
914
+
915
+	/**
916
+	 * _save_registration_attendee
917
+	 *
918
+	 * @param    EE_Registration $registration
919
+	 * @param bool               $show_errors
920
+	 * @return void
921
+	 * @throws \EE_Error
922
+	 */
923
+	private function _save_registration($registration, $show_errors = true)
924
+	{
925
+		// verify object
926
+		if ($registration instanceof EE_Registration) {
927
+			// should this registration be processed during this visit ?
928
+			if ($this->visit_allows_processing_of_this_registration($registration)) {
929
+				// set TXN ID
930
+				if (! $registration->transaction_ID()) {
931
+					$registration->set_transaction_id($this->transaction->ID());
932
+				}
933
+				// verify and save the attendee
934
+				$this->_save_registration_attendee($registration, $show_errors);
935
+				// save answers to reg form questions
936
+				$this->_save_registration_answers($registration, $show_errors);
937
+				// save changes
938
+				$registration->save();
939
+				// update txn cache
940
+				if (! $this->transaction->update_cache_after_object_save('Registration', $registration)) {
941
+					if ($show_errors) {
942
+						EE_Error::add_error(
943
+							__(
944
+								'The newly saved Registration object could not be cached on the Transaction.',
945
+								'event_espresso'
946
+							),
947
+							__FILE__,
948
+							__FUNCTION__,
949
+							__LINE__
950
+						);
951
+					}
952
+				}
953
+			}
954
+		} else {
955
+			if ($show_errors) {
956
+				EE_Error::add_error(
957
+					__(
958
+						'An invalid Registration object was discovered when attempting to save your registration information.',
959
+						'event_espresso'
960
+					),
961
+					__FILE__,
962
+					__FUNCTION__,
963
+					__LINE__
964
+				);
965
+			}
966
+		}
967
+	}
968
+
969
+
970
+	/**
971
+	 * _save_registration_attendee
972
+	 *
973
+	 * @param    EE_Registration $registration
974
+	 * @param bool               $show_errors
975
+	 * @return void
976
+	 * @throws \EE_Error
977
+	 */
978
+	private function _save_registration_attendee($registration, $show_errors = true)
979
+	{
980
+		if ($registration->attendee() instanceof EE_Attendee) {
981
+			// save so that ATT has ID
982
+			$registration->attendee()->save();
983
+			if (! $registration->update_cache_after_object_save('Attendee', $registration->attendee())) {
984
+				if ($show_errors) {
985
+					EE_Error::add_error(
986
+						__(
987
+							'The newly saved Attendee object could not be cached on the registration.',
988
+							'event_espresso'
989
+						),
990
+						__FILE__,
991
+						__FUNCTION__,
992
+						__LINE__
993
+					);
994
+				}
995
+			}
996
+		} else {
997
+			if ($show_errors) {
998
+				EE_Error::add_error(
999
+					sprintf(
1000
+						'%1$s||%1$s $attendee = %2$s',
1001
+						__(
1002
+							'Either no Attendee information was found, or an invalid Attendee object was discovered when attempting to save your registration information.',
1003
+							'event_espresso'
1004
+						),
1005
+						var_export($registration->attendee(), true)
1006
+					),
1007
+					__FILE__,
1008
+					__FUNCTION__,
1009
+					__LINE__
1010
+				);
1011
+			}
1012
+		}
1013
+	}
1014
+
1015
+
1016
+	/**
1017
+	 * _save_question_answers
1018
+	 *
1019
+	 * @param    EE_Registration $registration
1020
+	 * @param bool               $show_errors
1021
+	 * @return void
1022
+	 * @throws \EE_Error
1023
+	 */
1024
+	private function _save_registration_answers($registration, $show_errors = true)
1025
+	{
1026
+		// now save the answers
1027
+		foreach ($registration->answers() as $cache_key => $answer) {
1028
+			// verify object
1029
+			if ($answer instanceof EE_Answer) {
1030
+				$answer->set_registration($registration->ID());
1031
+				$answer->save();
1032
+				if (! $registration->update_cache_after_object_save('Answer', $answer, $cache_key)) {
1033
+					if ($show_errors) {
1034
+						EE_Error::add_error(
1035
+							__(
1036
+								'The newly saved Answer object could not be cached on the registration.',
1037
+								'event_espresso'
1038
+							),
1039
+							__FILE__,
1040
+							__FUNCTION__,
1041
+							__LINE__
1042
+						);
1043
+					}
1044
+				}
1045
+			} else {
1046
+				if ($show_errors) {
1047
+					EE_Error::add_error(
1048
+						__(
1049
+							'An invalid Answer object was discovered when attempting to save your registration information.',
1050
+							'event_espresso'
1051
+						),
1052
+						__FILE__,
1053
+						__FUNCTION__,
1054
+						__LINE__
1055
+					);
1056
+				}
1057
+			}
1058
+		}
1059
+	}
1060
+
1061
+
1062
+	/**
1063
+	 *    refresh_all_entities
1064
+	 *   will either refresh the entity map with objects form the db or from the checkout cache
1065
+	 *
1066
+	 * @access public
1067
+	 * @param bool $from_db
1068
+	 * @return bool
1069
+	 * @throws \EE_Error
1070
+	 */
1071
+	public function refresh_all_entities($from_db = false)
1072
+	{
1073
+		$from_db = $this->current_step->is_final_step() || $this->action === 'process_gateway_response'
1074
+			? true
1075
+			: $from_db;
1076
+		// $this->log(
1077
+		//     __CLASS__,
1078
+		//     __FUNCTION__,
1079
+		//     __LINE__,
1080
+		//     array('from_db' => $from_db)
1081
+		// );
1082
+		return $from_db ? $this->refresh_from_db() : $this->refresh_entity_map();
1083
+	}
1084
+
1085
+
1086
+	/**
1087
+	 *  refresh_entity_map
1088
+	 *  simply loops through the current transaction and updates each
1089
+	 *  model's entity map using EEM_Base::refresh_entity_map_from_db()
1090
+	 *
1091
+	 * @access public
1092
+	 * @return bool
1093
+	 * @throws \EE_Error
1094
+	 */
1095
+	protected function refresh_from_db()
1096
+	{
1097
+		// verify the transaction
1098
+		if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1099
+			// pull fresh TXN data from the db
1100
+			$this->transaction = $this->transaction->get_model()->refresh_entity_map_from_db($this->transaction->ID());
1101
+			// update EE_Checkout's cached primary_attendee object
1102
+			$this->primary_attendee_obj = $this->_refresh_primary_attendee_obj_from_db($this->transaction);
1103
+			// update EE_Checkout's cached payment object
1104
+			$payment = $this->transaction->last_payment();
1105
+			$this->payment = $payment instanceof EE_Payment ? $payment : $this->payment;
1106
+			// update EE_Checkout's cached payment_method object
1107
+			$payment_method = $this->payment instanceof EE_Payment ? $this->payment->payment_method() : null;
1108
+			$this->payment_method = $payment_method instanceof EE_Payment_Method ? $payment_method
1109
+				: $this->payment_method;
1110
+			// now refresh the cart, based on the TXN
1111
+			$this->cart = $this->get_cart_for_transaction($this->transaction);
1112
+		} else {
1113
+			EE_Error::add_error(
1114
+				__(
1115
+					'A valid Transaction was not found when attempting to update the model entity mapper.',
1116
+					'event_espresso'
1117
+				),
1118
+				__FILE__,
1119
+				__FUNCTION__,
1120
+				__LINE__
1121
+			);
1122
+			return false;
1123
+		}
1124
+		return true;
1125
+	}
1126
+
1127
+
1128
+	/**
1129
+	 * _refresh_primary_attendee_obj_from_db
1130
+	 *
1131
+	 * @param   EE_Transaction $transaction
1132
+	 * @return  EE_Attendee | null
1133
+	 * @throws \EE_Error
1134
+	 */
1135
+	protected function _refresh_primary_attendee_obj_from_db(EE_Transaction $transaction)
1136
+	{
1137
+
1138
+		$primary_attendee_obj = null;
1139
+		// grab the saved registrations from the transaction
1140
+		foreach ($transaction->registrations($this->reg_cache_where_params, true) as $registration) {
1141
+			// verify object
1142
+			if ($registration instanceof EE_Registration) {
1143
+				$attendee = $registration->attendee();
1144
+				// verify object && maybe cache primary_attendee_obj ?
1145
+				if ($attendee instanceof EE_Attendee && $registration->is_primary_registrant()) {
1146
+					$primary_attendee_obj = $attendee;
1147
+				}
1148
+			} else {
1149
+				EE_Error::add_error(
1150
+					__(
1151
+						'An invalid Registration object was discovered when attempting to update the model entity mapper.',
1152
+						'event_espresso'
1153
+					),
1154
+					__FILE__,
1155
+					__FUNCTION__,
1156
+					__LINE__
1157
+				);
1158
+			}
1159
+		}
1160
+		return $primary_attendee_obj;
1161
+	}
1162
+
1163
+
1164
+	/**
1165
+	 *  refresh_entity_map
1166
+	 *  simply loops through the current transaction and updates
1167
+	 *  each model's entity map using EEM_Base::refresh_entity_map_with()
1168
+	 *
1169
+	 * @access public
1170
+	 * @return bool
1171
+	 * @throws \EE_Error
1172
+	 */
1173
+	protected function refresh_entity_map()
1174
+	{
1175
+		// verify the transaction
1176
+		if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1177
+			// never cache payment info
1178
+			$this->transaction->clear_cache('Payment');
1179
+			// is the Payment Options Reg Step completed ?
1180
+			if ($this->transaction->reg_step_completed('payment_options')) {
1181
+				// then check for payments and update TXN accordingly
1182
+				/** @type EE_Transaction_Payments $transaction_payments */
1183
+				$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1184
+				$transaction_payments->calculate_total_payments_and_update_status($this->transaction);
1185
+			}
1186
+			// grab the saved registrations from the transaction
1187
+			foreach ($this->transaction->registrations($this->reg_cache_where_params) as $reg_cache_ID => $registration) {
1188
+				$this->_refresh_registration($reg_cache_ID, $registration);
1189
+			}
1190
+			// make sure our cached TXN is added to the model entity mapper
1191
+			$this->transaction = $this->transaction->get_model()->refresh_entity_map_with(
1192
+				$this->transaction->ID(),
1193
+				$this->transaction
1194
+			);
1195
+		} else {
1196
+			EE_Error::add_error(
1197
+				__(
1198
+					'A valid Transaction was not found when attempting to update the model entity mapper.',
1199
+					'event_espresso'
1200
+				),
1201
+				__FILE__,
1202
+				__FUNCTION__,
1203
+				__LINE__
1204
+			);
1205
+			return false;
1206
+		}
1207
+		// verify and update the cart because inaccurate totals are not so much fun
1208
+		if ($this->cart instanceof EE_Cart) {
1209
+			$grand_total = $this->cart->get_grand_total();
1210
+			if ($grand_total instanceof EE_Line_Item && $grand_total->ID()) {
1211
+				$grand_total->recalculate_total_including_taxes();
1212
+				$grand_total = $grand_total->get_model()->refresh_entity_map_with(
1213
+					$this->cart->get_grand_total()->ID(),
1214
+					$this->cart->get_grand_total()
1215
+				);
1216
+			}
1217
+			if ($grand_total instanceof EE_Line_Item) {
1218
+				$this->cart = EE_Cart::instance($grand_total);
1219
+			} else {
1220
+				EE_Error::add_error(
1221
+					__(
1222
+						'A valid Cart was not found when attempting to update the model entity mapper.',
1223
+						'event_espresso'
1224
+					),
1225
+					__FILE__,
1226
+					__FUNCTION__,
1227
+					__LINE__
1228
+				);
1229
+				return false;
1230
+			}
1231
+		}
1232
+		return true;
1233
+	}
1234
+
1235
+
1236
+	/**
1237
+	 * _refresh_registration
1238
+	 *
1239
+	 * @param    string | int    $reg_cache_ID
1240
+	 * @param    EE_Registration $registration
1241
+	 * @return void
1242
+	 * @throws \EE_Error
1243
+	 */
1244
+	protected function _refresh_registration($reg_cache_ID, $registration)
1245
+	{
1246
+
1247
+		// verify object
1248
+		if ($registration instanceof EE_Registration) {
1249
+			// update the entity mapper attendee
1250
+			$this->_refresh_registration_attendee($registration);
1251
+			// update the entity mapper answers for reg form questions
1252
+			$this->_refresh_registration_answers($registration);
1253
+			// make sure the cached registration is added to the model entity mapper
1254
+			$registration->get_model()->refresh_entity_map_with($reg_cache_ID, $registration);
1255
+		} else {
1256
+			EE_Error::add_error(
1257
+				__(
1258
+					'An invalid Registration object was discovered when attempting to update the model entity mapper.',
1259
+					'event_espresso'
1260
+				),
1261
+				__FILE__,
1262
+				__FUNCTION__,
1263
+				__LINE__
1264
+			);
1265
+		}
1266
+	}
1267
+
1268
+
1269
+	/**
1270
+	 * _save_registration_attendee
1271
+	 *
1272
+	 * @param    EE_Registration $registration
1273
+	 * @return void
1274
+	 * @throws \EE_Error
1275
+	 */
1276
+	protected function _refresh_registration_attendee($registration)
1277
+	{
1278
+
1279
+		$attendee = $registration->attendee();
1280
+		// verify object
1281
+		if ($attendee instanceof EE_Attendee && $attendee->ID()) {
1282
+			// make sure the cached attendee is added to the model entity mapper
1283
+			$registration->attendee()->get_model()->refresh_entity_map_with($attendee->ID(), $attendee);
1284
+			// maybe cache primary_attendee_obj ?
1285
+			if ($registration->is_primary_registrant()) {
1286
+				$this->primary_attendee_obj = $attendee;
1287
+			}
1288
+		}
1289
+	}
1290
+
1291
+
1292
+	/**
1293
+	 * _refresh_registration_answers
1294
+	 *
1295
+	 * @param    EE_Registration $registration
1296
+	 * @return void
1297
+	 * @throws \EE_Error
1298
+	 */
1299
+	protected function _refresh_registration_answers($registration)
1300
+	{
1301
+
1302
+		// now update the answers
1303
+		foreach ($registration->answers() as $cache_key => $answer) {
1304
+			// verify object
1305
+			if ($answer instanceof EE_Answer) {
1306
+				if ($answer->ID()) {
1307
+					// make sure the cached answer is added to the model entity mapper
1308
+					$answer->get_model()->refresh_entity_map_with($answer->ID(), $answer);
1309
+				}
1310
+			} else {
1311
+				EE_Error::add_error(
1312
+					__(
1313
+						'An invalid Answer object was discovered when attempting to update the model entity mapper.',
1314
+						'event_espresso'
1315
+					),
1316
+					__FILE__,
1317
+					__FUNCTION__,
1318
+					__LINE__
1319
+				);
1320
+			}
1321
+		}
1322
+	}
1323
+
1324
+
1325
+	/**
1326
+	 *    __sleep
1327
+	 * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon
1328
+	 * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the
1329
+	 * reg form, because if needed, it will be regenerated anyways
1330
+	 *
1331
+	 * @return array
1332
+	 * @throws \EE_Error
1333
+	 */
1334
+	public function __sleep()
1335
+	{
1336
+		if ($this->primary_attendee_obj instanceof EE_Attendee && $this->primary_attendee_obj->ID()) {
1337
+			$this->primary_attendee_obj = $this->primary_attendee_obj->ID();
1338
+		}        // remove the reg form and the checkout
1339
+		if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1340
+			$this->transaction = $this->transaction->ID();
1341
+		}        // remove the reg form and the checkout
1342
+		return array_diff(array_keys(get_object_vars($this)), array('billing_form', 'registration_form'));
1343
+	}
1344
+
1345
+
1346
+	/**
1347
+	 *    __wakeup
1348
+	 * to conserve db space, we are removing the EE_Checkout object from EE_SPCO_Reg_Step objects upon serialization
1349
+	 * this will reinstate the EE_Checkout object on each EE_SPCO_Reg_Step object
1350
+	 */
1351
+	public function __wakeup()
1352
+	{
1353
+		if (! $this->primary_attendee_obj instanceof EE_Attendee && absint($this->primary_attendee_obj) !== 0) {
1354
+			// $this->primary_attendee_obj is actually just an ID, so use it to get the object from the db
1355
+			$this->primary_attendee_obj = EEM_Attendee::instance()->get_one_by_ID($this->primary_attendee_obj);
1356
+		}
1357
+		if (! $this->transaction instanceof EE_Transaction && absint($this->transaction) !== 0) {
1358
+			// $this->transaction is actually just an ID, so use it to get the object from the db
1359
+			$this->transaction = EEM_Transaction::instance()->get_one_by_ID($this->transaction);
1360
+		}
1361
+		foreach ($this->reg_steps as $reg_step) {
1362
+			$reg_step->checkout = $this;
1363
+		}
1364
+	}
1365
+
1366
+
1367
+	/**
1368
+	 * debug
1369
+	 *
1370
+	 * @param string $class
1371
+	 * @param string $func
1372
+	 * @param string $line
1373
+	 * @param array  $info
1374
+	 * @param bool   $display_request
1375
+	 * @throws \EE_Error
1376
+	 */
1377
+	public function log($class = '', $func = '', $line = '', $info = array(), $display_request = false)
1378
+	{
1379
+		$disabled = true;
1380
+		if (WP_DEBUG && ! $disabled) {
1381
+			$debug_data = get_option('EE_DEBUG_SPCO_' . EE_Session::instance()->id(), array());
1382
+			$default_data = array(
1383
+				$class                    => $func . '() : ' . $line,
1384
+				'request->step'           => $this->step,
1385
+				'request->action'         => $this->action,
1386
+				'current_step->slug'      => $this->current_step instanceof EE_SPCO_Reg_Step ?
1387
+					$this->current_step->slug() : '',
1388
+				'current_step->completed' => $this->current_step instanceof EE_SPCO_Reg_Step ?
1389
+					$this->current_step->completed() : '',
1390
+				'txn_status_updated'      => $this->transaction->txn_status_updated(),
1391
+				'reg_status_updated'      => $this->reg_status_updated,
1392
+				'reg_url_link'            => $this->reg_url_link,
1393
+				'REQ'                     => $display_request ? $_REQUEST : '',
1394
+			);
1395
+			if ($this->transaction instanceof EE_Transaction) {
1396
+				$default_data['TXN_status'] = $this->transaction->status_ID();
1397
+				$default_data['TXN_reg_steps'] = $this->transaction->reg_steps();
1398
+				foreach ($this->transaction->registrations($this->reg_cache_where_params) as $REG_ID => $registration) {
1399
+					$default_data['registrations'][ $REG_ID ] = $registration->status_ID();
1400
+				}
1401
+				if ($this->transaction->ID()) {
1402
+					$TXN_ID = 'EE_Transaction: ' . $this->transaction->ID();
1403
+					// don't serialize objects
1404
+					$info = $this->_strip_objects($info);
1405
+					if (! isset($debug_data[ $TXN_ID ])) {
1406
+						$debug_data[ $TXN_ID ] = array();
1407
+					}
1408
+					$debug_data[ $TXN_ID ][ microtime() ] = array_merge(
1409
+						$default_data,
1410
+						$info
1411
+					);
1412
+					update_option('EE_DEBUG_SPCO_' . EE_Session::instance()->id(), $debug_data);
1413
+				}
1414
+			}
1415
+		}
1416
+	}
1417
+
1418
+
1419
+	/**
1420
+	 * _strip_objects
1421
+	 *
1422
+	 * @param array $info
1423
+	 * @return array
1424
+	 */
1425
+	public function _strip_objects($info = array())
1426
+	{
1427
+		foreach ((array) $info as $key => $value) {
1428
+			if (is_array($value)) {
1429
+				$info[ $key ] = $this->_strip_objects($value);
1430
+			} elseif (is_object($value)) {
1431
+				$object_class = get_class($value);
1432
+				$info[ $object_class ] = array();
1433
+				$info[ $object_class ]['ID'] = method_exists($value, 'ID') ? $value->ID() : 0;
1434
+				if (method_exists($value, 'status')) {
1435
+					$info[ $object_class ]['status'] = $value->status();
1436
+				} elseif (method_exists($value, 'status_ID')) {
1437
+					$info[ $object_class ]['status'] = $value->status_ID();
1438
+				}
1439
+				unset($info[ $key ]);
1440
+			}
1441
+		}
1442
+		return (array) $info;
1443
+	}
1444 1444
 }
Please login to merge, or discard this patch.