Completed
Branch dev (22bd0c)
by
unknown
24:44 queued 18:15
created
core/db_classes/EE_CSV.class.php 2 patches
Spacing   +48 added lines, -48 removed lines patch added patch discarded remove patch
@@ -46,31 +46,31 @@  discard block
 block discarded – undo
46 46
         global $wpdb;
47 47
 
48 48
         $this->_primary_keys = array(
49
-            $wpdb->prefix . 'esp_answer'                  => array('ANS_ID'),
50
-            $wpdb->prefix . 'esp_attendee'                => array('ATT_ID'),
51
-            $wpdb->prefix . 'esp_datetime'                => array('DTT_ID'),
52
-            $wpdb->prefix . 'esp_event_question_group'    => array('EQG_ID'),
53
-            $wpdb->prefix . 'esp_message_template'        => array('MTP_ID'),
54
-            $wpdb->prefix . 'esp_payment'                 => array('PAY_ID'),
55
-            $wpdb->prefix . 'esp_price'                   => array('PRC_ID'),
56
-            $wpdb->prefix . 'esp_price_type'              => array('PRT_ID'),
57
-            $wpdb->prefix . 'esp_question'                => array('QST_ID'),
58
-            $wpdb->prefix . 'esp_question_group'          => array('QSG_ID'),
59
-            $wpdb->prefix . 'esp_question_group_question' => array('QGQ_ID'),
60
-            $wpdb->prefix . 'esp_question_option'         => array('QSO_ID'),
61
-            $wpdb->prefix . 'esp_registration'            => array('REG_ID'),
62
-            $wpdb->prefix . 'esp_status'                  => array('STS_ID'),
63
-            $wpdb->prefix . 'esp_transaction'             => array('TXN_ID'),
64
-            $wpdb->prefix . 'esp_transaction'             => array('TXN_ID'),
65
-            $wpdb->prefix . 'events_detail'               => array('id'),
66
-            $wpdb->prefix . 'events_category_detail'      => array('id'),
67
-            $wpdb->prefix . 'events_category_rel'         => array('id'),
68
-            $wpdb->prefix . 'events_venue'                => array('id'),
69
-            $wpdb->prefix . 'events_venue_rel'            => array('emeta_id'),
70
-            $wpdb->prefix . 'events_locale'               => array('id'),
71
-            $wpdb->prefix . 'events_locale_rel'           => array('id'),
72
-            $wpdb->prefix . 'events_personnel'            => array('id'),
73
-            $wpdb->prefix . 'events_personnel_rel'        => array('id'),
49
+            $wpdb->prefix.'esp_answer'                  => array('ANS_ID'),
50
+            $wpdb->prefix.'esp_attendee'                => array('ATT_ID'),
51
+            $wpdb->prefix.'esp_datetime'                => array('DTT_ID'),
52
+            $wpdb->prefix.'esp_event_question_group'    => array('EQG_ID'),
53
+            $wpdb->prefix.'esp_message_template'        => array('MTP_ID'),
54
+            $wpdb->prefix.'esp_payment'                 => array('PAY_ID'),
55
+            $wpdb->prefix.'esp_price'                   => array('PRC_ID'),
56
+            $wpdb->prefix.'esp_price_type'              => array('PRT_ID'),
57
+            $wpdb->prefix.'esp_question'                => array('QST_ID'),
58
+            $wpdb->prefix.'esp_question_group'          => array('QSG_ID'),
59
+            $wpdb->prefix.'esp_question_group_question' => array('QGQ_ID'),
60
+            $wpdb->prefix.'esp_question_option'         => array('QSO_ID'),
61
+            $wpdb->prefix.'esp_registration'            => array('REG_ID'),
62
+            $wpdb->prefix.'esp_status'                  => array('STS_ID'),
63
+            $wpdb->prefix.'esp_transaction'             => array('TXN_ID'),
64
+            $wpdb->prefix.'esp_transaction'             => array('TXN_ID'),
65
+            $wpdb->prefix.'events_detail'               => array('id'),
66
+            $wpdb->prefix.'events_category_detail'      => array('id'),
67
+            $wpdb->prefix.'events_category_rel'         => array('id'),
68
+            $wpdb->prefix.'events_venue'                => array('id'),
69
+            $wpdb->prefix.'events_venue_rel'            => array('emeta_id'),
70
+            $wpdb->prefix.'events_locale'               => array('id'),
71
+            $wpdb->prefix.'events_locale_rel'           => array('id'),
72
+            $wpdb->prefix.'events_personnel'            => array('id'),
73
+            $wpdb->prefix.'events_personnel_rel'        => array('id'),
74 74
         );
75 75
     }
76 76
 
@@ -102,7 +102,7 @@  discard block
 block discarded – undo
102 102
     {
103 103
         $fc = "";
104 104
         $fh = fopen($file_path, "rb");
105
-        if (! $fh) {
105
+        if ( ! $fh) {
106 106
             throw new EE_Error(sprintf(esc_html__("Cannot open file for read: %s<br>\n", 'event_espresso'), $file_path));
107 107
         }
108 108
         $flen = filesize($file_path);
@@ -110,7 +110,7 @@  discard block
 block discarded – undo
110 110
         for ($i = 0; $i < $flen; $i++) {
111 111
             $c = substr($bc, $i, 1);
112 112
             if ((ord($c) != 0) && (ord($c) != 13)) {
113
-                $fc = $fc . $c;
113
+                $fc = $fc.$c;
114 114
             }
115 115
         }
116 116
         if ((ord(substr($fc, 0, 1)) == 255) && (ord(substr($fc, 1, 1)) == 254)) {
@@ -205,7 +205,7 @@  discard block
 block discarded – undo
205 205
     public function import_csv_to_model_data_array($path_to_file, $model_name = false, $first_row_is_headers = true)
206 206
     {
207 207
         $multi_dimensional_array = $this->import_csv_to_multi_dimensional_array($path_to_file);
208
-        if (! $multi_dimensional_array) {
208
+        if ( ! $multi_dimensional_array) {
209 209
             return false;
210 210
         }
211 211
         // gotta start somewhere
@@ -241,23 +241,23 @@  discard block
 block discarded – undo
241 241
             // loop through each column
242 242
             for ($i = 0; $i < $columns; $i++) {
243 243
                 // replace csv_enclosures with backslashed quotes
244
-                $data[ $i ] = str_replace('"""', '\\"', $data[ $i ]);
244
+                $data[$i] = str_replace('"""', '\\"', $data[$i]);
245 245
                 // do we need to grab the column names?
246 246
                 if ($row === 1) {
247 247
                     if ($first_row_is_headers) {
248 248
                         // store the column names to use for keys
249
-                        $column_name = $data[ $i ];
249
+                        $column_name = $data[$i];
250 250
                         // check it's not blank... sometimes CSV editign programs adda bunch of empty columns onto the end...
251
-                        if (! $column_name) {
251
+                        if ( ! $column_name) {
252 252
                             continue;
253 253
                         }
254 254
                         $matches = array();
255 255
                         if ($model_name == EE_CSV::metadata_header) {
256
-                            $headers[ $i ] = $column_name;
256
+                            $headers[$i] = $column_name;
257 257
                         } else {
258 258
                             // now get the db table name from it (the part between square brackets)
259 259
                             $success = preg_match('~(.*)\[(.*)\]~', $column_name, $matches);
260
-                            if (! $success) {
260
+                            if ( ! $success) {
261 261
                                 EE_Error::add_error(
262 262
                                     sprintf(
263 263
                                         esc_html__(
@@ -273,24 +273,24 @@  discard block
 block discarded – undo
273 273
                                 );
274 274
                                 return false;
275 275
                             }
276
-                            $headers[ $i ] = $matches[2];
276
+                            $headers[$i] = $matches[2];
277 277
                         }
278 278
                     } else {
279 279
                         // no column names means our final array will just use counters for keys
280
-                        $model_entry[ $headers[ $i ] ] = $data[ $i ];
281
-                        $headers[ $i ] = $i;
280
+                        $model_entry[$headers[$i]] = $data[$i];
281
+                        $headers[$i] = $i;
282 282
                     }
283 283
                     // and we need to store csv data
284 284
                 } else {
285 285
                     // this column isn' ta header, store it if there is a header for it
286
-                    if (isset($headers[ $i ])) {
287
-                        $model_entry[ $headers[ $i ] ] = $data[ $i ];
286
+                    if (isset($headers[$i])) {
287
+                        $model_entry[$headers[$i]] = $data[$i];
288 288
                     }
289 289
                 }
290 290
             }
291 291
             // save the row's data IF it's a non-header-row
292
-            if (! $first_row_is_headers || ($first_row_is_headers && $row > 1)) {
293
-                $ee_formatted_data[ $model_name ][] = $model_entry;
292
+            if ( ! $first_row_is_headers || ($first_row_is_headers && $row > 1)) {
293
+                $ee_formatted_data[$model_name][] = $model_entry;
294 294
             }
295 295
             // advance to next row
296 296
             $row++;
@@ -351,7 +351,7 @@  discard block
 block discarded – undo
351 351
         // header("Content-Type: application/force-download");
352 352
         // header("Content-Type: application/octet-stream");
353 353
         // header("Content-Type: application/download");
354
-        header('Content-disposition: attachment; filename=' . $filename);
354
+        header('Content-disposition: attachment; filename='.$filename);
355 355
         header("Content-Type: text/csv; charset=utf-8");
356 356
         do_action('AHEE__EE_CSV__begin_sending_csv__headers');
357 357
         echo apply_filters(
@@ -370,7 +370,7 @@  discard block
 block discarded – undo
370 370
      */
371 371
     public function write_metadata_to_csv($filehandle)
372 372
     {
373
-        $data_row = array(EE_CSV::metadata_header);// do NOT translate because this exact string is used when importing
373
+        $data_row = array(EE_CSV::metadata_header); // do NOT translate because this exact string is used when importing
374 374
         $this->fputcsv2($filehandle, $data_row);
375 375
         $meta_data = array(
376 376
             0 => array(
@@ -499,7 +499,7 @@  discard block
 block discarded – undo
499 499
             $this->fputcsv2($filehandle, array('MODEL', $model_name));
500 500
             // if we have items to put in the CSV, do it normally
501 501
 
502
-            if (! empty($model_instance_arrays)) {
502
+            if ( ! empty($model_instance_arrays)) {
503 503
                 $this->write_data_array_to_csv($filehandle, $model_instance_arrays);
504 504
             } else {
505 505
                 // echo "no data to write... so just write the headers";
@@ -508,7 +508,7 @@  discard block
 block discarded – undo
508 508
                 $model = EE_Registry::instance()->load_model($model_name);
509 509
                 $column_names = array();
510 510
                 foreach ($model->field_settings() as $field) {
511
-                    $column_names[ $field->get_nicename() . "[" . $field->get_name() . "]" ] = null;
511
+                    $column_names[$field->get_nicename()."[".$field->get_name()."]"] = null;
512 512
                 }
513 513
                 $this->write_data_array_to_csv($filehandle, array($column_names));
514 514
             }
@@ -541,12 +541,12 @@  discard block
 block discarded – undo
541 541
     {
542 542
 
543 543
         // no data file?? get outta here
544
-        if (! $data or ! is_array($data) or empty($data)) {
544
+        if ( ! $data or ! is_array($data) or empty($data)) {
545 545
             return false;
546 546
         }
547 547
 
548 548
         // no filename?? get outta here
549
-        if (! $filename) {
549
+        if ( ! $filename) {
550 550
             return false;
551 551
         }
552 552
 
@@ -627,11 +627,11 @@  discard block
 block discarded – undo
627 627
             }
628 628
 
629 629
             $output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field_value) ?
630
-                ($enclosure . str_replace($enclosure, $enclosure . $enclosure, $field_value) . $enclosure)
630
+                ($enclosure.str_replace($enclosure, $enclosure.$enclosure, $field_value).$enclosure)
631 631
                 : $field_value;
632 632
         }
633 633
 
634
-        fwrite($fh, join($delimiter, $output) . PHP_EOL);
634
+        fwrite($fh, join($delimiter, $output).PHP_EOL);
635 635
     }
636 636
 
637 637
 
Please login to merge, or discard this patch.
Indentation   +669 added lines, -669 removed lines patch added patch discarded remove patch
@@ -13,673 +13,673 @@
 block discarded – undo
13 13
  */
14 14
 class EE_CSV
15 15
 {
16
-    // instance of the EE_CSV object
17
-    private static $_instance = null;
18
-
19
-
20
-    // multidimensional array to store update & error messages
21
-    // var $_notices = array( 'updates' => array(), 'errors' => array() );
22
-
23
-
24
-    private $_primary_keys;
25
-
26
-    /**
27
-     *
28
-     * @var EE_Registry
29
-     */
30
-    private $EE;
31
-    /**
32
-     * string used for 1st cell in exports, which indicates that the following 2 rows will be metadata keys and values
33
-     */
34
-    const metadata_header = 'Event Espresso Export Meta Data';
35
-
36
-    /**
37
-     *        private constructor to prevent direct creation
38
-     *
39
-     * @Constructor
40
-     * @access private
41
-     * @return void
42
-     */
43
-    private function __construct()
44
-    {
45
-        global $wpdb;
46
-
47
-        $this->_primary_keys = array(
48
-            $wpdb->prefix . 'esp_answer'                  => array('ANS_ID'),
49
-            $wpdb->prefix . 'esp_attendee'                => array('ATT_ID'),
50
-            $wpdb->prefix . 'esp_datetime'                => array('DTT_ID'),
51
-            $wpdb->prefix . 'esp_event_question_group'    => array('EQG_ID'),
52
-            $wpdb->prefix . 'esp_message_template'        => array('MTP_ID'),
53
-            $wpdb->prefix . 'esp_payment'                 => array('PAY_ID'),
54
-            $wpdb->prefix . 'esp_price'                   => array('PRC_ID'),
55
-            $wpdb->prefix . 'esp_price_type'              => array('PRT_ID'),
56
-            $wpdb->prefix . 'esp_question'                => array('QST_ID'),
57
-            $wpdb->prefix . 'esp_question_group'          => array('QSG_ID'),
58
-            $wpdb->prefix . 'esp_question_group_question' => array('QGQ_ID'),
59
-            $wpdb->prefix . 'esp_question_option'         => array('QSO_ID'),
60
-            $wpdb->prefix . 'esp_registration'            => array('REG_ID'),
61
-            $wpdb->prefix . 'esp_status'                  => array('STS_ID'),
62
-            $wpdb->prefix . 'esp_transaction'             => array('TXN_ID'),
63
-            $wpdb->prefix . 'esp_transaction'             => array('TXN_ID'),
64
-            $wpdb->prefix . 'events_detail'               => array('id'),
65
-            $wpdb->prefix . 'events_category_detail'      => array('id'),
66
-            $wpdb->prefix . 'events_category_rel'         => array('id'),
67
-            $wpdb->prefix . 'events_venue'                => array('id'),
68
-            $wpdb->prefix . 'events_venue_rel'            => array('emeta_id'),
69
-            $wpdb->prefix . 'events_locale'               => array('id'),
70
-            $wpdb->prefix . 'events_locale_rel'           => array('id'),
71
-            $wpdb->prefix . 'events_personnel'            => array('id'),
72
-            $wpdb->prefix . 'events_personnel_rel'        => array('id'),
73
-        );
74
-    }
75
-
76
-
77
-    /**
78
-     *        @ singleton method used to instantiate class object
79
-     *        @ access public
80
-     *
81
-     * @return EE_CSV
82
-     */
83
-    public static function instance()
84
-    {
85
-        // check if class object is instantiated
86
-        if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_CSV)) {
87
-            self::$_instance = new self();
88
-        }
89
-        return self::$_instance;
90
-    }
91
-
92
-    /**
93
-     * Opens a unicode or utf file (normal file_get_contents has difficulty readin ga unicode file. @see
94
-     * http://stackoverflow.com/questions/15092764/how-to-read-unicode-text-file-in-php
95
-     *
96
-     * @param string $file_path
97
-     * @return string
98
-     * @throws EE_Error
99
-     */
100
-    private function read_unicode_file($file_path)
101
-    {
102
-        $fc = "";
103
-        $fh = fopen($file_path, "rb");
104
-        if (! $fh) {
105
-            throw new EE_Error(sprintf(esc_html__("Cannot open file for read: %s<br>\n", 'event_espresso'), $file_path));
106
-        }
107
-        $flen = filesize($file_path);
108
-        $bc = fread($fh, $flen);
109
-        for ($i = 0; $i < $flen; $i++) {
110
-            $c = substr($bc, $i, 1);
111
-            if ((ord($c) != 0) && (ord($c) != 13)) {
112
-                $fc = $fc . $c;
113
-            }
114
-        }
115
-        if ((ord(substr($fc, 0, 1)) == 255) && (ord(substr($fc, 1, 1)) == 254)) {
116
-            $fc = substr($fc, 2);
117
-        }
118
-        return ($fc);
119
-    }
120
-
121
-
122
-    /**
123
-     * Generic CSV-functionality to turn an entire CSV file into a single array that's
124
-     * NOT in a specific format to EE. It's just a 2-level array, with top-level arrays
125
-     * representing each row in the CSV file, and the second-level arrays being each column in that row
126
-     *
127
-     * @param string $path_to_file
128
-     * @return array of arrays. Top-level array has rows, second-level array has each item
129
-     */
130
-    public function import_csv_to_multi_dimensional_array($path_to_file)
131
-    {
132
-        // needed to deal with Mac line endings
133
-        ini_set('auto_detect_line_endings', true);
134
-
135
-        // because fgetcsv does not correctly deal with backslashed quotes such as \"
136
-        // we'll read the file into a string
137
-        $file_contents = $this->read_unicode_file($path_to_file);
138
-        // replace backslashed quotes with CSV enclosures
139
-        $file_contents = str_replace('\\"', '"""', $file_contents);
140
-        // HEY YOU! PUT THAT FILE BACK!!!
141
-        file_put_contents($path_to_file, $file_contents);
142
-
143
-        if (($file_handle = fopen($path_to_file, "r")) !== false) {
144
-            # Set the parent multidimensional array key to 0.
145
-            $nn = 0;
146
-            $csvarray = array();
147
-
148
-            // in PHP 5.3 fgetcsv accepts a 5th parameter, but the pre 5.3 versions of fgetcsv choke if passed more than 4 - is that crazy or what?
149
-            if (version_compare(PHP_VERSION, '5.3.0') < 0) {
150
-                //  PHP 5.2- version
151
-                // loop through each row of the file
152
-                while (($data = fgetcsv($file_handle, 0, ',', '"')) !== false) {
153
-                    $csvarray[] = $data;
154
-                }
155
-            } else {
156
-                // loop through each row of the file
157
-                while (($data = fgetcsv($file_handle, 0, ',', '"', '\\')) !== false) {
158
-                    $csvarray[] = $data;
159
-                }
160
-            }
161
-            # Close the File.
162
-            fclose($file_handle);
163
-            return $csvarray;
164
-        } else {
165
-            EE_Error::add_error(
166
-                sprintf(esc_html__("An error occurred - the file: %s could not opened.", "event_espresso"), $path_to_file),
167
-                __FILE__,
168
-                __FUNCTION__,
169
-                __LINE__
170
-            );
171
-            return false;
172
-        }
173
-    }
174
-
175
-
176
-    /**
177
-     * @Import contents of csv file and store values in an array to be manipulated by other functions
178
-     * @access public
179
-     * @param string  $path_to_file         - the csv file to be imported including the path to it's location.
180
-     *                                      If $model_name is provided, assumes that each row in the CSV represents a
181
-     *                                      model object for that model If $model_name ISN'T provided, assumes that
182
-     *                                      before model object data, there is a row where the first entry is simply
183
-     *                                      'MODEL', and next entry is the model's name, (untranslated) like Event, and
184
-     *                                      then maybe a row of headers, and then the model data. Eg.
185
-     *                                      '<br>MODEL,Event,<br>EVT_ID,EVT_name,...<br>1,Monkey
186
-     *                                      Party,...<br>2,Llamarama,...<br>MODEL,Venue,<br>VNU_ID,VNU_name<br>1,The
187
-     *                                      Forest
188
-     * @param string  $model_name           model name if we know what model we're importing
189
-     * @param boolean $first_row_is_headers - whether the first row of data is headers or not - TRUE = headers, FALSE =
190
-     *                                      data
191
-     * @return mixed - array on success - multi dimensional with headers as keys (if headers exist) OR string on fail -
192
-     *               error message like the following array('Event'=>array( array('EVT_ID'=>1,'EVT_name'=>'bob
193
-     *               party',...), array('EVT_ID'=>2,'EVT_name'=>'llamarama',...),
194
-     *                                      ...
195
-     *                                      )
196
-     *                                      'Venue'=>array(
197
-     *                                      array('VNU_ID'=>1,'VNU_name'=>'the shack',...),
198
-     *                                      array('VNU_ID'=>2,'VNU_name'=>'tree house',...),
199
-     *                                      ...
200
-     *                                      )
201
-     *                                      ...
202
-     *                                      )
203
-     */
204
-    public function import_csv_to_model_data_array($path_to_file, $model_name = false, $first_row_is_headers = true)
205
-    {
206
-        $multi_dimensional_array = $this->import_csv_to_multi_dimensional_array($path_to_file);
207
-        if (! $multi_dimensional_array) {
208
-            return false;
209
-        }
210
-        // gotta start somewhere
211
-        $row = 1;
212
-        // array to store csv data in
213
-        $ee_formatted_data = array();
214
-        // array to store headers (column names)
215
-        $headers = array();
216
-        foreach ($multi_dimensional_array as $data) {
217
-            // if first cell is MODEL, then second cell is the MODEL name
218
-            if ($data[0] == 'MODEL') {
219
-                $model_name = $data[1];
220
-                // don't bother looking for model data in this row. The rest of this
221
-                // row should be blank
222
-                // AND pretend this is the first row again
223
-                $row = 1;
224
-                // reset headers
225
-                $headers = array();
226
-                continue;
227
-            }
228
-            if (strpos($data[0], EE_CSV::metadata_header) !== false) {
229
-                $model_name = EE_CSV::metadata_header;
230
-                // store like model data, we just won't try importing it etc.
231
-                $row = 1;
232
-                continue;
233
-            }
234
-
235
-
236
-            // how many columns are there?
237
-            $columns = count($data);
238
-
239
-            $model_entry = array();
240
-            // loop through each column
241
-            for ($i = 0; $i < $columns; $i++) {
242
-                // replace csv_enclosures with backslashed quotes
243
-                $data[ $i ] = str_replace('"""', '\\"', $data[ $i ]);
244
-                // do we need to grab the column names?
245
-                if ($row === 1) {
246
-                    if ($first_row_is_headers) {
247
-                        // store the column names to use for keys
248
-                        $column_name = $data[ $i ];
249
-                        // check it's not blank... sometimes CSV editign programs adda bunch of empty columns onto the end...
250
-                        if (! $column_name) {
251
-                            continue;
252
-                        }
253
-                        $matches = array();
254
-                        if ($model_name == EE_CSV::metadata_header) {
255
-                            $headers[ $i ] = $column_name;
256
-                        } else {
257
-                            // now get the db table name from it (the part between square brackets)
258
-                            $success = preg_match('~(.*)\[(.*)\]~', $column_name, $matches);
259
-                            if (! $success) {
260
-                                EE_Error::add_error(
261
-                                    sprintf(
262
-                                        esc_html__(
263
-                                            "The column titled %s is invalid for importing. It must be be in the format of 'Nice Name[model_field_name]' in row %s",
264
-                                            "event_espresso"
265
-                                        ),
266
-                                        $column_name,
267
-                                        implode(",", $data)
268
-                                    ),
269
-                                    __FILE__,
270
-                                    __FUNCTION__,
271
-                                    __LINE__
272
-                                );
273
-                                return false;
274
-                            }
275
-                            $headers[ $i ] = $matches[2];
276
-                        }
277
-                    } else {
278
-                        // no column names means our final array will just use counters for keys
279
-                        $model_entry[ $headers[ $i ] ] = $data[ $i ];
280
-                        $headers[ $i ] = $i;
281
-                    }
282
-                    // and we need to store csv data
283
-                } else {
284
-                    // this column isn' ta header, store it if there is a header for it
285
-                    if (isset($headers[ $i ])) {
286
-                        $model_entry[ $headers[ $i ] ] = $data[ $i ];
287
-                    }
288
-                }
289
-            }
290
-            // save the row's data IF it's a non-header-row
291
-            if (! $first_row_is_headers || ($first_row_is_headers && $row > 1)) {
292
-                $ee_formatted_data[ $model_name ][] = $model_entry;
293
-            }
294
-            // advance to next row
295
-            $row++;
296
-        }
297
-
298
-        // delete the uploaded file
299
-        unlink($path_to_file);
300
-        // echo '<pre style="height:auto;border:2px solid lightblue;">' . print_r( $ee_formatted_data, TRUE ) . '</pre><br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>';
301
-        // die();
302
-
303
-        // it's good to give back
304
-        return $ee_formatted_data;
305
-    }
306
-
307
-
308
-    public function save_csv_to_db($csv_data_array, $model_name = false)
309
-    {
310
-        EE_Error::doing_it_wrong(
311
-            'save_csv_to_db',
312
-            esc_html__(
313
-                'Function moved to EE_Import and renamed to save_csv_data_array_to_db',
314
-                'event_espresso'
315
-            ),
316
-            '4.6.7'
317
-        );
318
-        return EE_Import::instance()->save_csv_data_array_to_db($csv_data_array, $model_name);
319
-    }
320
-
321
-    /**
322
-     * Sends HTTP headers to indicate that the browser should download a file,
323
-     * and starts writing the file to PHP's output. Returns the file handle so other functions can
324
-     * also write to it
325
-     *
326
-     * @param string $new_filename the name of the file that the user will download
327
-     * @return resource, like the results of fopen(), which can be used for fwrite, fputcsv2, etc.
328
-     */
329
-    public function begin_sending_csv($filename)
330
-    {
331
-        // grab file extension
332
-        $ext = substr(strrchr($filename, '.'), 1);
333
-        if ($ext == '.csv' or $ext == '.xls') {
334
-            str_replace($ext, '', $filename);
335
-        }
336
-        $filename .= '.csv';
337
-
338
-        // if somebody's been naughty and already started outputting stuff, trash it
339
-        // and start writing our stuff.
340
-        if (ob_get_length()) {
341
-            @ob_flush();
342
-            @flush();
343
-            @ob_end_flush();
344
-        }
345
-        @ob_start();
346
-        header("Pragma: public");
347
-        header("Expires: 0");
348
-        header("Pragma: no-cache");
349
-        header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
350
-        // header("Content-Type: application/force-download");
351
-        // header("Content-Type: application/octet-stream");
352
-        // header("Content-Type: application/download");
353
-        header('Content-disposition: attachment; filename=' . $filename);
354
-        header("Content-Type: text/csv; charset=utf-8");
355
-        do_action('AHEE__EE_CSV__begin_sending_csv__headers');
356
-        echo apply_filters(
357
-            'FHEE__EE_CSV__begin_sending_csv__start_writing',
358
-            "\xEF\xBB\xBF"
359
-        ); // makes excel open it as UTF-8. UTF-8 BOM, see http://stackoverflow.com/a/4440143/2773835
360
-        $fh = fopen('php://output', 'w');
361
-        return $fh;
362
-    }
363
-
364
-    /**
365
-     * Writes some meta data to the CSV as a bunch of columns. Initially we're only
366
-     * mentioning the version and timezone
367
-     *
368
-     * @param resource $filehandle
369
-     */
370
-    public function write_metadata_to_csv($filehandle)
371
-    {
372
-        $data_row = array(EE_CSV::metadata_header);// do NOT translate because this exact string is used when importing
373
-        $this->fputcsv2($filehandle, $data_row);
374
-        $meta_data = array(
375
-            0 => array(
376
-                'version'        => espresso_version(),
377
-                'timezone'       => EEH_DTT_Helper::get_timezone(),
378
-                'time_of_export' => current_time('mysql'),
379
-                'site_url'       => site_url(),
380
-            ),
381
-        );
382
-        $this->write_data_array_to_csv($filehandle, $meta_data);
383
-    }
384
-
385
-
386
-    /**
387
-     * Writes $data to the csv file open in $filehandle. uses the array indices of $data for column headers
388
-     *
389
-     * @param array   $data                 2D array, first numerically-indexed, and next-level-down preferably indexed
390
-     *                                      by string
391
-     * @param boolean $add_csv_column_names whether or not we should add the keys in the bottom-most array as a row for
392
-     *                                      headers in the CSV. Eg, if $data looked like
393
-     *                                      array(0=>array('EVT_ID'=>1,'EVT_name'=>'monkey'...), 1=>array(...),...))
394
-     *                                      then the first row we'd write to the CSV would be "EVT_ID,EVT_name,..."
395
-     * @return boolean if we successfully wrote to the CSV or not. If there's no $data, we consider that a success
396
-     *                 (because we wrote everything there was...nothing)
397
-     */
398
-    public function write_data_array_to_csv($filehandle, $data)
399
-    {
400
-
401
-
402
-        // determine if $data is actually a 2d array
403
-        if ($data && is_array($data) && is_array(EEH_Array::get_one_item_from_array($data))) {
404
-            // make sure top level is numerically indexed,
405
-
406
-            if (EEH_Array::is_associative_array($data)) {
407
-                throw new EE_Error(
408
-                    sprintf(
409
-                        esc_html__(
410
-                            "top-level array must be numerically indexed. Does these look like numbers to you? %s",
411
-                            "event_espresso"
412
-                        ),
413
-                        implode(",", array_keys($data))
414
-                    )
415
-                );
416
-            }
417
-            $item_in_top_level_array = EEH_Array::get_one_item_from_array($data);
418
-            // now, is the last item in the top-level array of $data an associative or numeric array?
419
-            if (EEH_Array::is_associative_array($item_in_top_level_array)) {
420
-                // its associative, so we want to output its keys as column headers
421
-                $keys = array_keys($item_in_top_level_array);
422
-                $this->fputcsv2($filehandle, $keys);
423
-            }
424
-            // start writing data
425
-            foreach ($data as $data_row) {
426
-                $this->fputcsv2($filehandle, $data_row);
427
-            }
428
-            return true;
429
-        } else {
430
-            // no data TO write... so we can assume that's a success
431
-            return true;
432
-        }
433
-        // //if 2nd level is indexed by strings, use those as csv column headers (ie, the first row)
434
-        //
435
-        //
436
-        // $no_table = TRUE;
437
-        //
438
-        // // loop through data and add each row to the file/stream as csv
439
-        // foreach ( $data as $model_name => $model_data ) {
440
-        // // test first row to see if it is data or a model name
441
-        // $model = EE_Registry::instance();->load_model($model_name);
442
-        // //if the model really exists,
443
-        // if ( $model ) {
444
-        //
445
-        // // we have a table name
446
-        // $no_table = FALSE;
447
-        //
448
-        // // put the tablename into an array cuz that's how fputcsv rolls
449
-        // $model_name_row = array( 'MODEL', $model_name );
450
-        //
451
-        // // add table name to csv output
452
-        // echo self::fputcsv2($filehandle, $model_name_row);
453
-        //
454
-        // // now get the rest of the data
455
-        // foreach ( $model_data as $row ) {
456
-        // // output the row
457
-        // echo self::fputcsv2($filehandle, $row);
458
-        // }
459
-        //
460
-        // }
461
-        //
462
-        // if ( $no_table ) {
463
-        // // no table so just put the data
464
-        // echo self::fputcsv2($filehandle, $model_data);
465
-        // }
466
-        //
467
-        // } // END OF foreach ( $data )
468
-    }
469
-
470
-    /**
471
-     * Should be called after begin_sending_csv(), and one or more write_data_array_to_csv()s.
472
-     * Calls exit to prevent polluting the CSV file with other junk
473
-     *
474
-     * @param resource $fh filehandle where we're writing the CSV to
475
-     */
476
-    public function end_sending_csv($fh)
477
-    {
478
-        fclose($fh);
479
-        exit(0);
480
-    }
481
-
482
-    /**
483
-     * Given an open file, writes all the model data to it in the format the importer expects.
484
-     * Usually preceded by begin_sending_csv($filename), and followed by end_sending_csv($filehandle).
485
-     *
486
-     * @param resource $filehandle
487
-     * @param array    $model_data_array is assumed to be a 3d array: 1st layer has keys of model names (eg 'Event'),
488
-     *                                   next layer is numerically indexed to represent each model object (eg, each
489
-     *                                   individual event), and the last layer has all the attributes o fthat model
490
-     *                                   object (eg, the event's id, name, etc)
491
-     * @return boolean success
492
-     */
493
-    public function write_model_data_to_csv($filehandle, $model_data_array)
494
-    {
495
-        $this->write_metadata_to_csv($filehandle);
496
-        foreach ($model_data_array as $model_name => $model_instance_arrays) {
497
-            // first: output a special row stating the model
498
-            $this->fputcsv2($filehandle, array('MODEL', $model_name));
499
-            // if we have items to put in the CSV, do it normally
500
-
501
-            if (! empty($model_instance_arrays)) {
502
-                $this->write_data_array_to_csv($filehandle, $model_instance_arrays);
503
-            } else {
504
-                // echo "no data to write... so just write the headers";
505
-                // so there's actually NO model objects for that model.
506
-                // probably still want to show the columns
507
-                $model = EE_Registry::instance()->load_model($model_name);
508
-                $column_names = array();
509
-                foreach ($model->field_settings() as $field) {
510
-                    $column_names[ $field->get_nicename() . "[" . $field->get_name() . "]" ] = null;
511
-                }
512
-                $this->write_data_array_to_csv($filehandle, array($column_names));
513
-            }
514
-        }
515
-    }
516
-
517
-    /**
518
-     * Writes the CSV file to the output buffer, with rows corresponding to $model_data_array,
519
-     * and dies (in order to avoid other plugins from messing up the csv output)
520
-     *
521
-     * @param string $filename         the filename you want to give the file
522
-     * @param array  $model_data_array 3d array, as described in EE_CSV::write_model_data_to_csv()
523
-     * @return bool | void writes CSV file to output and dies
524
-     */
525
-    public function export_multiple_model_data_to_csv($filename, $model_data_array)
526
-    {
527
-        $filehandle = $this->begin_sending_csv($filename);
528
-        $this->write_model_data_to_csv($filehandle, $model_data_array);
529
-        $this->end_sending_csv($filehandle);
530
-    }
531
-
532
-    /**
533
-     * @Export contents of an array to csv file
534
-     * @access public
535
-     * @param array  $data     - the array of data to be converted to csv and exported
536
-     * @param string $filename - name for newly created csv file
537
-     * @return TRUE on success, FALSE on fail
538
-     */
539
-    public function export_array_to_csv($data = false, $filename = false)
540
-    {
541
-
542
-        // no data file?? get outta here
543
-        if (! $data or ! is_array($data) or empty($data)) {
544
-            return false;
545
-        }
546
-
547
-        // no filename?? get outta here
548
-        if (! $filename) {
549
-            return false;
550
-        }
551
-
552
-
553
-        // somebody told me i might need this ???
554
-        global $wpdb;
555
-        $prefix = $wpdb->prefix;
556
-
557
-
558
-        $fh = $this->begin_sending_csv($filename);
559
-
560
-
561
-        $this->end_sending_csv($fh);
562
-    }
563
-
564
-
565
-    /**
566
-     * @Determine the maximum upload file size based on php.ini settings
567
-     * @access    public
568
-     * @param int $percent_of_max - desired percentage of the max upload_mb
569
-     * @return int KB
570
-     */
571
-    public function get_max_upload_size($percent_of_max = false)
572
-    {
573
-
574
-        $max_upload = (int) (ini_get('upload_max_filesize'));
575
-        $max_post = (int) (ini_get('post_max_size'));
576
-        $memory_limit = (int) (ini_get('memory_limit'));
577
-
578
-        // determine the smallest of the three values from above
579
-        $upload_mb = min($max_upload, $max_post, $memory_limit);
580
-
581
-        // convert MB to KB
582
-        $upload_mb = $upload_mb * 1024;
583
-
584
-        // don't want the full monty? then reduce the max uplaod size
585
-        if ($percent_of_max) {
586
-            // is percent_of_max like this -> 50 or like this -> 0.50 ?
587
-            if ($percent_of_max > 1) {
588
-                // chnages 50 to 0.50
589
-                $percent_of_max = $percent_of_max / 100;
590
-            }
591
-            // make upload_mb a percentage of the max upload_mb
592
-            $upload_mb = $upload_mb * $percent_of_max;
593
-        }
594
-
595
-        return $upload_mb;
596
-    }
597
-
598
-
599
-    /**
600
-     * @Drop   in replacement for PHP's fputcsv function - but this one works!!!
601
-     * @access private
602
-     * @param resource $fh         - file handle - what we are writing to
603
-     * @param array    $row        - individual row of csv data
604
-     * @param string   $delimiter  - csv delimiter
605
-     * @param string   $enclosure  - csv enclosure
606
-     * @param string   $mysql_null - allows php NULL to be overridden with MySQl's insertable NULL value
607
-     * @return void
608
-     */
609
-    private function fputcsv2($fh, array $row, $delimiter = ',', $enclosure = '"', $mysql_null = false)
610
-    {
611
-        // Allow user to filter the csv delimiter and enclosure for other countries csv standards
612
-        $delimiter = apply_filters('FHEE__EE_CSV__fputcsv2__delimiter', $delimiter);
613
-        $enclosure = apply_filters('FHEE__EE_CSV__fputcsv2__enclosure', $enclosure);
614
-
615
-        $delimiter_esc = preg_quote($delimiter, '/');
616
-        $enclosure_esc = preg_quote($enclosure, '/');
617
-
618
-        $output = array();
619
-        foreach ($row as $field_value) {
620
-            if (is_object($field_value) || is_array($field_value)) {
621
-                $field_value = serialize($field_value);
622
-            }
623
-            if ($field_value === null && $mysql_null) {
624
-                $output[] = 'NULL';
625
-                continue;
626
-            }
627
-
628
-            $output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field_value) ?
629
-                ($enclosure . str_replace($enclosure, $enclosure . $enclosure, $field_value) . $enclosure)
630
-                : $field_value;
631
-        }
632
-
633
-        fwrite($fh, join($delimiter, $output) . PHP_EOL);
634
-    }
635
-
636
-
637
-    // /**
638
-    //  * @CSV    Import / Export messages
639
-    //  * @access public
640
-    //  * @return void
641
-    //  */
642
-    // public function csv_admin_notices()
643
-    // {
644
-    //
645
-    //     // We play both kinds of music here! Country AND Western! - err... I mean, cycle through both types of notices
646
-    //     foreach (array('updates', 'errors') as $type) {
647
-    //
648
-    //         // if particular notice type is not empty, then "You've got Mail"
649
-    //         if (! empty($this->_notices[ $type ])) {
650
-    //
651
-    //             // is it an update or an error ?
652
-    //             $msg_class = $type == 'updates' ? 'updated' : 'error';
653
-    //             echo '<div id="message" class="' . $msg_class . '">';
654
-    //             // display each notice, however many that may be
655
-    //             foreach ($this->_notices[ $type ] as $message) {
656
-    //                 echo '<p>' . $message . '</p>';
657
-    //             }
658
-    //             // wrap it up
659
-    //             echo '</div>';
660
-    //         }
661
-    //     }
662
-    // }
663
-
664
-    /**
665
-     * Gets the date format to use in teh csv. filterable
666
-     *
667
-     * @param string $current_format
668
-     * @return string
669
-     */
670
-    public function get_date_format_for_csv($current_format = null)
671
-    {
672
-        return apply_filters('FHEE__EE_CSV__get_date_format_for_csv__format', 'Y-m-d', $current_format);
673
-    }
674
-
675
-    /**
676
-     * Gets the time format we want to use in CSV reports. Filterable
677
-     *
678
-     * @param string $current_format
679
-     * @return string
680
-     */
681
-    public function get_time_format_for_csv($current_format = null)
682
-    {
683
-        return apply_filters('FHEE__EE_CSV__get_time_format_for_csv__format', 'H:i:s', $current_format);
684
-    }
16
+	// instance of the EE_CSV object
17
+	private static $_instance = null;
18
+
19
+
20
+	// multidimensional array to store update & error messages
21
+	// var $_notices = array( 'updates' => array(), 'errors' => array() );
22
+
23
+
24
+	private $_primary_keys;
25
+
26
+	/**
27
+	 *
28
+	 * @var EE_Registry
29
+	 */
30
+	private $EE;
31
+	/**
32
+	 * string used for 1st cell in exports, which indicates that the following 2 rows will be metadata keys and values
33
+	 */
34
+	const metadata_header = 'Event Espresso Export Meta Data';
35
+
36
+	/**
37
+	 *        private constructor to prevent direct creation
38
+	 *
39
+	 * @Constructor
40
+	 * @access private
41
+	 * @return void
42
+	 */
43
+	private function __construct()
44
+	{
45
+		global $wpdb;
46
+
47
+		$this->_primary_keys = array(
48
+			$wpdb->prefix . 'esp_answer'                  => array('ANS_ID'),
49
+			$wpdb->prefix . 'esp_attendee'                => array('ATT_ID'),
50
+			$wpdb->prefix . 'esp_datetime'                => array('DTT_ID'),
51
+			$wpdb->prefix . 'esp_event_question_group'    => array('EQG_ID'),
52
+			$wpdb->prefix . 'esp_message_template'        => array('MTP_ID'),
53
+			$wpdb->prefix . 'esp_payment'                 => array('PAY_ID'),
54
+			$wpdb->prefix . 'esp_price'                   => array('PRC_ID'),
55
+			$wpdb->prefix . 'esp_price_type'              => array('PRT_ID'),
56
+			$wpdb->prefix . 'esp_question'                => array('QST_ID'),
57
+			$wpdb->prefix . 'esp_question_group'          => array('QSG_ID'),
58
+			$wpdb->prefix . 'esp_question_group_question' => array('QGQ_ID'),
59
+			$wpdb->prefix . 'esp_question_option'         => array('QSO_ID'),
60
+			$wpdb->prefix . 'esp_registration'            => array('REG_ID'),
61
+			$wpdb->prefix . 'esp_status'                  => array('STS_ID'),
62
+			$wpdb->prefix . 'esp_transaction'             => array('TXN_ID'),
63
+			$wpdb->prefix . 'esp_transaction'             => array('TXN_ID'),
64
+			$wpdb->prefix . 'events_detail'               => array('id'),
65
+			$wpdb->prefix . 'events_category_detail'      => array('id'),
66
+			$wpdb->prefix . 'events_category_rel'         => array('id'),
67
+			$wpdb->prefix . 'events_venue'                => array('id'),
68
+			$wpdb->prefix . 'events_venue_rel'            => array('emeta_id'),
69
+			$wpdb->prefix . 'events_locale'               => array('id'),
70
+			$wpdb->prefix . 'events_locale_rel'           => array('id'),
71
+			$wpdb->prefix . 'events_personnel'            => array('id'),
72
+			$wpdb->prefix . 'events_personnel_rel'        => array('id'),
73
+		);
74
+	}
75
+
76
+
77
+	/**
78
+	 *        @ singleton method used to instantiate class object
79
+	 *        @ access public
80
+	 *
81
+	 * @return EE_CSV
82
+	 */
83
+	public static function instance()
84
+	{
85
+		// check if class object is instantiated
86
+		if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_CSV)) {
87
+			self::$_instance = new self();
88
+		}
89
+		return self::$_instance;
90
+	}
91
+
92
+	/**
93
+	 * Opens a unicode or utf file (normal file_get_contents has difficulty readin ga unicode file. @see
94
+	 * http://stackoverflow.com/questions/15092764/how-to-read-unicode-text-file-in-php
95
+	 *
96
+	 * @param string $file_path
97
+	 * @return string
98
+	 * @throws EE_Error
99
+	 */
100
+	private function read_unicode_file($file_path)
101
+	{
102
+		$fc = "";
103
+		$fh = fopen($file_path, "rb");
104
+		if (! $fh) {
105
+			throw new EE_Error(sprintf(esc_html__("Cannot open file for read: %s<br>\n", 'event_espresso'), $file_path));
106
+		}
107
+		$flen = filesize($file_path);
108
+		$bc = fread($fh, $flen);
109
+		for ($i = 0; $i < $flen; $i++) {
110
+			$c = substr($bc, $i, 1);
111
+			if ((ord($c) != 0) && (ord($c) != 13)) {
112
+				$fc = $fc . $c;
113
+			}
114
+		}
115
+		if ((ord(substr($fc, 0, 1)) == 255) && (ord(substr($fc, 1, 1)) == 254)) {
116
+			$fc = substr($fc, 2);
117
+		}
118
+		return ($fc);
119
+	}
120
+
121
+
122
+	/**
123
+	 * Generic CSV-functionality to turn an entire CSV file into a single array that's
124
+	 * NOT in a specific format to EE. It's just a 2-level array, with top-level arrays
125
+	 * representing each row in the CSV file, and the second-level arrays being each column in that row
126
+	 *
127
+	 * @param string $path_to_file
128
+	 * @return array of arrays. Top-level array has rows, second-level array has each item
129
+	 */
130
+	public function import_csv_to_multi_dimensional_array($path_to_file)
131
+	{
132
+		// needed to deal with Mac line endings
133
+		ini_set('auto_detect_line_endings', true);
134
+
135
+		// because fgetcsv does not correctly deal with backslashed quotes such as \"
136
+		// we'll read the file into a string
137
+		$file_contents = $this->read_unicode_file($path_to_file);
138
+		// replace backslashed quotes with CSV enclosures
139
+		$file_contents = str_replace('\\"', '"""', $file_contents);
140
+		// HEY YOU! PUT THAT FILE BACK!!!
141
+		file_put_contents($path_to_file, $file_contents);
142
+
143
+		if (($file_handle = fopen($path_to_file, "r")) !== false) {
144
+			# Set the parent multidimensional array key to 0.
145
+			$nn = 0;
146
+			$csvarray = array();
147
+
148
+			// in PHP 5.3 fgetcsv accepts a 5th parameter, but the pre 5.3 versions of fgetcsv choke if passed more than 4 - is that crazy or what?
149
+			if (version_compare(PHP_VERSION, '5.3.0') < 0) {
150
+				//  PHP 5.2- version
151
+				// loop through each row of the file
152
+				while (($data = fgetcsv($file_handle, 0, ',', '"')) !== false) {
153
+					$csvarray[] = $data;
154
+				}
155
+			} else {
156
+				// loop through each row of the file
157
+				while (($data = fgetcsv($file_handle, 0, ',', '"', '\\')) !== false) {
158
+					$csvarray[] = $data;
159
+				}
160
+			}
161
+			# Close the File.
162
+			fclose($file_handle);
163
+			return $csvarray;
164
+		} else {
165
+			EE_Error::add_error(
166
+				sprintf(esc_html__("An error occurred - the file: %s could not opened.", "event_espresso"), $path_to_file),
167
+				__FILE__,
168
+				__FUNCTION__,
169
+				__LINE__
170
+			);
171
+			return false;
172
+		}
173
+	}
174
+
175
+
176
+	/**
177
+	 * @Import contents of csv file and store values in an array to be manipulated by other functions
178
+	 * @access public
179
+	 * @param string  $path_to_file         - the csv file to be imported including the path to it's location.
180
+	 *                                      If $model_name is provided, assumes that each row in the CSV represents a
181
+	 *                                      model object for that model If $model_name ISN'T provided, assumes that
182
+	 *                                      before model object data, there is a row where the first entry is simply
183
+	 *                                      'MODEL', and next entry is the model's name, (untranslated) like Event, and
184
+	 *                                      then maybe a row of headers, and then the model data. Eg.
185
+	 *                                      '<br>MODEL,Event,<br>EVT_ID,EVT_name,...<br>1,Monkey
186
+	 *                                      Party,...<br>2,Llamarama,...<br>MODEL,Venue,<br>VNU_ID,VNU_name<br>1,The
187
+	 *                                      Forest
188
+	 * @param string  $model_name           model name if we know what model we're importing
189
+	 * @param boolean $first_row_is_headers - whether the first row of data is headers or not - TRUE = headers, FALSE =
190
+	 *                                      data
191
+	 * @return mixed - array on success - multi dimensional with headers as keys (if headers exist) OR string on fail -
192
+	 *               error message like the following array('Event'=>array( array('EVT_ID'=>1,'EVT_name'=>'bob
193
+	 *               party',...), array('EVT_ID'=>2,'EVT_name'=>'llamarama',...),
194
+	 *                                      ...
195
+	 *                                      )
196
+	 *                                      'Venue'=>array(
197
+	 *                                      array('VNU_ID'=>1,'VNU_name'=>'the shack',...),
198
+	 *                                      array('VNU_ID'=>2,'VNU_name'=>'tree house',...),
199
+	 *                                      ...
200
+	 *                                      )
201
+	 *                                      ...
202
+	 *                                      )
203
+	 */
204
+	public function import_csv_to_model_data_array($path_to_file, $model_name = false, $first_row_is_headers = true)
205
+	{
206
+		$multi_dimensional_array = $this->import_csv_to_multi_dimensional_array($path_to_file);
207
+		if (! $multi_dimensional_array) {
208
+			return false;
209
+		}
210
+		// gotta start somewhere
211
+		$row = 1;
212
+		// array to store csv data in
213
+		$ee_formatted_data = array();
214
+		// array to store headers (column names)
215
+		$headers = array();
216
+		foreach ($multi_dimensional_array as $data) {
217
+			// if first cell is MODEL, then second cell is the MODEL name
218
+			if ($data[0] == 'MODEL') {
219
+				$model_name = $data[1];
220
+				// don't bother looking for model data in this row. The rest of this
221
+				// row should be blank
222
+				// AND pretend this is the first row again
223
+				$row = 1;
224
+				// reset headers
225
+				$headers = array();
226
+				continue;
227
+			}
228
+			if (strpos($data[0], EE_CSV::metadata_header) !== false) {
229
+				$model_name = EE_CSV::metadata_header;
230
+				// store like model data, we just won't try importing it etc.
231
+				$row = 1;
232
+				continue;
233
+			}
234
+
235
+
236
+			// how many columns are there?
237
+			$columns = count($data);
238
+
239
+			$model_entry = array();
240
+			// loop through each column
241
+			for ($i = 0; $i < $columns; $i++) {
242
+				// replace csv_enclosures with backslashed quotes
243
+				$data[ $i ] = str_replace('"""', '\\"', $data[ $i ]);
244
+				// do we need to grab the column names?
245
+				if ($row === 1) {
246
+					if ($first_row_is_headers) {
247
+						// store the column names to use for keys
248
+						$column_name = $data[ $i ];
249
+						// check it's not blank... sometimes CSV editign programs adda bunch of empty columns onto the end...
250
+						if (! $column_name) {
251
+							continue;
252
+						}
253
+						$matches = array();
254
+						if ($model_name == EE_CSV::metadata_header) {
255
+							$headers[ $i ] = $column_name;
256
+						} else {
257
+							// now get the db table name from it (the part between square brackets)
258
+							$success = preg_match('~(.*)\[(.*)\]~', $column_name, $matches);
259
+							if (! $success) {
260
+								EE_Error::add_error(
261
+									sprintf(
262
+										esc_html__(
263
+											"The column titled %s is invalid for importing. It must be be in the format of 'Nice Name[model_field_name]' in row %s",
264
+											"event_espresso"
265
+										),
266
+										$column_name,
267
+										implode(",", $data)
268
+									),
269
+									__FILE__,
270
+									__FUNCTION__,
271
+									__LINE__
272
+								);
273
+								return false;
274
+							}
275
+							$headers[ $i ] = $matches[2];
276
+						}
277
+					} else {
278
+						// no column names means our final array will just use counters for keys
279
+						$model_entry[ $headers[ $i ] ] = $data[ $i ];
280
+						$headers[ $i ] = $i;
281
+					}
282
+					// and we need to store csv data
283
+				} else {
284
+					// this column isn' ta header, store it if there is a header for it
285
+					if (isset($headers[ $i ])) {
286
+						$model_entry[ $headers[ $i ] ] = $data[ $i ];
287
+					}
288
+				}
289
+			}
290
+			// save the row's data IF it's a non-header-row
291
+			if (! $first_row_is_headers || ($first_row_is_headers && $row > 1)) {
292
+				$ee_formatted_data[ $model_name ][] = $model_entry;
293
+			}
294
+			// advance to next row
295
+			$row++;
296
+		}
297
+
298
+		// delete the uploaded file
299
+		unlink($path_to_file);
300
+		// echo '<pre style="height:auto;border:2px solid lightblue;">' . print_r( $ee_formatted_data, TRUE ) . '</pre><br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>';
301
+		// die();
302
+
303
+		// it's good to give back
304
+		return $ee_formatted_data;
305
+	}
306
+
307
+
308
+	public function save_csv_to_db($csv_data_array, $model_name = false)
309
+	{
310
+		EE_Error::doing_it_wrong(
311
+			'save_csv_to_db',
312
+			esc_html__(
313
+				'Function moved to EE_Import and renamed to save_csv_data_array_to_db',
314
+				'event_espresso'
315
+			),
316
+			'4.6.7'
317
+		);
318
+		return EE_Import::instance()->save_csv_data_array_to_db($csv_data_array, $model_name);
319
+	}
320
+
321
+	/**
322
+	 * Sends HTTP headers to indicate that the browser should download a file,
323
+	 * and starts writing the file to PHP's output. Returns the file handle so other functions can
324
+	 * also write to it
325
+	 *
326
+	 * @param string $new_filename the name of the file that the user will download
327
+	 * @return resource, like the results of fopen(), which can be used for fwrite, fputcsv2, etc.
328
+	 */
329
+	public function begin_sending_csv($filename)
330
+	{
331
+		// grab file extension
332
+		$ext = substr(strrchr($filename, '.'), 1);
333
+		if ($ext == '.csv' or $ext == '.xls') {
334
+			str_replace($ext, '', $filename);
335
+		}
336
+		$filename .= '.csv';
337
+
338
+		// if somebody's been naughty and already started outputting stuff, trash it
339
+		// and start writing our stuff.
340
+		if (ob_get_length()) {
341
+			@ob_flush();
342
+			@flush();
343
+			@ob_end_flush();
344
+		}
345
+		@ob_start();
346
+		header("Pragma: public");
347
+		header("Expires: 0");
348
+		header("Pragma: no-cache");
349
+		header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
350
+		// header("Content-Type: application/force-download");
351
+		// header("Content-Type: application/octet-stream");
352
+		// header("Content-Type: application/download");
353
+		header('Content-disposition: attachment; filename=' . $filename);
354
+		header("Content-Type: text/csv; charset=utf-8");
355
+		do_action('AHEE__EE_CSV__begin_sending_csv__headers');
356
+		echo apply_filters(
357
+			'FHEE__EE_CSV__begin_sending_csv__start_writing',
358
+			"\xEF\xBB\xBF"
359
+		); // makes excel open it as UTF-8. UTF-8 BOM, see http://stackoverflow.com/a/4440143/2773835
360
+		$fh = fopen('php://output', 'w');
361
+		return $fh;
362
+	}
363
+
364
+	/**
365
+	 * Writes some meta data to the CSV as a bunch of columns. Initially we're only
366
+	 * mentioning the version and timezone
367
+	 *
368
+	 * @param resource $filehandle
369
+	 */
370
+	public function write_metadata_to_csv($filehandle)
371
+	{
372
+		$data_row = array(EE_CSV::metadata_header);// do NOT translate because this exact string is used when importing
373
+		$this->fputcsv2($filehandle, $data_row);
374
+		$meta_data = array(
375
+			0 => array(
376
+				'version'        => espresso_version(),
377
+				'timezone'       => EEH_DTT_Helper::get_timezone(),
378
+				'time_of_export' => current_time('mysql'),
379
+				'site_url'       => site_url(),
380
+			),
381
+		);
382
+		$this->write_data_array_to_csv($filehandle, $meta_data);
383
+	}
384
+
385
+
386
+	/**
387
+	 * Writes $data to the csv file open in $filehandle. uses the array indices of $data for column headers
388
+	 *
389
+	 * @param array   $data                 2D array, first numerically-indexed, and next-level-down preferably indexed
390
+	 *                                      by string
391
+	 * @param boolean $add_csv_column_names whether or not we should add the keys in the bottom-most array as a row for
392
+	 *                                      headers in the CSV. Eg, if $data looked like
393
+	 *                                      array(0=>array('EVT_ID'=>1,'EVT_name'=>'monkey'...), 1=>array(...),...))
394
+	 *                                      then the first row we'd write to the CSV would be "EVT_ID,EVT_name,..."
395
+	 * @return boolean if we successfully wrote to the CSV or not. If there's no $data, we consider that a success
396
+	 *                 (because we wrote everything there was...nothing)
397
+	 */
398
+	public function write_data_array_to_csv($filehandle, $data)
399
+	{
400
+
401
+
402
+		// determine if $data is actually a 2d array
403
+		if ($data && is_array($data) && is_array(EEH_Array::get_one_item_from_array($data))) {
404
+			// make sure top level is numerically indexed,
405
+
406
+			if (EEH_Array::is_associative_array($data)) {
407
+				throw new EE_Error(
408
+					sprintf(
409
+						esc_html__(
410
+							"top-level array must be numerically indexed. Does these look like numbers to you? %s",
411
+							"event_espresso"
412
+						),
413
+						implode(",", array_keys($data))
414
+					)
415
+				);
416
+			}
417
+			$item_in_top_level_array = EEH_Array::get_one_item_from_array($data);
418
+			// now, is the last item in the top-level array of $data an associative or numeric array?
419
+			if (EEH_Array::is_associative_array($item_in_top_level_array)) {
420
+				// its associative, so we want to output its keys as column headers
421
+				$keys = array_keys($item_in_top_level_array);
422
+				$this->fputcsv2($filehandle, $keys);
423
+			}
424
+			// start writing data
425
+			foreach ($data as $data_row) {
426
+				$this->fputcsv2($filehandle, $data_row);
427
+			}
428
+			return true;
429
+		} else {
430
+			// no data TO write... so we can assume that's a success
431
+			return true;
432
+		}
433
+		// //if 2nd level is indexed by strings, use those as csv column headers (ie, the first row)
434
+		//
435
+		//
436
+		// $no_table = TRUE;
437
+		//
438
+		// // loop through data and add each row to the file/stream as csv
439
+		// foreach ( $data as $model_name => $model_data ) {
440
+		// // test first row to see if it is data or a model name
441
+		// $model = EE_Registry::instance();->load_model($model_name);
442
+		// //if the model really exists,
443
+		// if ( $model ) {
444
+		//
445
+		// // we have a table name
446
+		// $no_table = FALSE;
447
+		//
448
+		// // put the tablename into an array cuz that's how fputcsv rolls
449
+		// $model_name_row = array( 'MODEL', $model_name );
450
+		//
451
+		// // add table name to csv output
452
+		// echo self::fputcsv2($filehandle, $model_name_row);
453
+		//
454
+		// // now get the rest of the data
455
+		// foreach ( $model_data as $row ) {
456
+		// // output the row
457
+		// echo self::fputcsv2($filehandle, $row);
458
+		// }
459
+		//
460
+		// }
461
+		//
462
+		// if ( $no_table ) {
463
+		// // no table so just put the data
464
+		// echo self::fputcsv2($filehandle, $model_data);
465
+		// }
466
+		//
467
+		// } // END OF foreach ( $data )
468
+	}
469
+
470
+	/**
471
+	 * Should be called after begin_sending_csv(), and one or more write_data_array_to_csv()s.
472
+	 * Calls exit to prevent polluting the CSV file with other junk
473
+	 *
474
+	 * @param resource $fh filehandle where we're writing the CSV to
475
+	 */
476
+	public function end_sending_csv($fh)
477
+	{
478
+		fclose($fh);
479
+		exit(0);
480
+	}
481
+
482
+	/**
483
+	 * Given an open file, writes all the model data to it in the format the importer expects.
484
+	 * Usually preceded by begin_sending_csv($filename), and followed by end_sending_csv($filehandle).
485
+	 *
486
+	 * @param resource $filehandle
487
+	 * @param array    $model_data_array is assumed to be a 3d array: 1st layer has keys of model names (eg 'Event'),
488
+	 *                                   next layer is numerically indexed to represent each model object (eg, each
489
+	 *                                   individual event), and the last layer has all the attributes o fthat model
490
+	 *                                   object (eg, the event's id, name, etc)
491
+	 * @return boolean success
492
+	 */
493
+	public function write_model_data_to_csv($filehandle, $model_data_array)
494
+	{
495
+		$this->write_metadata_to_csv($filehandle);
496
+		foreach ($model_data_array as $model_name => $model_instance_arrays) {
497
+			// first: output a special row stating the model
498
+			$this->fputcsv2($filehandle, array('MODEL', $model_name));
499
+			// if we have items to put in the CSV, do it normally
500
+
501
+			if (! empty($model_instance_arrays)) {
502
+				$this->write_data_array_to_csv($filehandle, $model_instance_arrays);
503
+			} else {
504
+				// echo "no data to write... so just write the headers";
505
+				// so there's actually NO model objects for that model.
506
+				// probably still want to show the columns
507
+				$model = EE_Registry::instance()->load_model($model_name);
508
+				$column_names = array();
509
+				foreach ($model->field_settings() as $field) {
510
+					$column_names[ $field->get_nicename() . "[" . $field->get_name() . "]" ] = null;
511
+				}
512
+				$this->write_data_array_to_csv($filehandle, array($column_names));
513
+			}
514
+		}
515
+	}
516
+
517
+	/**
518
+	 * Writes the CSV file to the output buffer, with rows corresponding to $model_data_array,
519
+	 * and dies (in order to avoid other plugins from messing up the csv output)
520
+	 *
521
+	 * @param string $filename         the filename you want to give the file
522
+	 * @param array  $model_data_array 3d array, as described in EE_CSV::write_model_data_to_csv()
523
+	 * @return bool | void writes CSV file to output and dies
524
+	 */
525
+	public function export_multiple_model_data_to_csv($filename, $model_data_array)
526
+	{
527
+		$filehandle = $this->begin_sending_csv($filename);
528
+		$this->write_model_data_to_csv($filehandle, $model_data_array);
529
+		$this->end_sending_csv($filehandle);
530
+	}
531
+
532
+	/**
533
+	 * @Export contents of an array to csv file
534
+	 * @access public
535
+	 * @param array  $data     - the array of data to be converted to csv and exported
536
+	 * @param string $filename - name for newly created csv file
537
+	 * @return TRUE on success, FALSE on fail
538
+	 */
539
+	public function export_array_to_csv($data = false, $filename = false)
540
+	{
541
+
542
+		// no data file?? get outta here
543
+		if (! $data or ! is_array($data) or empty($data)) {
544
+			return false;
545
+		}
546
+
547
+		// no filename?? get outta here
548
+		if (! $filename) {
549
+			return false;
550
+		}
551
+
552
+
553
+		// somebody told me i might need this ???
554
+		global $wpdb;
555
+		$prefix = $wpdb->prefix;
556
+
557
+
558
+		$fh = $this->begin_sending_csv($filename);
559
+
560
+
561
+		$this->end_sending_csv($fh);
562
+	}
563
+
564
+
565
+	/**
566
+	 * @Determine the maximum upload file size based on php.ini settings
567
+	 * @access    public
568
+	 * @param int $percent_of_max - desired percentage of the max upload_mb
569
+	 * @return int KB
570
+	 */
571
+	public function get_max_upload_size($percent_of_max = false)
572
+	{
573
+
574
+		$max_upload = (int) (ini_get('upload_max_filesize'));
575
+		$max_post = (int) (ini_get('post_max_size'));
576
+		$memory_limit = (int) (ini_get('memory_limit'));
577
+
578
+		// determine the smallest of the three values from above
579
+		$upload_mb = min($max_upload, $max_post, $memory_limit);
580
+
581
+		// convert MB to KB
582
+		$upload_mb = $upload_mb * 1024;
583
+
584
+		// don't want the full monty? then reduce the max uplaod size
585
+		if ($percent_of_max) {
586
+			// is percent_of_max like this -> 50 or like this -> 0.50 ?
587
+			if ($percent_of_max > 1) {
588
+				// chnages 50 to 0.50
589
+				$percent_of_max = $percent_of_max / 100;
590
+			}
591
+			// make upload_mb a percentage of the max upload_mb
592
+			$upload_mb = $upload_mb * $percent_of_max;
593
+		}
594
+
595
+		return $upload_mb;
596
+	}
597
+
598
+
599
+	/**
600
+	 * @Drop   in replacement for PHP's fputcsv function - but this one works!!!
601
+	 * @access private
602
+	 * @param resource $fh         - file handle - what we are writing to
603
+	 * @param array    $row        - individual row of csv data
604
+	 * @param string   $delimiter  - csv delimiter
605
+	 * @param string   $enclosure  - csv enclosure
606
+	 * @param string   $mysql_null - allows php NULL to be overridden with MySQl's insertable NULL value
607
+	 * @return void
608
+	 */
609
+	private function fputcsv2($fh, array $row, $delimiter = ',', $enclosure = '"', $mysql_null = false)
610
+	{
611
+		// Allow user to filter the csv delimiter and enclosure for other countries csv standards
612
+		$delimiter = apply_filters('FHEE__EE_CSV__fputcsv2__delimiter', $delimiter);
613
+		$enclosure = apply_filters('FHEE__EE_CSV__fputcsv2__enclosure', $enclosure);
614
+
615
+		$delimiter_esc = preg_quote($delimiter, '/');
616
+		$enclosure_esc = preg_quote($enclosure, '/');
617
+
618
+		$output = array();
619
+		foreach ($row as $field_value) {
620
+			if (is_object($field_value) || is_array($field_value)) {
621
+				$field_value = serialize($field_value);
622
+			}
623
+			if ($field_value === null && $mysql_null) {
624
+				$output[] = 'NULL';
625
+				continue;
626
+			}
627
+
628
+			$output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field_value) ?
629
+				($enclosure . str_replace($enclosure, $enclosure . $enclosure, $field_value) . $enclosure)
630
+				: $field_value;
631
+		}
632
+
633
+		fwrite($fh, join($delimiter, $output) . PHP_EOL);
634
+	}
635
+
636
+
637
+	// /**
638
+	//  * @CSV    Import / Export messages
639
+	//  * @access public
640
+	//  * @return void
641
+	//  */
642
+	// public function csv_admin_notices()
643
+	// {
644
+	//
645
+	//     // We play both kinds of music here! Country AND Western! - err... I mean, cycle through both types of notices
646
+	//     foreach (array('updates', 'errors') as $type) {
647
+	//
648
+	//         // if particular notice type is not empty, then "You've got Mail"
649
+	//         if (! empty($this->_notices[ $type ])) {
650
+	//
651
+	//             // is it an update or an error ?
652
+	//             $msg_class = $type == 'updates' ? 'updated' : 'error';
653
+	//             echo '<div id="message" class="' . $msg_class . '">';
654
+	//             // display each notice, however many that may be
655
+	//             foreach ($this->_notices[ $type ] as $message) {
656
+	//                 echo '<p>' . $message . '</p>';
657
+	//             }
658
+	//             // wrap it up
659
+	//             echo '</div>';
660
+	//         }
661
+	//     }
662
+	// }
663
+
664
+	/**
665
+	 * Gets the date format to use in teh csv. filterable
666
+	 *
667
+	 * @param string $current_format
668
+	 * @return string
669
+	 */
670
+	public function get_date_format_for_csv($current_format = null)
671
+	{
672
+		return apply_filters('FHEE__EE_CSV__get_date_format_for_csv__format', 'Y-m-d', $current_format);
673
+	}
674
+
675
+	/**
676
+	 * Gets the time format we want to use in CSV reports. Filterable
677
+	 *
678
+	 * @param string $current_format
679
+	 * @return string
680
+	 */
681
+	public function get_time_format_for_csv($current_format = null)
682
+	{
683
+		return apply_filters('FHEE__EE_CSV__get_time_format_for_csv__format', 'H:i:s', $current_format);
684
+	}
685 685
 }
Please login to merge, or discard this patch.
core/helpers/EEH_Form_Fields.helper.php 2 patches
Indentation   +2063 added lines, -2063 removed lines patch added patch discarded remove patch
@@ -27,1056 +27,1056 @@  discard block
 block discarded – undo
27 27
  */
28 28
 class EEH_Form_Fields
29 29
 {
30
-    /**
31
-     *  Generates HTML for the forms used on admin pages
32
-     *
33
-     *
34
-     * @static
35
-     * @access public
36
-     * @param array $input_vars - array of input field details
37
-     *                          format:
38
-     *                          $template_form_fields['field-id'] = array(
39
-     *                          'name' => 'name_attribute',
40
-     *                          'label' => esc_html__('Field Label', 'event_espresso'), //or false
41
-     *                          'input' => 'hidden', //field input type can be 'text', 'select', 'textarea', 'hidden',
42
-     *                          'checkbox', 'wp_editor'
43
-     *                          'type' => 'int', //what "type" the value is (i.e. string, int etc)
44
-     *                          'required' => false, //boolean for whether the field is required
45
-     *                          'validation' => true, //boolean, whether to validate the field (todo)
46
-     *                          'value' => 'some_value_for_field', //what value is used for field
47
-     *                          'format' => '%d', //what format the value is (%d, %f, or %s)
48
-     *                          'db-col' => 'column_in_db' //used to indicate which column the field corresponds with
49
-     *                          in the db
50
-     *                          'options' => optiona, optionb || array('value' => 'label', '') //if the input type is
51
-     *                          "select", this allows you to set the args for the different <option> tags.
52
-     *                          'tabindex' => 1 //this allows you to set the tabindex for the field.
53
-     *                          'append_content' => '' //this allows you to send in html content to append to the
54
-     *                          field.
55
-     *                          )
56
-     * @param array $form_id    - used for defining unique identifiers for the form.
57
-     * @return string
58
-     * @todo   : at some point we can break this down into other static methods to abstract it a bit better.
59
-     */
60
-    public static function get_form_fields($input_vars = [], $form_id = false)
61
-    {
62
-
63
-        if (empty($input_vars)) {
64
-            EE_Error::add_error(
65
-                esc_html__('missing required variables for the form field generator', 'event_espresso'),
66
-                __FILE__,
67
-                __FUNCTION__,
68
-                __LINE__
69
-            );
70
-            return false;
71
-        }
72
-
73
-        $output        = "";
74
-        $inputs        = [];
75
-        $hidden_inputs = [];
76
-
77
-        // cycle thru inputs
78
-        foreach ($input_vars as $input_key => $input_value) {
79
-            $defaults = [
80
-                'append_content' => '',
81
-                'css_class'      => '',
82
-                'cols'           => 80,
83
-                'db-col'         => 'column_in_db',
84
-                'format'         => '%d',
85
-                'input'          => 'hidden',
86
-                'label'          => esc_html__('No label', 'event_espresso'),
87
-                'name'           => $input_key,
88
-                'options'        => [],
89
-                'required'       => false,
90
-                'tabindex'       => 0,
91
-                'rows'           => 10,
92
-                'type'           => 'int',
93
-                'validation'     => true,
94
-                'value'          => 'some_value_for_field',
95
-            ];
96
-
97
-            $input_value = wp_parse_args($input_value, $defaults);
98
-
99
-            $append_content = $input_value['append_content'];
100
-            $css_class      = $input_value['css_class'];
101
-            $cols           = $input_value['cols'];
102
-            $label          = $input_value['label'];
103
-            $name           = $input_value['name'];
104
-            $options        = $input_value['options'];
105
-            $required       = $input_value['required'];
106
-            $tab_index      = $input_value['tabindex'];
107
-            $rows           = $input_value['rows'];
108
-            $type           = $input_value['input'];
109
-            $value          = $input_value['value'];
110
-
111
-            $id    = $form_id ? $form_id . '-' . $input_key : $input_key;
112
-            $class = $required ? 'required ' . $css_class : $css_class;
113
-
114
-            // what type of input are we dealing with ?
115
-            switch ($type) {
116
-                case 'checkbox':
117
-                case 'radio':
118
-                    $field = self::adminMulti($value, $class, $id, $name, $required, $tab_index, $type, 1, $label);
119
-                    $field .= $append_content ?: '';
120
-                    break;
121
-
122
-                case 'hidden':
123
-                    $field           = null;
124
-                    $hidden_inputs[] = self::adminHidden($css_class, $id, $name, $value);
125
-                    break;
126
-
127
-                case 'select':
128
-                    $options = is_array($options) ? $options : explode(',', $options);
129
-                    $field   = self::adminLabel($id, $label, $required);
130
-                    $field   .= self::adminSelect($value, $class, $id, $name, $required, $tab_index, $options);
131
-                    $field   .= $append_content ?: '';
132
-                    break;
133
-
134
-                case 'textarea':
135
-                    $field = self::adminLabel($id, $label, $required);
136
-                    $field .= self::adminTextarea($class, $cols, $id, $name, $required, $rows, $tab_index, $value);
137
-                    $field .= $append_content ?: '';
138
-                    break;
139
-
140
-                case 'wp_editor':
141
-                    $label = esc_html($label);
142
-                    $field = "<h4>{$label}</h4>";
143
-                    $field .= $append_content ?: '';
144
-                    $field .= self::adminWpEditor(
145
-                        $class,
146
-                        $id,
147
-                        $name,
148
-                        $rows,
149
-                        $tab_index,
150
-                        $value
151
-                    );
152
-                    break;
153
-
154
-                default:
155
-                    $field = self::adminLabel($id, $label, $required);
156
-                    $field .= self::adminText($class, $id, $name, $required, $tab_index, $value);
157
-                    $field .= $append_content ?: '';
158
-            }
159
-            if ($field) {
160
-                $inputs[] = $field;
161
-            }
162
-        } // end foreach( $input_vars as $input_key => $input_value )
163
-
164
-        if (! empty($inputs)) {
165
-            $glue   = "
30
+	/**
31
+	 *  Generates HTML for the forms used on admin pages
32
+	 *
33
+	 *
34
+	 * @static
35
+	 * @access public
36
+	 * @param array $input_vars - array of input field details
37
+	 *                          format:
38
+	 *                          $template_form_fields['field-id'] = array(
39
+	 *                          'name' => 'name_attribute',
40
+	 *                          'label' => esc_html__('Field Label', 'event_espresso'), //or false
41
+	 *                          'input' => 'hidden', //field input type can be 'text', 'select', 'textarea', 'hidden',
42
+	 *                          'checkbox', 'wp_editor'
43
+	 *                          'type' => 'int', //what "type" the value is (i.e. string, int etc)
44
+	 *                          'required' => false, //boolean for whether the field is required
45
+	 *                          'validation' => true, //boolean, whether to validate the field (todo)
46
+	 *                          'value' => 'some_value_for_field', //what value is used for field
47
+	 *                          'format' => '%d', //what format the value is (%d, %f, or %s)
48
+	 *                          'db-col' => 'column_in_db' //used to indicate which column the field corresponds with
49
+	 *                          in the db
50
+	 *                          'options' => optiona, optionb || array('value' => 'label', '') //if the input type is
51
+	 *                          "select", this allows you to set the args for the different <option> tags.
52
+	 *                          'tabindex' => 1 //this allows you to set the tabindex for the field.
53
+	 *                          'append_content' => '' //this allows you to send in html content to append to the
54
+	 *                          field.
55
+	 *                          )
56
+	 * @param array $form_id    - used for defining unique identifiers for the form.
57
+	 * @return string
58
+	 * @todo   : at some point we can break this down into other static methods to abstract it a bit better.
59
+	 */
60
+	public static function get_form_fields($input_vars = [], $form_id = false)
61
+	{
62
+
63
+		if (empty($input_vars)) {
64
+			EE_Error::add_error(
65
+				esc_html__('missing required variables for the form field generator', 'event_espresso'),
66
+				__FILE__,
67
+				__FUNCTION__,
68
+				__LINE__
69
+			);
70
+			return false;
71
+		}
72
+
73
+		$output        = "";
74
+		$inputs        = [];
75
+		$hidden_inputs = [];
76
+
77
+		// cycle thru inputs
78
+		foreach ($input_vars as $input_key => $input_value) {
79
+			$defaults = [
80
+				'append_content' => '',
81
+				'css_class'      => '',
82
+				'cols'           => 80,
83
+				'db-col'         => 'column_in_db',
84
+				'format'         => '%d',
85
+				'input'          => 'hidden',
86
+				'label'          => esc_html__('No label', 'event_espresso'),
87
+				'name'           => $input_key,
88
+				'options'        => [],
89
+				'required'       => false,
90
+				'tabindex'       => 0,
91
+				'rows'           => 10,
92
+				'type'           => 'int',
93
+				'validation'     => true,
94
+				'value'          => 'some_value_for_field',
95
+			];
96
+
97
+			$input_value = wp_parse_args($input_value, $defaults);
98
+
99
+			$append_content = $input_value['append_content'];
100
+			$css_class      = $input_value['css_class'];
101
+			$cols           = $input_value['cols'];
102
+			$label          = $input_value['label'];
103
+			$name           = $input_value['name'];
104
+			$options        = $input_value['options'];
105
+			$required       = $input_value['required'];
106
+			$tab_index      = $input_value['tabindex'];
107
+			$rows           = $input_value['rows'];
108
+			$type           = $input_value['input'];
109
+			$value          = $input_value['value'];
110
+
111
+			$id    = $form_id ? $form_id . '-' . $input_key : $input_key;
112
+			$class = $required ? 'required ' . $css_class : $css_class;
113
+
114
+			// what type of input are we dealing with ?
115
+			switch ($type) {
116
+				case 'checkbox':
117
+				case 'radio':
118
+					$field = self::adminMulti($value, $class, $id, $name, $required, $tab_index, $type, 1, $label);
119
+					$field .= $append_content ?: '';
120
+					break;
121
+
122
+				case 'hidden':
123
+					$field           = null;
124
+					$hidden_inputs[] = self::adminHidden($css_class, $id, $name, $value);
125
+					break;
126
+
127
+				case 'select':
128
+					$options = is_array($options) ? $options : explode(',', $options);
129
+					$field   = self::adminLabel($id, $label, $required);
130
+					$field   .= self::adminSelect($value, $class, $id, $name, $required, $tab_index, $options);
131
+					$field   .= $append_content ?: '';
132
+					break;
133
+
134
+				case 'textarea':
135
+					$field = self::adminLabel($id, $label, $required);
136
+					$field .= self::adminTextarea($class, $cols, $id, $name, $required, $rows, $tab_index, $value);
137
+					$field .= $append_content ?: '';
138
+					break;
139
+
140
+				case 'wp_editor':
141
+					$label = esc_html($label);
142
+					$field = "<h4>{$label}</h4>";
143
+					$field .= $append_content ?: '';
144
+					$field .= self::adminWpEditor(
145
+						$class,
146
+						$id,
147
+						$name,
148
+						$rows,
149
+						$tab_index,
150
+						$value
151
+					);
152
+					break;
153
+
154
+				default:
155
+					$field = self::adminLabel($id, $label, $required);
156
+					$field .= self::adminText($class, $id, $name, $required, $tab_index, $value);
157
+					$field .= $append_content ?: '';
158
+			}
159
+			if ($field) {
160
+				$inputs[] = $field;
161
+			}
162
+		} // end foreach( $input_vars as $input_key => $input_value )
163
+
164
+		if (! empty($inputs)) {
165
+			$glue   = "
166 166
                 </li>
167 167
                 <li>
168 168
                     ";
169
-            $inputs = implode($glue, $inputs);
170
-            $output = "
169
+			$inputs = implode($glue, $inputs);
170
+			$output = "
171 171
             <ul>
172 172
                 <li>
173 173
                 {$inputs}
174 174
                 </li>
175 175
             </ul>
176 176
             ";
177
-        }
178
-        return $output . implode("\n", $hidden_inputs);
179
-    }
180
-
181
-
182
-    /**
183
-     * form_fields_array
184
-     * This utility function assembles form fields from a given structured array with field information.
185
-     * //TODO: This is an alternate generator that we may want to use instead.
186
-     *
187
-     * @param array $fields structured array of fields to assemble in the following format:
188
-     *                      [field_name] => array(
189
-     *                      ['label'] => 'label for field',
190
-     *                      ['labels'] => array('label_1', 'label_2'); //optional - if the field type is a multi select
191
-     *                      type of field you can indicated the labels for each option via this index
192
-     *                      ['extra_desc'] => 'extra description for the field', //optional
193
-     *                      ['type'] => 'textarea'|'text'|'wp_editor'|'checkbox'|'radio'|'hidden'|'select', //defaults
194
-     *                      to text
195
-     *                      ['value'] => 'value that goes in the field', //(if multi then this is an array of values
196
-     *                      and the 'default' paramater will be used for what is selected)
197
-     *                      ['default'] => 'default if the field type is multi (i.e. select or radios or checkboxes)',
198
-     *                      ['class'] => 'name-of-class(es)-for-input',
199
-     *                      ['classes'] => array('class_1', 'class_2'); //optional - if the field type is a multi
200
-     *                      select type of field you can indicate the css class for each option via this index.
201
-     *                      ['id'] => 'css-id-for-input') //defaults to 'field_name'
202
-     *                      ['unique_id'] => 1 //defaults to empty string.  This is useful for when the fields
203
-     *                      generated are going to be used in a loop and you want to make sure that the field
204
-     *                      identifiers are unique from each other.
205
-     *                      ['dimensions'] => array(100,300), //defaults to empty array.  This is used by field types
206
-     *                      such as textarea to indicate cols/rows.
207
-     *                      ['tabindex'] => '' //this allows you to set the tabindex for the field.
208
-     *                      ['wpeditor_args'] => array() //if the type of field is wpeditor then this can optionally
209
-     *                      contain an array of arguments for the editor setup.
210
-     *
211
-     * @return array         an array of inputs for form indexed by field name, and in the following structure:
212
-     *     [field_name] => array( 'label' => '{label_html}', 'field' => '{input_html}'
213
-     */
214
-    public static function get_form_fields_array($fields)
215
-    {
216
-
217
-        $form_fields = [];
218
-        $fields      = (array) $fields;
219
-
220
-        foreach ($fields as $field_name => $field_atts) {
221
-            // defaults:
222
-            $defaults = [
223
-                'class'         => '',
224
-                'classes'       => '',
225
-                'default'       => '',
226
-                'dimensions'    => ['10', '5'],
227
-                'extra_desc'    => '',
228
-                'id'            => $field_name,
229
-                'label'         => '',
230
-                'labels'        => '',
231
-                'required'      => false,
232
-                'tabindex'      => 0,
233
-                'type'          => 'text',
234
-                'unique_id'     => '',
235
-                'value'         => '',
236
-                'wpeditor_args' => [],
237
-            ];
238
-            // merge defaults with passed arguments
239
-            $_fields = wp_parse_args($field_atts, $defaults);
240
-
241
-            $class          = $_fields['class'];
242
-            $classes        = $_fields['classes'];
243
-            $default        = $_fields['default'];
244
-            $dims           = $_fields['dimensions'];
245
-            $extra_desc     = $_fields['extra_desc'];
246
-            $id             = $_fields['id'];
247
-            $label          = $_fields['label'];
248
-            $labels         = $_fields['labels'];
249
-            $required       = $_fields['required'];
250
-            $tab_index      = $_fields['tabindex'];
251
-            $type           = $_fields['type'];
252
-            $unique_id      = $_fields['unique_id'];
253
-            $value          = $_fields['value'];
254
-            $wp_editor_args = $_fields['wpeditor_args'];
255
-
256
-            // generate label
257
-            $label = ! empty($label) ? self::adminLabel($id, $label, $required) : '';
258
-            // generate field name
259
-            $name = ! empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
260
-
261
-            // we determine what we're building based on the type
262
-            switch ($type) {
263
-                case 'checkbox':
264
-                case 'radio':
265
-                    if (is_array($value)) {
266
-                        $c_input = '';
267
-                        foreach ($value as $key => $val) {
268
-                            $c_input .= self::adminMulti(
269
-                                $default,
270
-                                isset($classes[ $key ]) ? $classes[ $key ] : '',
271
-                                $field_name . '_' . $value,
272
-                                $name,
273
-                                $required,
274
-                                $tab_index,
275
-                                $type,
276
-                                $val,
277
-                                isset($labels[ $key ]) ? $labels[ $key ] : ''
278
-                            );
279
-                        }
280
-                        $field = $c_input;
281
-                    } else {
282
-                        $field = self::adminMulti(
283
-                            $default,
284
-                            $class,
285
-                            $id,
286
-                            $name,
287
-                            $required,
288
-                            $tab_index,
289
-                            $type,
290
-                            $value,
291
-                            $_fields['label']
292
-                        );
293
-                    }
294
-                    break;
295
-
296
-                case 'hidden':
297
-                    $field = self::adminHidden($class, $id, $name, $value);
298
-                    break;
299
-
300
-                case 'select':
301
-                    $options = [];
302
-                    foreach ($value as $key => $val) {
303
-                        $options[ $val ] = isset($labels[ $key ]) ? $labels[ $key ] : '';
304
-                    }
305
-                    $field = self::adminSelect($default, $class, $id, $name, $required, $tab_index, $options);
306
-                    break;
307
-
308
-                case 'textarea':
309
-                    $field =
310
-                        self::adminTextarea($class, $dims[0], $id, $name, $required, $dims[1], $tab_index, $value);
311
-                    break;
312
-
313
-                case 'wp_editor':
314
-                    $field = self::adminWpEditor(
315
-                        $class,
316
-                        $_fields['id'],
317
-                        $name,
318
-                        $dims[1],
319
-                        $tab_index,
320
-                        $value,
321
-                        $wp_editor_args
322
-                    );
323
-                    break;
324
-
325
-                default:
326
-                    $field = self::adminText($class, $id, $name, $required, $tab_index, $value);
327
-            }
328
-
329
-            $form_fields[ $field_name ] = ['label' => $label, 'field' => $field . $extra_desc];
330
-        }
331
-
332
-        return $form_fields;
333
-    }
334
-
335
-
336
-    /**
337
-     * @param string $class
338
-     * @param string $id
339
-     * @param string $name
340
-     * @param string $value
341
-     * @return string
342
-     * @since   4.10.14.p
343
-     */
344
-    private static function adminHidden($class, $id, $name, $value)
345
-    {
346
-        $id    = esc_attr($id);
347
-        $name  = esc_attr($name);
348
-        $class = esc_attr($class);
349
-        return "
177
+		}
178
+		return $output . implode("\n", $hidden_inputs);
179
+	}
180
+
181
+
182
+	/**
183
+	 * form_fields_array
184
+	 * This utility function assembles form fields from a given structured array with field information.
185
+	 * //TODO: This is an alternate generator that we may want to use instead.
186
+	 *
187
+	 * @param array $fields structured array of fields to assemble in the following format:
188
+	 *                      [field_name] => array(
189
+	 *                      ['label'] => 'label for field',
190
+	 *                      ['labels'] => array('label_1', 'label_2'); //optional - if the field type is a multi select
191
+	 *                      type of field you can indicated the labels for each option via this index
192
+	 *                      ['extra_desc'] => 'extra description for the field', //optional
193
+	 *                      ['type'] => 'textarea'|'text'|'wp_editor'|'checkbox'|'radio'|'hidden'|'select', //defaults
194
+	 *                      to text
195
+	 *                      ['value'] => 'value that goes in the field', //(if multi then this is an array of values
196
+	 *                      and the 'default' paramater will be used for what is selected)
197
+	 *                      ['default'] => 'default if the field type is multi (i.e. select or radios or checkboxes)',
198
+	 *                      ['class'] => 'name-of-class(es)-for-input',
199
+	 *                      ['classes'] => array('class_1', 'class_2'); //optional - if the field type is a multi
200
+	 *                      select type of field you can indicate the css class for each option via this index.
201
+	 *                      ['id'] => 'css-id-for-input') //defaults to 'field_name'
202
+	 *                      ['unique_id'] => 1 //defaults to empty string.  This is useful for when the fields
203
+	 *                      generated are going to be used in a loop and you want to make sure that the field
204
+	 *                      identifiers are unique from each other.
205
+	 *                      ['dimensions'] => array(100,300), //defaults to empty array.  This is used by field types
206
+	 *                      such as textarea to indicate cols/rows.
207
+	 *                      ['tabindex'] => '' //this allows you to set the tabindex for the field.
208
+	 *                      ['wpeditor_args'] => array() //if the type of field is wpeditor then this can optionally
209
+	 *                      contain an array of arguments for the editor setup.
210
+	 *
211
+	 * @return array         an array of inputs for form indexed by field name, and in the following structure:
212
+	 *     [field_name] => array( 'label' => '{label_html}', 'field' => '{input_html}'
213
+	 */
214
+	public static function get_form_fields_array($fields)
215
+	{
216
+
217
+		$form_fields = [];
218
+		$fields      = (array) $fields;
219
+
220
+		foreach ($fields as $field_name => $field_atts) {
221
+			// defaults:
222
+			$defaults = [
223
+				'class'         => '',
224
+				'classes'       => '',
225
+				'default'       => '',
226
+				'dimensions'    => ['10', '5'],
227
+				'extra_desc'    => '',
228
+				'id'            => $field_name,
229
+				'label'         => '',
230
+				'labels'        => '',
231
+				'required'      => false,
232
+				'tabindex'      => 0,
233
+				'type'          => 'text',
234
+				'unique_id'     => '',
235
+				'value'         => '',
236
+				'wpeditor_args' => [],
237
+			];
238
+			// merge defaults with passed arguments
239
+			$_fields = wp_parse_args($field_atts, $defaults);
240
+
241
+			$class          = $_fields['class'];
242
+			$classes        = $_fields['classes'];
243
+			$default        = $_fields['default'];
244
+			$dims           = $_fields['dimensions'];
245
+			$extra_desc     = $_fields['extra_desc'];
246
+			$id             = $_fields['id'];
247
+			$label          = $_fields['label'];
248
+			$labels         = $_fields['labels'];
249
+			$required       = $_fields['required'];
250
+			$tab_index      = $_fields['tabindex'];
251
+			$type           = $_fields['type'];
252
+			$unique_id      = $_fields['unique_id'];
253
+			$value          = $_fields['value'];
254
+			$wp_editor_args = $_fields['wpeditor_args'];
255
+
256
+			// generate label
257
+			$label = ! empty($label) ? self::adminLabel($id, $label, $required) : '';
258
+			// generate field name
259
+			$name = ! empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
260
+
261
+			// we determine what we're building based on the type
262
+			switch ($type) {
263
+				case 'checkbox':
264
+				case 'radio':
265
+					if (is_array($value)) {
266
+						$c_input = '';
267
+						foreach ($value as $key => $val) {
268
+							$c_input .= self::adminMulti(
269
+								$default,
270
+								isset($classes[ $key ]) ? $classes[ $key ] : '',
271
+								$field_name . '_' . $value,
272
+								$name,
273
+								$required,
274
+								$tab_index,
275
+								$type,
276
+								$val,
277
+								isset($labels[ $key ]) ? $labels[ $key ] : ''
278
+							);
279
+						}
280
+						$field = $c_input;
281
+					} else {
282
+						$field = self::adminMulti(
283
+							$default,
284
+							$class,
285
+							$id,
286
+							$name,
287
+							$required,
288
+							$tab_index,
289
+							$type,
290
+							$value,
291
+							$_fields['label']
292
+						);
293
+					}
294
+					break;
295
+
296
+				case 'hidden':
297
+					$field = self::adminHidden($class, $id, $name, $value);
298
+					break;
299
+
300
+				case 'select':
301
+					$options = [];
302
+					foreach ($value as $key => $val) {
303
+						$options[ $val ] = isset($labels[ $key ]) ? $labels[ $key ] : '';
304
+					}
305
+					$field = self::adminSelect($default, $class, $id, $name, $required, $tab_index, $options);
306
+					break;
307
+
308
+				case 'textarea':
309
+					$field =
310
+						self::adminTextarea($class, $dims[0], $id, $name, $required, $dims[1], $tab_index, $value);
311
+					break;
312
+
313
+				case 'wp_editor':
314
+					$field = self::adminWpEditor(
315
+						$class,
316
+						$_fields['id'],
317
+						$name,
318
+						$dims[1],
319
+						$tab_index,
320
+						$value,
321
+						$wp_editor_args
322
+					);
323
+					break;
324
+
325
+				default:
326
+					$field = self::adminText($class, $id, $name, $required, $tab_index, $value);
327
+			}
328
+
329
+			$form_fields[ $field_name ] = ['label' => $label, 'field' => $field . $extra_desc];
330
+		}
331
+
332
+		return $form_fields;
333
+	}
334
+
335
+
336
+	/**
337
+	 * @param string $class
338
+	 * @param string $id
339
+	 * @param string $name
340
+	 * @param string $value
341
+	 * @return string
342
+	 * @since   4.10.14.p
343
+	 */
344
+	private static function adminHidden($class, $id, $name, $value)
345
+	{
346
+		$id    = esc_attr($id);
347
+		$name  = esc_attr($name);
348
+		$class = esc_attr($class);
349
+		return "
350 350
         <input name='{$name}' type='hidden' id='{$id}' class='{$class}' value='{$value}' />";
351
-    }
352
-
353
-
354
-    /**
355
-     * @param string $id
356
-     * @param string $label
357
-     * @param string $required
358
-     * @return string
359
-     * @since   4.10.14.p
360
-     */
361
-    private static function adminLabel($id, $label, $required)
362
-    {
363
-        $id       = esc_attr($id);
364
-        $label    = esc_html($label);
365
-        $required = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? " <span>*</span>" : '';
366
-        return "<label for='{$id}'>{$label}{$required}</label>";
367
-    }
368
-
369
-
370
-    /**
371
-     * @param string $default
372
-     * @param string $class
373
-     * @param string $id
374
-     * @param string $name
375
-     * @param string $required
376
-     * @param int    $tab_index
377
-     * @param string $type
378
-     * @param string $value
379
-     * @param string $label
380
-     * @return string
381
-     * @since   4.10.14.p
382
-     */
383
-    private static function adminMulti($default, $class, $id, $name, $required, $tab_index, $type, $value, $label = '')
384
-    {
385
-        $id        = esc_attr($id);
386
-        $name      = esc_attr($name);
387
-        $class     = esc_attr($class);
388
-        $tab_index = absint($tab_index);
389
-        $checked   = ! empty($default) && $default == $value ? 'checked ' : '';
390
-        $required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
391
-        $input     = "
351
+	}
352
+
353
+
354
+	/**
355
+	 * @param string $id
356
+	 * @param string $label
357
+	 * @param string $required
358
+	 * @return string
359
+	 * @since   4.10.14.p
360
+	 */
361
+	private static function adminLabel($id, $label, $required)
362
+	{
363
+		$id       = esc_attr($id);
364
+		$label    = esc_html($label);
365
+		$required = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? " <span>*</span>" : '';
366
+		return "<label for='{$id}'>{$label}{$required}</label>";
367
+	}
368
+
369
+
370
+	/**
371
+	 * @param string $default
372
+	 * @param string $class
373
+	 * @param string $id
374
+	 * @param string $name
375
+	 * @param string $required
376
+	 * @param int    $tab_index
377
+	 * @param string $type
378
+	 * @param string $value
379
+	 * @param string $label
380
+	 * @return string
381
+	 * @since   4.10.14.p
382
+	 */
383
+	private static function adminMulti($default, $class, $id, $name, $required, $tab_index, $type, $value, $label = '')
384
+	{
385
+		$id        = esc_attr($id);
386
+		$name      = esc_attr($name);
387
+		$class     = esc_attr($class);
388
+		$tab_index = absint($tab_index);
389
+		$checked   = ! empty($default) && $default == $value ? 'checked ' : '';
390
+		$required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
391
+		$input     = "
392 392
         <input name='{$name}[]' type='{$type}' id='{$id}' class='{$class}' value='{$value}' {$checked} {$required} tabindex='{$tab_index}'/>";
393
-        if ($label === '') {
394
-            return $input;
395
-        }
396
-        $label = esc_html($label);
397
-        $label_class = self::appendInputSizeClass('', $label);
398
-        $label_class = $label_class ? ' class="' . $label_class . '"' : '';
399
-        return "
393
+		if ($label === '') {
394
+			return $input;
395
+		}
396
+		$label = esc_html($label);
397
+		$label_class = self::appendInputSizeClass('', $label);
398
+		$label_class = $label_class ? ' class="' . $label_class . '"' : '';
399
+		return "
400 400
         <label for='$id'{$label_class}>
401 401
             {$input}
402 402
             {$label}
403 403
         </label>";
404
-    }
405
-
406
-
407
-    /**
408
-     * @param string $default
409
-     * @param string $class
410
-     * @param string $id
411
-     * @param string $name
412
-     * @param string $required
413
-     * @param int    $tab_index
414
-     * @param array  $options
415
-     * @return string
416
-     * @since   4.10.14.p
417
-     */
418
-    private static function adminSelect($default, $class, $id, $name, $required, $tab_index, $options = [])
419
-    {
420
-        $options_array = [];
421
-        foreach ($options as $value => $label) {
422
-            $selected        = ! empty($default) && $default == $value ? 'selected' : '';
423
-            $value           = esc_attr($value);
424
-            $label           = wp_strip_all_tags($label);
425
-            $options_array[] = "<option value='{$value}' {$selected}>{$label}</option>";
426
-        }
427
-        $options_html = implode($options_array, "\n");
428
-        $id           = esc_attr($id);
429
-        $name         = esc_attr($name);
430
-        $class        = esc_attr($class);
431
-        $tab_index    = absint($tab_index);
432
-        $required     = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
433
-
434
-        $class = self::appendInputSizeClass($class, $options);
435
-
436
-        return "
404
+	}
405
+
406
+
407
+	/**
408
+	 * @param string $default
409
+	 * @param string $class
410
+	 * @param string $id
411
+	 * @param string $name
412
+	 * @param string $required
413
+	 * @param int    $tab_index
414
+	 * @param array  $options
415
+	 * @return string
416
+	 * @since   4.10.14.p
417
+	 */
418
+	private static function adminSelect($default, $class, $id, $name, $required, $tab_index, $options = [])
419
+	{
420
+		$options_array = [];
421
+		foreach ($options as $value => $label) {
422
+			$selected        = ! empty($default) && $default == $value ? 'selected' : '';
423
+			$value           = esc_attr($value);
424
+			$label           = wp_strip_all_tags($label);
425
+			$options_array[] = "<option value='{$value}' {$selected}>{$label}</option>";
426
+		}
427
+		$options_html = implode($options_array, "\n");
428
+		$id           = esc_attr($id);
429
+		$name         = esc_attr($name);
430
+		$class        = esc_attr($class);
431
+		$tab_index    = absint($tab_index);
432
+		$required     = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
433
+
434
+		$class = self::appendInputSizeClass($class, $options);
435
+
436
+		return "
437 437
         <select name='{$name}' id='{$id}' class='{$class}' {$required} tabindex='{$tab_index}'>
438 438
             {$options_html}
439 439
         </select>";
440
-    }
441
-
442
-
443
-    /**
444
-     * @param string $class
445
-     * @param string $id
446
-     * @param string $name
447
-     * @param string $required
448
-     * @param int    $tab_index
449
-     * @param string $value
450
-     * @return string
451
-     * @since   4.10.14.p
452
-     */
453
-    private static function adminText($class, $id, $name, $required, $tab_index, $value)
454
-    {
455
-        $id        = esc_attr($id);
456
-        $name      = esc_attr($name);
457
-        $class     = esc_attr($class);
458
-        $tab_index = absint($tab_index);
459
-        $required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
460
-        $class     = self::appendInputSizeClass($class, $value);
461
-        return "
440
+	}
441
+
442
+
443
+	/**
444
+	 * @param string $class
445
+	 * @param string $id
446
+	 * @param string $name
447
+	 * @param string $required
448
+	 * @param int    $tab_index
449
+	 * @param string $value
450
+	 * @return string
451
+	 * @since   4.10.14.p
452
+	 */
453
+	private static function adminText($class, $id, $name, $required, $tab_index, $value)
454
+	{
455
+		$id        = esc_attr($id);
456
+		$name      = esc_attr($name);
457
+		$class     = esc_attr($class);
458
+		$tab_index = absint($tab_index);
459
+		$required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
460
+		$class     = self::appendInputSizeClass($class, $value);
461
+		return "
462 462
         <input name='{$name}' type='text' id='{$id}' class='{$class}' value='{$value}' {$required} tabindex='{$tab_index}'/>";
463
-    }
464
-
465
-
466
-    /**
467
-     * @param string $class
468
-     * @param int    $cols
469
-     * @param string $id
470
-     * @param string $name
471
-     * @param string $required
472
-     * @param int    $rows
473
-     * @param int    $tab_index
474
-     * @param string $value
475
-     * @return string
476
-     * @since   4.10.14.p
477
-     */
478
-    private static function adminTextarea($class, $cols, $id, $name, $required, $rows, $tab_index, $value)
479
-    {
480
-        $id        = esc_attr($id);
481
-        $name      = esc_attr($name);
482
-        $class     = esc_attr($class);
483
-        $cols      = absint($cols);
484
-        $rows      = absint($rows);
485
-        $value     = esc_textarea($value);
486
-        $tab_index = absint($tab_index);
487
-        $required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
488
-        return "
463
+	}
464
+
465
+
466
+	/**
467
+	 * @param string $class
468
+	 * @param int    $cols
469
+	 * @param string $id
470
+	 * @param string $name
471
+	 * @param string $required
472
+	 * @param int    $rows
473
+	 * @param int    $tab_index
474
+	 * @param string $value
475
+	 * @return string
476
+	 * @since   4.10.14.p
477
+	 */
478
+	private static function adminTextarea($class, $cols, $id, $name, $required, $rows, $tab_index, $value)
479
+	{
480
+		$id        = esc_attr($id);
481
+		$name      = esc_attr($name);
482
+		$class     = esc_attr($class);
483
+		$cols      = absint($cols);
484
+		$rows      = absint($rows);
485
+		$value     = esc_textarea($value);
486
+		$tab_index = absint($tab_index);
487
+		$required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
488
+		return "
489 489
         <textarea name='{$name}' id='{$id}' class='{$class}' rows='{$rows}' cols='{$cols}' {$required} tabindex='{$tab_index}'>{$value}</textarea>";
490
-    }
491
-
492
-
493
-    /**
494
-     * @param string $class
495
-     * @param string $id
496
-     * @param string $name
497
-     * @param int    $rows
498
-     * @param int    $tab_index
499
-     * @param string $value
500
-     * @param array  $wp_editor_args
501
-     * @return false|string
502
-     * @since   4.10.14.p
503
-     */
504
-    private static function adminWpEditor($class, $id, $name, $rows, $tab_index, $value, $wp_editor_args = [])
505
-    {
506
-        $editor_settings = $wp_editor_args + [
507
-                'textarea_name' => esc_attr($name),
508
-                'textarea_rows' => absint($rows),
509
-                'editor_class'  => esc_attr($class),
510
-                'tabindex'      => absint($tab_index),
511
-            ];
512
-        ob_start();
513
-        wp_editor($value, esc_attr($id), $editor_settings);
514
-        return ob_get_clean();
515
-    }
516
-
517
-
518
-    /**
519
-     * espresso admin page select_input
520
-     * Turns an array into a select fields
521
-     *
522
-     * @static
523
-     * @access public
524
-     * @param string  $name       field name
525
-     * @param array   $values     option values, numbered array starting at 0, where each value is an array with a key
526
-     *                            'text' (meaning text to display' and 'id' (meaning the internal value) eg:
527
-     *                            array(1=>array('text'=>'Monday','id'=>1),2=>array('text'=>'Tuesday','id'=>2)...). or
528
-     *                            as an array of key-value pairs, where the key is to be used for the select input's
529
-     *                            name, and the value will be the text shown to the user.  Optionally you can also
530
-     *                            include an additional key of "class" which will add a specific class to the option
531
-     *                            for that value.
532
-     * @param string  $default    default value
533
-     * @param string  $parameters extra parameters
534
-     * @param string  $class      css class
535
-     * @param boolean $autosize   whether to autosize the select or not
536
-     * @return string              html string for the select input
537
-     */
538
-    public static function select_input(
539
-        $name,
540
-        $values,
541
-        $default = '',
542
-        $parameters = '',
543
-        $class = '',
544
-        $autosize = true
545
-    ) {
546
-        // if $values was submitted in the wrong format, convert it over
547
-        if (! empty($values) && (! array_key_exists(0, $values) || ! is_array($values[0]))) {
548
-            $converted_values = [];
549
-            foreach ($values as $id => $text) {
550
-                $converted_values[] = ['id' => $id, 'text' => $text];
551
-            }
552
-            $values = $converted_values;
553
-        }
554
-
555
-        $field =
556
-            '<select id="' . EEH_Formatter::ee_tep_output_string($name)
557
-            . '" name="' . EEH_Formatter::ee_tep_output_string($name)
558
-            . '"';
559
-
560
-        if (EEH_Formatter::ee_tep_not_null($parameters)) {
561
-            $field .= ' ' . $parameters;
562
-        }
563
-        $class = $autosize ? self::appendInputSizeClass($class, $values) : '';
564
-
565
-        $field .= ' class="' . $class . '">';
566
-
567
-        if (empty($default) && isset($GLOBALS[ $name ])) {
568
-            $default = stripslashes($GLOBALS[ $name ]);
569
-        }
570
-
571
-        $field .= self::selectInputOption($values, $default);
572
-        $field .= '</select>';
573
-
574
-        return $field;
575
-    }
576
-
577
-
578
-    private static function selectInputOption(array $values, $default): string
579
-    {
580
-        if (isset($values['id'], $values['text'])) {
581
-            $id = is_scalar($values['id']) ? $values['id'] : '';
582
-            $text = is_scalar($values['text']) ? $values['text'] : '';
583
-            $selected = $default == $values['id'] ? ' selected = "selected"' : '';
584
-            $html_class = isset($values['class']) ? ' class="' . $values['class'] . '"' : '';
585
-            return "<option value='{$id}'{$selected}{$html_class}>{$text}</option>";
586
-        }
587
-        $options = '';
588
-        foreach ($values as $value) {
589
-            $options .= self::selectInputOption($value, $default);
590
-        }
591
-        return $options;
592
-    }
593
-
594
-
595
-    /**
596
-     * @param mixed $value
597
-     * @return int
598
-     * @since   $VID:$
599
-     */
600
-    private static function getInputValueLength($value): int
601
-    {
602
-        if ($value instanceof EE_Question_Option) {
603
-            return self::getInputValueLength($value->desc());
604
-        }
605
-        if (is_array($value)) {
606
-            $chars = 0;
607
-            foreach ($value as $val) {
608
-                $length = self::getInputValueLength($val);
609
-                $chars = $length > $chars ? $length : $chars;
610
-            }
611
-            return $chars;
612
-        }
613
-        // not a primitive? return something big
614
-        if (! is_scalar($value)) {
615
-            return 500;
616
-        }
617
-        return strlen((string) $value);
618
-    }
619
-
620
-
621
-    /**
622
-     * @param string $class
623
-     * @param mixed $value
624
-     * @return string
625
-     * @since   $VID:$
626
-     */
627
-    private static function appendInputSizeClass(string $class, $value): string
628
-    {
629
-        if (strpos($class, 'ee-input-width--') !== false) {
630
-            return $class;
631
-        }
632
-        $chars = self::getInputValueLength($value);
633
-        if ($chars && $chars < 5) {
634
-            return "{$class} ee-input-width--tiny";
635
-        }
636
-        if ($chars && $chars < 15) {
637
-            return "{$class} ee-input-width--small";
638
-        }
639
-        if ($chars && $chars > 100) {
640
-            return "{$class} ee-input-width--big";
641
-        }
642
-        return "{$class} ee-input-width--reg";
643
-    }
644
-
645
-
646
-    /**
647
-     * generate_question_groups_html
648
-     *
649
-     * @param array  $question_groups
650
-     * @param string $group_wrapper
651
-     * @return string HTML
652
-     * @throws EE_Error
653
-     * @throws ReflectionException
654
-     */
655
-    public static function generate_question_groups_html($question_groups = [], $group_wrapper = 'fieldset')
656
-    {
657
-
658
-        $html                            = '';
659
-        $before_question_group_questions =
660
-            apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
661
-        $after_question_group_questions  =
662
-            apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
663
-
664
-        if (! empty($question_groups)) {
665
-            // loop thru question groups
666
-            foreach ($question_groups as $QSG) {
667
-                // check that questions exist
668
-                if (! empty($QSG['QSG_questions'])) {
669
-                    // use fieldsets
670
-                    $html .= "\n\t"
671
-                             . '<'
672
-                             . $group_wrapper
673
-                             . ' class="espresso-question-group-wrap" id="'
674
-                             . $QSG['QSG_identifier']
675
-                             . '">';
676
-                    // group_name
677
-                    $html .= $QSG['QSG_show_group_name']
678
-                        ? "\n\t\t"
679
-                          . '<h5 class="espresso-question-group-title-h5 section-title">'
680
-                          . self::prep_answer($QSG['QSG_name'])
681
-                          . '</h5>'
682
-                        : '';
683
-                    // group_desc
684
-                    $html .= $QSG['QSG_show_group_desc'] && ! empty($QSG['QSG_desc'])
685
-                        ? '<div class="espresso-question-group-desc-pg">'
686
-                          . self::prep_answer($QSG['QSG_desc'])
687
-                          . '</div>'
688
-                        : '';
689
-
690
-                    $html .= $before_question_group_questions;
691
-                    // loop thru questions
692
-                    foreach ($QSG['QSG_questions'] as $question) {
693
-                        $QFI  = new EE_Question_Form_Input(
694
-                            $question['qst_obj'],
695
-                            $question['ans_obj'],
696
-                            $question
697
-                        );
698
-                        $html .= self::generate_form_input($QFI);
699
-                    }
700
-                    $html .= $after_question_group_questions;
701
-                    $html .= "\n\t" . '</' . $group_wrapper . '>';
702
-                }
703
-            }
704
-        }
705
-
706
-        return $html;
707
-    }
708
-
709
-
710
-    /**
711
-     * generate_question_groups_html
712
-     *
713
-     * @param array  $question_groups
714
-     * @param array  $q_meta
715
-     * @param bool   $from_admin
716
-     * @param string $group_wrapper
717
-     * @return string HTML
718
-     * @throws EE_Error
719
-     * @throws ReflectionException
720
-     */
721
-    public static function generate_question_groups_html2(
722
-        $question_groups = [],
723
-        $q_meta = [],
724
-        $from_admin = false,
725
-        $group_wrapper = 'fieldset'
726
-    ) {
727
-
728
-        $html                            = '';
729
-        $before_question_group_questions =
730
-            apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
731
-        $after_question_group_questions  =
732
-            apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
733
-
734
-        $default_q_meta = [
735
-            'att_nmbr'    => 1,
736
-            'ticket_id'   => '',
737
-            'input_name'  => '',
738
-            'input_id'    => '',
739
-            'input_class' => '',
740
-        ];
741
-        $q_meta         = array_merge($default_q_meta, $q_meta);
742
-
743
-        if (! empty($question_groups)) {
744
-            // loop thru question groups
745
-            foreach ($question_groups as $QSG) {
746
-                if ($QSG instanceof EE_Question_Group) {
747
-                    // check that questions exist
748
-
749
-                    $where = ['QST_deleted' => 0];
750
-                    if (! $from_admin) {
751
-                        $where['QST_admin_only'] = 0;
752
-                    }
753
-                    $questions =
754
-                        $QSG->questions([$where, 'order_by' => ['Question_Group_Question.QGQ_order' => 'ASC']]);
755
-                    if (! empty($questions)) {
756
-                        // use fieldsets
757
-                        $html .= "\n\t"
758
-                                 . '<' . $group_wrapper . ' class="espresso-question-group-wrap" '
759
-                                 . 'id="' . $QSG->get('QSG_identifier') . '">';
760
-                        // group_name
761
-                        if ($QSG->show_group_name()) {
762
-                            $html .= "\n\t\t"
763
-                                     . '<h5 class="espresso-question-group-title-h5 section-title">'
764
-                                     . $QSG->get_pretty('QSG_name')
765
-                                     . '</h5>';
766
-                        }
767
-                        // group_desc
768
-                        if ($QSG->show_group_desc()) {
769
-                            $html .= '<div class="espresso-question-group-desc-pg">'
770
-                                     . $QSG->get_pretty('QSG_desc')
771
-                                     . '</div>';
772
-                        }
773
-
774
-                        $html .= $before_question_group_questions;
775
-                        // loop thru questions
776
-                        foreach ($questions as $QST) {
777
-                            $qstn_id = $QST->is_system_question() ? $QST->system_ID() : $QST->ID();
778
-
779
-                            $answer = null;
780
-
781
-                            /** @var RequestInterface $request */
782
-                            $request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
783
-                            $request_qstn = $request->getRequestParam('qstn', [], 'string', true);
784
-                            if (! empty($request_qstn) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
785
-                                // check for answer in $request_qstn in case we are reprocessing a form after an error
786
-                                if (isset($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])) {
787
-                                    $answer = is_array($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])
788
-                                        ? $request_qstn[ $q_meta['input_id'] ][ $qstn_id ]
789
-                                        : sanitize_text_field($request_qstn[ $q_meta['input_id'] ][ $qstn_id ]);
790
-                                }
791
-                            } elseif (isset($q_meta['attendee']) && $q_meta['attendee']) {
792
-                                // attendee data from the session
793
-                                $answer =
794
-                                    isset($q_meta['attendee'][ $qstn_id ]) ? $q_meta['attendee'][ $qstn_id ] : null;
795
-                            }
796
-
797
-
798
-                            $QFI  = new EE_Question_Form_Input(
799
-                                $QST,
800
-                                EE_Answer::new_instance(
801
-                                    [
802
-                                        'ANS_ID'    => 0,
803
-                                        'QST_ID'    => 0,
804
-                                        'REG_ID'    => 0,
805
-                                        'ANS_value' => $answer,
806
-                                    ]
807
-                                ),
808
-                                $q_meta
809
-                            );
810
-                            $html .= self::generate_form_input($QFI);
811
-                        }
812
-                        $html .= $after_question_group_questions;
813
-                        $html .= "\n\t" . '</' . $group_wrapper . '>';
814
-                    }
815
-                }
816
-            }
817
-        }
818
-        return $html;
819
-    }
820
-
821
-
822
-    /**
823
-     * generate_form_input
824
-     *
825
-     * @param EE_Question_Form_Input $QFI
826
-     * @return string HTML
827
-     * @throws EE_Error
828
-     * @throws ReflectionException
829
-     */
830
-    public static function generate_form_input(EE_Question_Form_Input $QFI)
831
-    {
832
-        if (isset($QFI->QST_admin_only) && $QFI->QST_admin_only && ! is_admin()) {
833
-            return '';
834
-        }
835
-        /** @var RequestInterface $request */
836
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
837
-
838
-        $QFI = self::_load_system_dropdowns($QFI);
839
-        $QFI = self::_load_specialized_dropdowns($QFI);
840
-
841
-        // we also need to verify
842
-
843
-        $display_text = $QFI->get('QST_display_text');
844
-        $input_name   = $QFI->get('QST_input_name');
845
-        $answer       = $request->getRequestParam($input_name, $QFI->get('ANS_value'));
846
-        $input_id     = $QFI->get('QST_input_id');
847
-        $input_class  = $QFI->get('QST_input_class');
848
-        //      $disabled = $QFI->get('QST_disabled') ? ' disabled="disabled"' : '';
849
-        $disabled          = $QFI->get('QST_disabled');
850
-        $required_label    = apply_filters(' FHEE__EEH_Form_Fields__generate_form_input__required_label', '<em>*</em>');
851
-        $QST_required      = $QFI->get('QST_required');
852
-        $required          =
853
-            $QST_required
854
-                ? ['label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required]
855
-                : [];
856
-        $use_html_entities = $QFI->get_meta('htmlentities');
857
-        $required_text     =
858
-            $QFI->get('QST_required_text') != ''
859
-                ? $QFI->get('QST_required_text')
860
-                : esc_html__('This field is required', 'event_espresso');
861
-        $required_text     = $QST_required
862
-            ? "\n\t\t\t"
863
-              . '<div class="required-text hidden">'
864
-              . self::prep_answer($required_text, $use_html_entities)
865
-              . '</div>'
866
-            : '';
867
-        $label_class       = $QFI->get('label_class');
868
-        $label_class       = $label_class ? "{$label_class} espresso-form-input-lbl" : 'espresso-form-input-lbl';
869
-        $QST_options       = $QFI->options(true, $answer);
870
-        $options           = is_array($QST_options) ? self::prep_answer_options($QST_options) : [];
871
-        $system_ID         = $QFI->get('QST_system');
872
-        $label_b4          = $QFI->get_meta('label_b4');
873
-        $use_desc_4_label  = $QFI->get_meta('use_desc_4_label');
874
-        $add_mobile_label  = $QFI->get_meta('add_mobile_label');
875
-
876
-
877
-        switch ($QFI->get('QST_type')) {
878
-            case 'TEXTAREA':
879
-                return EEH_Form_Fields::textarea(
880
-                    $display_text,
881
-                    $answer,
882
-                    $input_name,
883
-                    $input_id,
884
-                    $input_class,
885
-                    [],
886
-                    $required,
887
-                    $required_text,
888
-                    $label_class,
889
-                    $disabled,
890
-                    $system_ID,
891
-                    $use_html_entities,
892
-                    $add_mobile_label
893
-                );
894
-
895
-            case 'DROPDOWN':
896
-                return EEH_Form_Fields::select(
897
-                    $display_text,
898
-                    $answer,
899
-                    $options,
900
-                    $input_name,
901
-                    $input_id,
902
-                    $input_class,
903
-                    $required,
904
-                    $required_text,
905
-                    $label_class,
906
-                    $disabled,
907
-                    $system_ID,
908
-                    $use_html_entities,
909
-                    true,
910
-                    $add_mobile_label
911
-                );
912
-
913
-
914
-            case 'RADIO_BTN':
915
-                return EEH_Form_Fields::radio(
916
-                    $display_text,
917
-                    $answer,
918
-                    $options,
919
-                    $input_name,
920
-                    $input_id,
921
-                    $input_class,
922
-                    $required,
923
-                    $required_text,
924
-                    $label_class,
925
-                    $disabled,
926
-                    $system_ID,
927
-                    $use_html_entities,
928
-                    $label_b4,
929
-                    $use_desc_4_label,
930
-                    $add_mobile_label
931
-                );
932
-
933
-            case 'CHECKBOX':
934
-                return EEH_Form_Fields::checkbox(
935
-                    $display_text,
936
-                    $answer,
937
-                    $options,
938
-                    $input_name,
939
-                    $input_id,
940
-                    $input_class,
941
-                    $required,
942
-                    $required_text,
943
-                    $label_class,
944
-                    $disabled,
945
-                    $label_b4,
946
-                    $system_ID,
947
-                    $use_html_entities,
948
-                    $add_mobile_label
949
-                );
950
-
951
-            case 'DATE':
952
-                return EEH_Form_Fields::datepicker(
953
-                    $display_text,
954
-                    $answer,
955
-                    $input_name,
956
-                    $input_id,
957
-                    $input_class,
958
-                    $required,
959
-                    $required_text,
960
-                    $label_class,
961
-                    $disabled,
962
-                    $system_ID,
963
-                    $use_html_entities,
964
-                    $add_mobile_label
965
-                );
966
-
967
-            case 'TEXT':
968
-            default:
969
-                return EEH_Form_Fields::text(
970
-                    $display_text,
971
-                    $answer,
972
-                    $input_name,
973
-                    $input_id,
974
-                    $input_class,
975
-                    $required,
976
-                    $required_text,
977
-                    $label_class,
978
-                    $disabled,
979
-                    $system_ID,
980
-                    $use_html_entities,
981
-                    $add_mobile_label
982
-                );
983
-        }
984
-    }
985
-
986
-
987
-    public static function label(
988
-        string $question,
989
-        string $required_text = '',
990
-        string $required_label = '',
991
-        string $name = '',
992
-        string $label_class = '',
993
-        bool $filter = true
994
-    ): string {
995
-        $for   = ! empty($name) ? " for='{$name}'" : '';
996
-        $class = ! empty($label_class) ? " class='{$label_class}'" : '';
997
-        $label = self::prep_question($question) . $required_label;
998
-        $label_html = "
490
+	}
491
+
492
+
493
+	/**
494
+	 * @param string $class
495
+	 * @param string $id
496
+	 * @param string $name
497
+	 * @param int    $rows
498
+	 * @param int    $tab_index
499
+	 * @param string $value
500
+	 * @param array  $wp_editor_args
501
+	 * @return false|string
502
+	 * @since   4.10.14.p
503
+	 */
504
+	private static function adminWpEditor($class, $id, $name, $rows, $tab_index, $value, $wp_editor_args = [])
505
+	{
506
+		$editor_settings = $wp_editor_args + [
507
+				'textarea_name' => esc_attr($name),
508
+				'textarea_rows' => absint($rows),
509
+				'editor_class'  => esc_attr($class),
510
+				'tabindex'      => absint($tab_index),
511
+			];
512
+		ob_start();
513
+		wp_editor($value, esc_attr($id), $editor_settings);
514
+		return ob_get_clean();
515
+	}
516
+
517
+
518
+	/**
519
+	 * espresso admin page select_input
520
+	 * Turns an array into a select fields
521
+	 *
522
+	 * @static
523
+	 * @access public
524
+	 * @param string  $name       field name
525
+	 * @param array   $values     option values, numbered array starting at 0, where each value is an array with a key
526
+	 *                            'text' (meaning text to display' and 'id' (meaning the internal value) eg:
527
+	 *                            array(1=>array('text'=>'Monday','id'=>1),2=>array('text'=>'Tuesday','id'=>2)...). or
528
+	 *                            as an array of key-value pairs, where the key is to be used for the select input's
529
+	 *                            name, and the value will be the text shown to the user.  Optionally you can also
530
+	 *                            include an additional key of "class" which will add a specific class to the option
531
+	 *                            for that value.
532
+	 * @param string  $default    default value
533
+	 * @param string  $parameters extra parameters
534
+	 * @param string  $class      css class
535
+	 * @param boolean $autosize   whether to autosize the select or not
536
+	 * @return string              html string for the select input
537
+	 */
538
+	public static function select_input(
539
+		$name,
540
+		$values,
541
+		$default = '',
542
+		$parameters = '',
543
+		$class = '',
544
+		$autosize = true
545
+	) {
546
+		// if $values was submitted in the wrong format, convert it over
547
+		if (! empty($values) && (! array_key_exists(0, $values) || ! is_array($values[0]))) {
548
+			$converted_values = [];
549
+			foreach ($values as $id => $text) {
550
+				$converted_values[] = ['id' => $id, 'text' => $text];
551
+			}
552
+			$values = $converted_values;
553
+		}
554
+
555
+		$field =
556
+			'<select id="' . EEH_Formatter::ee_tep_output_string($name)
557
+			. '" name="' . EEH_Formatter::ee_tep_output_string($name)
558
+			. '"';
559
+
560
+		if (EEH_Formatter::ee_tep_not_null($parameters)) {
561
+			$field .= ' ' . $parameters;
562
+		}
563
+		$class = $autosize ? self::appendInputSizeClass($class, $values) : '';
564
+
565
+		$field .= ' class="' . $class . '">';
566
+
567
+		if (empty($default) && isset($GLOBALS[ $name ])) {
568
+			$default = stripslashes($GLOBALS[ $name ]);
569
+		}
570
+
571
+		$field .= self::selectInputOption($values, $default);
572
+		$field .= '</select>';
573
+
574
+		return $field;
575
+	}
576
+
577
+
578
+	private static function selectInputOption(array $values, $default): string
579
+	{
580
+		if (isset($values['id'], $values['text'])) {
581
+			$id = is_scalar($values['id']) ? $values['id'] : '';
582
+			$text = is_scalar($values['text']) ? $values['text'] : '';
583
+			$selected = $default == $values['id'] ? ' selected = "selected"' : '';
584
+			$html_class = isset($values['class']) ? ' class="' . $values['class'] . '"' : '';
585
+			return "<option value='{$id}'{$selected}{$html_class}>{$text}</option>";
586
+		}
587
+		$options = '';
588
+		foreach ($values as $value) {
589
+			$options .= self::selectInputOption($value, $default);
590
+		}
591
+		return $options;
592
+	}
593
+
594
+
595
+	/**
596
+	 * @param mixed $value
597
+	 * @return int
598
+	 * @since   $VID:$
599
+	 */
600
+	private static function getInputValueLength($value): int
601
+	{
602
+		if ($value instanceof EE_Question_Option) {
603
+			return self::getInputValueLength($value->desc());
604
+		}
605
+		if (is_array($value)) {
606
+			$chars = 0;
607
+			foreach ($value as $val) {
608
+				$length = self::getInputValueLength($val);
609
+				$chars = $length > $chars ? $length : $chars;
610
+			}
611
+			return $chars;
612
+		}
613
+		// not a primitive? return something big
614
+		if (! is_scalar($value)) {
615
+			return 500;
616
+		}
617
+		return strlen((string) $value);
618
+	}
619
+
620
+
621
+	/**
622
+	 * @param string $class
623
+	 * @param mixed $value
624
+	 * @return string
625
+	 * @since   $VID:$
626
+	 */
627
+	private static function appendInputSizeClass(string $class, $value): string
628
+	{
629
+		if (strpos($class, 'ee-input-width--') !== false) {
630
+			return $class;
631
+		}
632
+		$chars = self::getInputValueLength($value);
633
+		if ($chars && $chars < 5) {
634
+			return "{$class} ee-input-width--tiny";
635
+		}
636
+		if ($chars && $chars < 15) {
637
+			return "{$class} ee-input-width--small";
638
+		}
639
+		if ($chars && $chars > 100) {
640
+			return "{$class} ee-input-width--big";
641
+		}
642
+		return "{$class} ee-input-width--reg";
643
+	}
644
+
645
+
646
+	/**
647
+	 * generate_question_groups_html
648
+	 *
649
+	 * @param array  $question_groups
650
+	 * @param string $group_wrapper
651
+	 * @return string HTML
652
+	 * @throws EE_Error
653
+	 * @throws ReflectionException
654
+	 */
655
+	public static function generate_question_groups_html($question_groups = [], $group_wrapper = 'fieldset')
656
+	{
657
+
658
+		$html                            = '';
659
+		$before_question_group_questions =
660
+			apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
661
+		$after_question_group_questions  =
662
+			apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
663
+
664
+		if (! empty($question_groups)) {
665
+			// loop thru question groups
666
+			foreach ($question_groups as $QSG) {
667
+				// check that questions exist
668
+				if (! empty($QSG['QSG_questions'])) {
669
+					// use fieldsets
670
+					$html .= "\n\t"
671
+							 . '<'
672
+							 . $group_wrapper
673
+							 . ' class="espresso-question-group-wrap" id="'
674
+							 . $QSG['QSG_identifier']
675
+							 . '">';
676
+					// group_name
677
+					$html .= $QSG['QSG_show_group_name']
678
+						? "\n\t\t"
679
+						  . '<h5 class="espresso-question-group-title-h5 section-title">'
680
+						  . self::prep_answer($QSG['QSG_name'])
681
+						  . '</h5>'
682
+						: '';
683
+					// group_desc
684
+					$html .= $QSG['QSG_show_group_desc'] && ! empty($QSG['QSG_desc'])
685
+						? '<div class="espresso-question-group-desc-pg">'
686
+						  . self::prep_answer($QSG['QSG_desc'])
687
+						  . '</div>'
688
+						: '';
689
+
690
+					$html .= $before_question_group_questions;
691
+					// loop thru questions
692
+					foreach ($QSG['QSG_questions'] as $question) {
693
+						$QFI  = new EE_Question_Form_Input(
694
+							$question['qst_obj'],
695
+							$question['ans_obj'],
696
+							$question
697
+						);
698
+						$html .= self::generate_form_input($QFI);
699
+					}
700
+					$html .= $after_question_group_questions;
701
+					$html .= "\n\t" . '</' . $group_wrapper . '>';
702
+				}
703
+			}
704
+		}
705
+
706
+		return $html;
707
+	}
708
+
709
+
710
+	/**
711
+	 * generate_question_groups_html
712
+	 *
713
+	 * @param array  $question_groups
714
+	 * @param array  $q_meta
715
+	 * @param bool   $from_admin
716
+	 * @param string $group_wrapper
717
+	 * @return string HTML
718
+	 * @throws EE_Error
719
+	 * @throws ReflectionException
720
+	 */
721
+	public static function generate_question_groups_html2(
722
+		$question_groups = [],
723
+		$q_meta = [],
724
+		$from_admin = false,
725
+		$group_wrapper = 'fieldset'
726
+	) {
727
+
728
+		$html                            = '';
729
+		$before_question_group_questions =
730
+			apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
731
+		$after_question_group_questions  =
732
+			apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
733
+
734
+		$default_q_meta = [
735
+			'att_nmbr'    => 1,
736
+			'ticket_id'   => '',
737
+			'input_name'  => '',
738
+			'input_id'    => '',
739
+			'input_class' => '',
740
+		];
741
+		$q_meta         = array_merge($default_q_meta, $q_meta);
742
+
743
+		if (! empty($question_groups)) {
744
+			// loop thru question groups
745
+			foreach ($question_groups as $QSG) {
746
+				if ($QSG instanceof EE_Question_Group) {
747
+					// check that questions exist
748
+
749
+					$where = ['QST_deleted' => 0];
750
+					if (! $from_admin) {
751
+						$where['QST_admin_only'] = 0;
752
+					}
753
+					$questions =
754
+						$QSG->questions([$where, 'order_by' => ['Question_Group_Question.QGQ_order' => 'ASC']]);
755
+					if (! empty($questions)) {
756
+						// use fieldsets
757
+						$html .= "\n\t"
758
+								 . '<' . $group_wrapper . ' class="espresso-question-group-wrap" '
759
+								 . 'id="' . $QSG->get('QSG_identifier') . '">';
760
+						// group_name
761
+						if ($QSG->show_group_name()) {
762
+							$html .= "\n\t\t"
763
+									 . '<h5 class="espresso-question-group-title-h5 section-title">'
764
+									 . $QSG->get_pretty('QSG_name')
765
+									 . '</h5>';
766
+						}
767
+						// group_desc
768
+						if ($QSG->show_group_desc()) {
769
+							$html .= '<div class="espresso-question-group-desc-pg">'
770
+									 . $QSG->get_pretty('QSG_desc')
771
+									 . '</div>';
772
+						}
773
+
774
+						$html .= $before_question_group_questions;
775
+						// loop thru questions
776
+						foreach ($questions as $QST) {
777
+							$qstn_id = $QST->is_system_question() ? $QST->system_ID() : $QST->ID();
778
+
779
+							$answer = null;
780
+
781
+							/** @var RequestInterface $request */
782
+							$request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
783
+							$request_qstn = $request->getRequestParam('qstn', [], 'string', true);
784
+							if (! empty($request_qstn) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
785
+								// check for answer in $request_qstn in case we are reprocessing a form after an error
786
+								if (isset($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])) {
787
+									$answer = is_array($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])
788
+										? $request_qstn[ $q_meta['input_id'] ][ $qstn_id ]
789
+										: sanitize_text_field($request_qstn[ $q_meta['input_id'] ][ $qstn_id ]);
790
+								}
791
+							} elseif (isset($q_meta['attendee']) && $q_meta['attendee']) {
792
+								// attendee data from the session
793
+								$answer =
794
+									isset($q_meta['attendee'][ $qstn_id ]) ? $q_meta['attendee'][ $qstn_id ] : null;
795
+							}
796
+
797
+
798
+							$QFI  = new EE_Question_Form_Input(
799
+								$QST,
800
+								EE_Answer::new_instance(
801
+									[
802
+										'ANS_ID'    => 0,
803
+										'QST_ID'    => 0,
804
+										'REG_ID'    => 0,
805
+										'ANS_value' => $answer,
806
+									]
807
+								),
808
+								$q_meta
809
+							);
810
+							$html .= self::generate_form_input($QFI);
811
+						}
812
+						$html .= $after_question_group_questions;
813
+						$html .= "\n\t" . '</' . $group_wrapper . '>';
814
+					}
815
+				}
816
+			}
817
+		}
818
+		return $html;
819
+	}
820
+
821
+
822
+	/**
823
+	 * generate_form_input
824
+	 *
825
+	 * @param EE_Question_Form_Input $QFI
826
+	 * @return string HTML
827
+	 * @throws EE_Error
828
+	 * @throws ReflectionException
829
+	 */
830
+	public static function generate_form_input(EE_Question_Form_Input $QFI)
831
+	{
832
+		if (isset($QFI->QST_admin_only) && $QFI->QST_admin_only && ! is_admin()) {
833
+			return '';
834
+		}
835
+		/** @var RequestInterface $request */
836
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
837
+
838
+		$QFI = self::_load_system_dropdowns($QFI);
839
+		$QFI = self::_load_specialized_dropdowns($QFI);
840
+
841
+		// we also need to verify
842
+
843
+		$display_text = $QFI->get('QST_display_text');
844
+		$input_name   = $QFI->get('QST_input_name');
845
+		$answer       = $request->getRequestParam($input_name, $QFI->get('ANS_value'));
846
+		$input_id     = $QFI->get('QST_input_id');
847
+		$input_class  = $QFI->get('QST_input_class');
848
+		//      $disabled = $QFI->get('QST_disabled') ? ' disabled="disabled"' : '';
849
+		$disabled          = $QFI->get('QST_disabled');
850
+		$required_label    = apply_filters(' FHEE__EEH_Form_Fields__generate_form_input__required_label', '<em>*</em>');
851
+		$QST_required      = $QFI->get('QST_required');
852
+		$required          =
853
+			$QST_required
854
+				? ['label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required]
855
+				: [];
856
+		$use_html_entities = $QFI->get_meta('htmlentities');
857
+		$required_text     =
858
+			$QFI->get('QST_required_text') != ''
859
+				? $QFI->get('QST_required_text')
860
+				: esc_html__('This field is required', 'event_espresso');
861
+		$required_text     = $QST_required
862
+			? "\n\t\t\t"
863
+			  . '<div class="required-text hidden">'
864
+			  . self::prep_answer($required_text, $use_html_entities)
865
+			  . '</div>'
866
+			: '';
867
+		$label_class       = $QFI->get('label_class');
868
+		$label_class       = $label_class ? "{$label_class} espresso-form-input-lbl" : 'espresso-form-input-lbl';
869
+		$QST_options       = $QFI->options(true, $answer);
870
+		$options           = is_array($QST_options) ? self::prep_answer_options($QST_options) : [];
871
+		$system_ID         = $QFI->get('QST_system');
872
+		$label_b4          = $QFI->get_meta('label_b4');
873
+		$use_desc_4_label  = $QFI->get_meta('use_desc_4_label');
874
+		$add_mobile_label  = $QFI->get_meta('add_mobile_label');
875
+
876
+
877
+		switch ($QFI->get('QST_type')) {
878
+			case 'TEXTAREA':
879
+				return EEH_Form_Fields::textarea(
880
+					$display_text,
881
+					$answer,
882
+					$input_name,
883
+					$input_id,
884
+					$input_class,
885
+					[],
886
+					$required,
887
+					$required_text,
888
+					$label_class,
889
+					$disabled,
890
+					$system_ID,
891
+					$use_html_entities,
892
+					$add_mobile_label
893
+				);
894
+
895
+			case 'DROPDOWN':
896
+				return EEH_Form_Fields::select(
897
+					$display_text,
898
+					$answer,
899
+					$options,
900
+					$input_name,
901
+					$input_id,
902
+					$input_class,
903
+					$required,
904
+					$required_text,
905
+					$label_class,
906
+					$disabled,
907
+					$system_ID,
908
+					$use_html_entities,
909
+					true,
910
+					$add_mobile_label
911
+				);
912
+
913
+
914
+			case 'RADIO_BTN':
915
+				return EEH_Form_Fields::radio(
916
+					$display_text,
917
+					$answer,
918
+					$options,
919
+					$input_name,
920
+					$input_id,
921
+					$input_class,
922
+					$required,
923
+					$required_text,
924
+					$label_class,
925
+					$disabled,
926
+					$system_ID,
927
+					$use_html_entities,
928
+					$label_b4,
929
+					$use_desc_4_label,
930
+					$add_mobile_label
931
+				);
932
+
933
+			case 'CHECKBOX':
934
+				return EEH_Form_Fields::checkbox(
935
+					$display_text,
936
+					$answer,
937
+					$options,
938
+					$input_name,
939
+					$input_id,
940
+					$input_class,
941
+					$required,
942
+					$required_text,
943
+					$label_class,
944
+					$disabled,
945
+					$label_b4,
946
+					$system_ID,
947
+					$use_html_entities,
948
+					$add_mobile_label
949
+				);
950
+
951
+			case 'DATE':
952
+				return EEH_Form_Fields::datepicker(
953
+					$display_text,
954
+					$answer,
955
+					$input_name,
956
+					$input_id,
957
+					$input_class,
958
+					$required,
959
+					$required_text,
960
+					$label_class,
961
+					$disabled,
962
+					$system_ID,
963
+					$use_html_entities,
964
+					$add_mobile_label
965
+				);
966
+
967
+			case 'TEXT':
968
+			default:
969
+				return EEH_Form_Fields::text(
970
+					$display_text,
971
+					$answer,
972
+					$input_name,
973
+					$input_id,
974
+					$input_class,
975
+					$required,
976
+					$required_text,
977
+					$label_class,
978
+					$disabled,
979
+					$system_ID,
980
+					$use_html_entities,
981
+					$add_mobile_label
982
+				);
983
+		}
984
+	}
985
+
986
+
987
+	public static function label(
988
+		string $question,
989
+		string $required_text = '',
990
+		string $required_label = '',
991
+		string $name = '',
992
+		string $label_class = '',
993
+		bool $filter = true
994
+	): string {
995
+		$for   = ! empty($name) ? " for='{$name}'" : '';
996
+		$class = ! empty($label_class) ? " class='{$label_class}'" : '';
997
+		$label = self::prep_question($question) . $required_label;
998
+		$label_html = "
999 999
             {$required_text}
1000 1000
             <label{$for}{$class}>{$label}</label>";
1001
-        // filter label but ensure required text comes before it
1002
-        return $filter
1003
-            ? apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text)
1004
-            : $label_html;
1005
-    }
1006
-
1007
-
1008
-
1009
-    public static function mobileLabel(
1010
-        bool $add_mobile_label,
1011
-        string $question,
1012
-        string $required_text = '',
1013
-        string $required_label = '',
1014
-        string $label_class = '',
1015
-        string $name = ''
1016
-    ): string {
1017
-        return $add_mobile_label
1018
-            ? self::label($question, $required_text, $required_label, $name, $label_class, false)
1019
-            : '';
1020
-    }
1021
-
1022
-
1023
-    /**
1024
-     * generates HTML for a form text input
1025
-     *
1026
-     * @param string $question    label content
1027
-     * @param string $answer      form input value attribute
1028
-     * @param string $name        form input name attribute
1029
-     * @param string $id          form input css id attribute
1030
-     * @param string $class       form input css class attribute
1031
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1032
-     *                            required 'class', and required 'msg' attribute
1033
-     * @param string $label_class css class attribute for the label
1034
-     * @param string $disabled    disabled="disabled" or null
1035
-     * @return string HTML
1036
-     */
1037
-    public static function text(
1038
-        $question = false,
1039
-        $answer = null,
1040
-        $name = false,
1041
-        $id = '',
1042
-        $class = '',
1043
-        $required = false,
1044
-        $required_text = '',
1045
-        $label_class = '',
1046
-        $disabled = false,
1047
-        $system_ID = false,
1048
-        $use_html_entities = true,
1049
-        $add_mobile_label = false
1050
-    ) {
1051
-        // need these
1052
-        if (! $question || ! $name) {
1053
-            return null;
1054
-        }
1055
-        // prep the answer
1056
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1057
-        // prep the required array
1058
-        $required = self::prep_required($required);
1059
-        // set disabled tag
1060
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1061
-        // ya gots ta have style man!!!
1062
-        $txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
1063
-        $class     = empty($class) ? $txt_class : $class;
1064
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1065
-        $class = self::appendInputSizeClass($class, $answer);
1066
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1067
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1068
-
1069
-        $label_html = self::label($question, $required_text, $required['label'], $name, $label_class);
1070
-        $mobile_label = self::mobileLabel(
1071
-            $add_mobile_label,
1072
-            $question,
1073
-            $required_text,
1074
-            $required['label'],
1075
-            $label_class,
1076
-            $name
1077
-        );
1078
-
1079
-        $input_html = $mobile_label . '
1001
+		// filter label but ensure required text comes before it
1002
+		return $filter
1003
+			? apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text)
1004
+			: $label_html;
1005
+	}
1006
+
1007
+
1008
+
1009
+	public static function mobileLabel(
1010
+		bool $add_mobile_label,
1011
+		string $question,
1012
+		string $required_text = '',
1013
+		string $required_label = '',
1014
+		string $label_class = '',
1015
+		string $name = ''
1016
+	): string {
1017
+		return $add_mobile_label
1018
+			? self::label($question, $required_text, $required_label, $name, $label_class, false)
1019
+			: '';
1020
+	}
1021
+
1022
+
1023
+	/**
1024
+	 * generates HTML for a form text input
1025
+	 *
1026
+	 * @param string $question    label content
1027
+	 * @param string $answer      form input value attribute
1028
+	 * @param string $name        form input name attribute
1029
+	 * @param string $id          form input css id attribute
1030
+	 * @param string $class       form input css class attribute
1031
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1032
+	 *                            required 'class', and required 'msg' attribute
1033
+	 * @param string $label_class css class attribute for the label
1034
+	 * @param string $disabled    disabled="disabled" or null
1035
+	 * @return string HTML
1036
+	 */
1037
+	public static function text(
1038
+		$question = false,
1039
+		$answer = null,
1040
+		$name = false,
1041
+		$id = '',
1042
+		$class = '',
1043
+		$required = false,
1044
+		$required_text = '',
1045
+		$label_class = '',
1046
+		$disabled = false,
1047
+		$system_ID = false,
1048
+		$use_html_entities = true,
1049
+		$add_mobile_label = false
1050
+	) {
1051
+		// need these
1052
+		if (! $question || ! $name) {
1053
+			return null;
1054
+		}
1055
+		// prep the answer
1056
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1057
+		// prep the required array
1058
+		$required = self::prep_required($required);
1059
+		// set disabled tag
1060
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1061
+		// ya gots ta have style man!!!
1062
+		$txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
1063
+		$class     = empty($class) ? $txt_class : $class;
1064
+		$class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1065
+		$class = self::appendInputSizeClass($class, $answer);
1066
+		$class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1067
+		$extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1068
+
1069
+		$label_html = self::label($question, $required_text, $required['label'], $name, $label_class);
1070
+		$mobile_label = self::mobileLabel(
1071
+			$add_mobile_label,
1072
+			$question,
1073
+			$required_text,
1074
+			$required['label'],
1075
+			$label_class,
1076
+			$name
1077
+		);
1078
+
1079
+		$input_html = $mobile_label . '
1080 1080
             <input  type="text"
1081 1081
                     name="' . $name . '"
1082 1082
                     id="' . $id . '"
@@ -1086,1039 +1086,1039 @@  discard block
 block discarded – undo
1086 1086
                     ' . $disabled . ' ' . $extra . '
1087 1087
             />';
1088 1088
 
1089
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1090
-        return $label_html . $input_html;
1091
-    }
1092
-
1093
-
1094
-    /**
1095
-     * generates HTML for a form textarea
1096
-     *
1097
-     * @param string $question    label content
1098
-     * @param string $answer      form input value attribute
1099
-     * @param string $name        form input name attribute
1100
-     * @param string $id          form input css id attribute
1101
-     * @param string $class       form input css class attribute
1102
-     * @param array  $dimensions  array of form input rows and cols attributes : array( 'rows' => 3, 'cols' => 40 )
1103
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1104
-     *                            required 'class', and required 'msg' attribute
1105
-     * @param string $label_class css class attribute for the label
1106
-     * @param string $disabled    disabled="disabled" or null
1107
-     * @return string HTML
1108
-     */
1109
-    public static function textarea(
1110
-        $question = false,
1111
-        $answer = null,
1112
-        $name = false,
1113
-        $id = '',
1114
-        $class = '',
1115
-        $dimensions = false,
1116
-        $required = false,
1117
-        $required_text = '',
1118
-        $label_class = '',
1119
-        $disabled = false,
1120
-        $system_ID = false,
1121
-        $use_html_entities = true,
1122
-        $add_mobile_label = false
1123
-    ) {
1124
-        // need these
1125
-        if (! $question || ! $name) {
1126
-            return null;
1127
-        }
1128
-        // prep the answer
1129
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1130
-        // prep the required array
1131
-        $required = self::prep_required($required);
1132
-        // make sure $dimensions is an array
1133
-        $dimensions = is_array($dimensions) ? $dimensions : [];
1134
-        // and set some defaults
1135
-        $dimensions = array_merge(['rows' => 3, 'cols' => 40], $dimensions);
1136
-        // set disabled tag
1137
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1138
-        // ya gots ta have style man!!!
1139
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1140
-        $class     .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1141
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1142
-
1143
-        $label_html   = self::label($question, $required_text, $required['label'], $name, $label_class);
1144
-        $mobile_label = self::mobileLabel(
1145
-            $add_mobile_label,
1146
-            $question,
1147
-            $required_text,
1148
-            $required['label'],
1149
-            $label_class,
1150
-            $name
1151
-        );
1152
-
1153
-        $input_html = $mobile_label
1154
-            . '<textarea name="' . $name . '" id="' . $id . '" class="' . trim($class) . '" '
1155
-            . 'rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  '
1156
-            . 'aria-label="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>'
1157
-             . esc_textarea($answer)
1158
-              . '</textarea>';
1159
-
1160
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1161
-        return $label_html . $input_html;
1162
-    }
1163
-
1164
-
1165
-    /**
1166
-     * generates HTML for a form select input
1167
-     *
1168
-     * @param string $question    label content
1169
-     * @param string $answer      form input value attribute
1170
-     * @param array  $options     array of answer options where array key = option value and array value = option
1171
-     *                            display text
1172
-     * @param string $name        form input name attribute
1173
-     * @param string $id          form input css id attribute
1174
-     * @param string $class       form input css class attribute
1175
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1176
-     *                            required 'class', and required 'msg' attribute
1177
-     * @param string $label_class css class attribute for the label
1178
-     * @param string $disabled    disabled="disabled" or null
1179
-     * @return string HTML
1180
-     */
1181
-    public static function select(
1182
-        $question = false,
1183
-        $answer = null,
1184
-        $options = false,
1185
-        $name = false,
1186
-        $id = '',
1187
-        $class = '',
1188
-        $required = false,
1189
-        $required_text = '',
1190
-        $label_class = '',
1191
-        $disabled = false,
1192
-        $system_ID = false,
1193
-        $use_html_entities = true,
1194
-        $add_please_select_option = false,
1195
-        $add_mobile_label = false
1196
-    ) {
1197
-
1198
-        // need these
1199
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1200
-            return null;
1201
-        }
1202
-        // prep the answer
1203
-        $answer = is_array($answer)
1204
-            ? self::prep_answer(array_shift($answer), $use_html_entities)
1205
-            : self::prep_answer($answer, $use_html_entities);
1206
-        // prep the required array
1207
-        $required = self::prep_required($required);
1208
-        // set disabled tag
1209
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1210
-        // ya gots ta have style man!!!
1211
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1212
-        $class = self::appendInputSizeClass($class, $options);
1213
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1214
-
1215
-        $label_html   = self::label($question, $required_text, $required['label'], $name, $label_class);
1216
-        $mobile_label = self::mobileLabel(
1217
-            $add_mobile_label,
1218
-            $question,
1219
-            $required_text,
1220
-            $required['label'],
1221
-            $label_class,
1222
-            $name
1223
-        );
1224
-
1225
-        $input_html = $mobile_label
1226
-            . '<select name="' . $name . '" id="' . $id . '" class="' . trim($class) . ' ' . $required['class'] . '" '
1227
-            . 'aria-label="' . esc_attr($required['msg']) . '"' . $disabled . ' ' . $extra . '>';
1228
-        // recursively count array elements, to determine total number of options
1229
-        $only_option = count($options, 1) == 1;
1230
-        if (! $only_option) {
1231
-            // if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
1232
-            $selected   = $answer === null ? ' selected' : '';
1233
-            $input_html .= $add_please_select_option
1234
-                ? "\n\t\t\t\t"
1235
-                  . '<option value=""' . $selected . '>'
1236
-                  . esc_html__(' - please select - ', 'event_espresso')
1237
-                  . '</option>'
1238
-                : '';
1239
-        }
1240
-        foreach ($options as $key => $value) {
1241
-            // if value is an array, then create option groups, else create regular ol' options
1242
-            $input_html .= is_array($value)
1243
-                ? self::_generate_select_option_group(
1244
-                    $key,
1245
-                    $value,
1246
-                    $answer,
1247
-                    $use_html_entities
1248
-                )
1249
-                : self::_generate_select_option(
1250
-                    $value->value(),
1251
-                    $value->desc(),
1252
-                    $answer,
1253
-                    $only_option,
1254
-                    $use_html_entities
1255
-                );
1256
-        }
1257
-
1258
-        $input_html .= "\n\t\t\t" . '</select>';
1259
-
1260
-        $input_html =
1261
-            apply_filters(
1262
-                'FHEE__EEH_Form_Fields__select__before_end_wrapper',
1263
-                $input_html,
1264
-                $question,
1265
-                $answer,
1266
-                $name,
1267
-                $id,
1268
-                $class,
1269
-                $system_ID
1270
-            );
1271
-
1272
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1273
-        return $label_html . $input_html;
1274
-    }
1275
-
1276
-
1277
-    /**
1278
-     *  _generate_select_option_group
1279
-     *
1280
-     *  if  $value for a select box is an array, then the key will be used as the optgroup label
1281
-     *  and the value array will be looped thru and the elements sent to _generate_select_option
1282
-     *
1283
-     * @param mixed   $opt_group
1284
-     * @param mixed   $QSOs
1285
-     * @param mixed   $answer
1286
-     * @param boolean $use_html_entities
1287
-     * @return string
1288
-     */
1289
-    private static function _generate_select_option_group($opt_group, $QSOs, $answer, $use_html_entities = true)
1290
-    {
1291
-        $html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value($opt_group) . '">';
1292
-        foreach ($QSOs as $QSO) {
1293
-            $html .= self::_generate_select_option($QSO->value(), $QSO->desc(), $answer, false, $use_html_entities);
1294
-        }
1295
-        $html .= "\n\t\t\t\t" . '</optgroup>';
1296
-        return $html;
1297
-    }
1298
-
1299
-
1300
-    /**
1301
-     *  _generate_select_option
1302
-     *
1303
-     * @param mixed   $key
1304
-     * @param mixed   $value
1305
-     * @param mixed   $answer
1306
-     * @param int     $only_option
1307
-     * @param boolean $use_html_entities
1308
-     * @return string
1309
-     */
1310
-    private static function _generate_select_option(
1311
-        $key,
1312
-        $value,
1313
-        $answer,
1314
-        $only_option = false,
1315
-        $use_html_entities = true
1316
-    ) {
1317
-        $key      = self::prep_answer($key, $use_html_entities);
1318
-        $value    = self::prep_answer($value, $use_html_entities);
1319
-        $value    = ! empty($value) ? $value : $key;
1320
-        $selected = ($answer == $key || $only_option) ? 'selected' : '';
1321
-        return "\n\t\t\t\t"
1322
-               . '<option value="' . self::prep_option_value($key) . '" ' . $selected . '> '
1323
-               . $value
1324
-               . '&nbsp;&nbsp;&nbsp;</option>';
1325
-    }
1326
-
1327
-
1328
-    /**
1329
-     * generates HTML for form radio button inputs
1330
-     *
1331
-     * @param bool|string $question    label content
1332
-     * @param string      $answer      form input value attribute
1333
-     * @param array|bool  $options     array of answer options where array key = option value and array value = option
1334
-     *                                 display text
1335
-     * @param bool|string $name        form input name attribute
1336
-     * @param string      $id          form input css id attribute
1337
-     * @param string      $class       form input css class attribute
1338
-     * @param array|bool  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1339
-     *                                 required 'class', and required 'msg' attribute
1340
-     * @param string      $required_text
1341
-     * @param string      $label_class css class attribute for the label
1342
-     * @param bool|string $disabled    disabled="disabled" or null
1343
-     * @param bool        $system_ID
1344
-     * @param bool        $use_html_entities
1345
-     * @param bool        $label_b4
1346
-     * @param bool        $use_desc_4_label
1347
-     * @return string HTML
1348
-     */
1349
-    public static function radio(
1350
-        $question = false,
1351
-        $answer = null,
1352
-        $options = false,
1353
-        $name = false,
1354
-        $id = '',
1355
-        $class = '',
1356
-        $required = false,
1357
-        $required_text = '',
1358
-        $label_class = '',
1359
-        $disabled = false,
1360
-        $system_ID = false,
1361
-        $use_html_entities = true,
1362
-        $label_b4 = false,
1363
-        $use_desc_4_label = false,
1364
-        $add_mobile_label = false
1365
-    ) {
1366
-        // need these
1367
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1368
-            return null;
1369
-        }
1370
-        // prep the answer
1371
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1372
-        // prep the required array
1373
-        $required = self::prep_required($required);
1374
-        // set disabled tag
1375
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1376
-        // ya gots ta have style man!!!
1377
-        $radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
1378
-        $class       = ! empty($class) ? $class : 'espresso-radio-btn-inp';
1379
-        $extra       = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1380
-
1381
-        $label_html = self::label($question, $required_text, $required['label'], '', $label_class);
1382
-        $mobile_label = self::mobileLabel(
1383
-            $add_mobile_label,
1384
-            $question,
1385
-            $required_text,
1386
-            $required['label'],
1387
-            $label_class
1388
-        );
1389
-
1390
-        $input_html = $mobile_label
1391
-            . '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $class . '-ul">';
1392
-
1393
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1394
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1395
-
1396
-        foreach ($options as $OPT) {
1397
-            if ($OPT instanceof EE_Question_Option) {
1398
-                $value   = self::prep_option_value($OPT->value());
1399
-                $label   = $use_desc_4_label ? $OPT->desc() : $OPT->value();
1400
-                $size    = $use_desc_4_label
1401
-                    ? self::get_label_size_class($OPT->value() . ' ' . $OPT->desc())
1402
-                    : self::get_label_size_class($OPT->value());
1403
-                $desc    = $OPT->desc();// no self::prep_answer
1404
-                $answer  = is_numeric($value) && empty($answer) ? 0 : $answer;
1405
-                $checked = (string) $value == (string) $answer ? ' checked' : '';
1406
-                $opt     = '-' . sanitize_key($value);
1407
-
1408
-                $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1409
-                $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
1410
-                $input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>&nbsp;&nbsp;' : '';
1411
-                $input_html .= "\n\t\t\t\t\t\t"
1412
-                               . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" '
1413
-                               . 'class="' . $class . '" value="' . $value . '" '
1414
-                               . 'aria-label="' . esc_attr($required['msg']) . '" ' . $disabled
1415
-                               . $checked . ' ' . $extra . '/>';
1416
-                $input_html .= ! $label_b4
1417
-                    ? "\n\t\t\t\t\t\t"
1418
-                      . '&nbsp;&nbsp;<span class="espresso-radio-btn-desc">'
1419
-                      . $label
1420
-                      . '</span>'
1421
-                    : '';
1422
-                $input_html .= "\n\t\t\t\t\t" . '</label>';
1423
-                $input_html .= $use_desc_4_label
1424
-                    ? ''
1425
-                    : '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
1426
-                $input_html .= "\n\t\t\t\t" . '</li>';
1427
-            }
1428
-        }
1429
-
1430
-        $input_html .= "\n\t\t\t" . '</ul>';
1431
-
1432
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1433
-        return $label_html . $input_html;
1434
-    }
1435
-
1436
-
1437
-    /**
1438
-     * generates HTML for form checkbox inputs
1439
-     *
1440
-     * @param string $question    label content
1441
-     * @param string $answer      form input value attribute
1442
-     * @param array  $options     array of options where array key = option value and array value = option display text
1443
-     * @param string $name        form input name attribute
1444
-     * @param string $id          form input css id attribute
1445
-     * @param string $class       form input css class attribute
1446
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1447
-     *                            required 'class', and required 'msg' attribute
1448
-     * @param string $label_class css class attribute for the label
1449
-     * @param string $disabled    disabled="disabled" or null
1450
-     * @return string HTML
1451
-     */
1452
-    public static function checkbox(
1453
-        $question = false,
1454
-        $answer = null,
1455
-        $options = false,
1456
-        $name = false,
1457
-        $id = '',
1458
-        $class = '',
1459
-        $required = false,
1460
-        $required_text = '',
1461
-        $label_class = '',
1462
-        $disabled = false,
1463
-        $label_b4 = false,
1464
-        $system_ID = false,
1465
-        $use_html_entities = true,
1466
-        $add_mobile_label = false
1467
-    ) {
1468
-        // need these
1469
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1470
-            return null;
1471
-        }
1472
-        $answer = maybe_unserialize($answer);
1473
-
1474
-        // prep the answer(s)
1475
-        $answer = is_array($answer) ? $answer : [sanitize_key($answer) => $answer];
1476
-
1477
-        foreach ($answer as $key => $value) {
1478
-            $key            = self::prep_option_value($key);
1479
-            $answer[ $key ] = self::prep_answer($value, $use_html_entities);
1480
-        }
1481
-
1482
-        // prep the required array
1483
-        $required = self::prep_required($required);
1484
-        // set disabled tag
1485
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1486
-        // ya gots ta have style man!!!
1487
-        $radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
1488
-        $class       = empty($class) ? 'espresso-radio-btn-inp' : $class;
1489
-        $extra       = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1490
-
1491
-        $label_html   = self::label($question, $required_text, $required['label'], '', $label_class);
1492
-        $mobile_label = self::mobileLabel(
1493
-            $add_mobile_label,
1494
-            $question,
1495
-            $required_text,
1496
-            $required['label'],
1497
-            $label_class
1498
-        );
1499
-
1500
-        $input_html = $mobile_label
1501
-            . '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $class . '-ul">';
1502
-
1503
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1504
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1505
-
1506
-        foreach ($options as $OPT) {
1507
-            $value = $OPT->value();// self::prep_option_value( $OPT->value() );
1508
-            $size  = self::get_label_size_class($OPT->value() . ' ' . $OPT->desc());
1509
-            $text  = self::prep_answer($OPT->value());
1510
-            $desc  = $OPT->desc();
1511
-            $opt   = '-' . sanitize_key($value);
1512
-
1513
-            $checked = is_array($answer) && in_array($text, $answer) ? ' checked' : '';
1514
-
1515
-            $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1516
-            $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
1517
-            $input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>&nbsp;&nbsp;' : '';
1518
-            $input_html .= "\n\t\t\t\t\t\t"
1519
-                           . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" '
1520
-                           . 'id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" '
1521
-                           . 'aria-label="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
1522
-            $input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t" . '&nbsp;&nbsp;<span>' . $text . '</span>' : '';
1523
-            $input_html .= "\n\t\t\t\t\t" . '</label>';
1524
-            if (! empty($desc) && $desc != $text) {
1525
-                $input_html .= "\n\t\t\t\t\t"
1526
-                               . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">'
1527
-                               . $desc
1528
-                               . '</div>';
1529
-            }
1530
-            $input_html .= "\n\t\t\t\t" . '</li>';
1531
-        }
1532
-
1533
-        $input_html .= "\n\t\t\t" . '</ul>';
1534
-
1535
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1536
-        return $label_html . $input_html;
1537
-    }
1538
-
1539
-
1540
-    /**
1541
-     * generates HTML for a form datepicker input
1542
-     *
1543
-     * @param string $question    label content
1544
-     * @param string $answer      form input value attribute
1545
-     * @param string $name        form input name attribute
1546
-     * @param string $id          form input css id attribute
1547
-     * @param string $class       form input css class attribute
1548
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1549
-     *                            required 'class', and required 'msg' attribute
1550
-     * @param string $label_class css class attribute for the label
1551
-     * @param string $disabled    disabled="disabled" or null
1552
-     * @return string HTML
1553
-     */
1554
-    public static function datepicker(
1555
-        $question = false,
1556
-        $answer = null,
1557
-        $name = false,
1558
-        $id = '',
1559
-        $class = '',
1560
-        $required = false,
1561
-        $required_text = '',
1562
-        $label_class = '',
1563
-        $disabled = false,
1564
-        $system_ID = false,
1565
-        $use_html_entities = true,
1566
-        $add_mobile_label = false
1567
-    ) {
1568
-        // need these
1569
-        if (! $question || ! $name) {
1570
-            return null;
1571
-        }
1572
-        // prep the answer
1573
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1574
-        // prep the required array
1575
-        $required = self::prep_required($required);
1576
-        // set disabled tag
1577
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1578
-        // ya gots ta have style man!!!
1579
-        $txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1580
-        $class     = empty($class) ? $txt_class : $class;
1581
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1582
-        $class = self::appendInputSizeClass($class, $answer);
1583
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1584
-
1585
-        $label_html   = self::label($question, $required_text, $required['label'], '', $label_class);
1586
-        $mobile_label = self::mobileLabel(
1587
-            $add_mobile_label,
1588
-            $question,
1589
-            $required_text,
1590
-            $required['label'],
1591
-            $label_class,
1592
-            $name
1593
-        );
1594
-
1595
-        $input_html = $mobile_label
1596
-            . '<input type="text" name="' . $name . '" id="' . $id . '" '
1597
-            . 'class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  '
1598
-            . 'aria-label="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
1599
-
1600
-        // enqueue scripts
1601
-        wp_register_style(
1602
-            'espresso-ui-theme',
1603
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1604
-            [],
1605
-            EVENT_ESPRESSO_VERSION
1606
-        );
1607
-        wp_enqueue_style('espresso-ui-theme');
1608
-        wp_enqueue_script('jquery-ui-datepicker');
1609
-
1610
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1611
-        return $label_html . $input_html;
1612
-    }
1613
-
1614
-
1615
-    /**
1616
-     *  remove_label_keep_required_msg
1617
-     *  this will strip out a form input's label HTML while keeping the required text HTML that MUST be before the label
1618
-     *
1619
-     * @access public
1620
-     * @return     string
1621
-     */
1622
-    public static function remove_label_keep_required_msg($label_html, $required_text)
1623
-    {
1624
-        return $required_text;
1625
-    }
1626
-
1627
-
1628
-    /**
1629
-     * Simply returns the HTML for a hidden input of the given name and value.
1630
-     *
1631
-     * @param string $name
1632
-     * @param string $value
1633
-     * @return string HTML
1634
-     */
1635
-    public static function hidden_input($name, $value, $id = '')
1636
-    {
1637
-        $id = ! empty($id) ? $id : $name;
1638
-        return '<input id="' . $id . '" type="hidden" name="' . $name . '" value="' . $value . '"/>';
1639
-    }
1640
-
1641
-
1642
-    /**
1643
-     * prep_question
1644
-     *
1645
-     * @param string $question
1646
-     * @return string
1647
-     */
1648
-    public static function prep_question($question)
1649
-    {
1650
-        return $question;
1651
-    }
1652
-
1653
-
1654
-    /**
1655
-     *  prep_answer
1656
-     *
1657
-     * @param mixed $answer
1658
-     * @return string
1659
-     */
1660
-    public static function prep_answer($answer, $use_html_entities = true)
1661
-    {
1662
-        // make sure we convert bools first.  Otherwise (bool) false becomes an empty string which is NOT desired,
1663
-        // we want "0".
1664
-        if (is_bool($answer)) {
1665
-            $answer = $answer ? 1 : 0;
1666
-        }
1667
-        $answer = trim(stripslashes(str_replace('&#039;', "'", $answer)));
1668
-        return $use_html_entities ? htmlentities($answer, ENT_QUOTES, 'UTF-8') : $answer;
1669
-    }
1670
-
1671
-
1672
-    /**
1673
-     *  prep_answer_options
1674
-     *
1675
-     * @param array $QSOs array of EE_Question_Option objects
1676
-     * @return array
1677
-     */
1678
-    public static function prep_answer_options($QSOs = [])
1679
-    {
1680
-        $prepped_answer_options = [];
1681
-        if (is_array($QSOs) && ! empty($QSOs)) {
1682
-            foreach ($QSOs as $key => $QSO) {
1683
-                if (! $QSO instanceof EE_Question_Option) {
1684
-                    $QSO = EE_Question_Option::new_instance(
1685
-                        [
1686
-                            'QSO_value' => is_array($QSO) && isset($QSO['id'])
1687
-                                ? (string) $QSO['id']
1688
-                                : (string) $key,
1689
-                            'QSO_desc'  => is_array($QSO) && isset($QSO['text'])
1690
-                                ? (string) $QSO['text']
1691
-                                : (string) $QSO,
1692
-                        ]
1693
-                    );
1694
-                }
1695
-                if ($QSO->opt_group()) {
1696
-                    $prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
1697
-                } else {
1698
-                    $prepped_answer_options[] = $QSO;
1699
-                }
1700
-            }
1701
-        }
1702
-        //      d( $prepped_answer_options );
1703
-        return $prepped_answer_options;
1704
-    }
1705
-
1706
-
1707
-    /**
1708
-     *  prep_option_value
1709
-     *
1710
-     * @param string $option_value
1711
-     * @return string
1712
-     */
1713
-    public static function prep_option_value($option_value)
1714
-    {
1715
-        return esc_attr(trim(stripslashes($option_value)));
1716
-    }
1717
-
1718
-
1719
-    /**
1720
-     *  prep_required
1721
-     *
1722
-     * @param string|array $required
1723
-     * @return array
1724
-     */
1725
-    public static function prep_required($required = [])
1726
-    {
1727
-        // make sure required is an array
1728
-        $required = is_array($required) ? $required : [];
1729
-        // and set some defaults
1730
-        return array_merge(['label' => '', 'class' => '', 'msg' => ''], $required);
1731
-    }
1732
-
1733
-
1734
-    /**
1735
-     *  get_label_size_class
1736
-     *
1737
-     * @param string $value
1738
-     * @return string
1739
-     */
1740
-    public static function get_label_size_class($value = false)
1741
-    {
1742
-        if ($value === false || $value === '') {
1743
-            return ' class="medium-lbl"';
1744
-        }
1745
-        // determine length of option value
1746
-        $val_size = strlen($value);
1747
-        switch ($val_size) {
1748
-            case $val_size < 3:
1749
-                $size = ' class="nano-lbl"';
1750
-                break;
1751
-            case $val_size < 6:
1752
-                $size = ' class="micro-lbl"';
1753
-                break;
1754
-            case $val_size < 12:
1755
-                $size = ' class="tiny-lbl"';
1756
-                break;
1757
-            case $val_size < 25:
1758
-                $size = ' class="small-lbl"';
1759
-                break;
1760
-            case $val_size > 100:
1761
-                $size = ' class="big-lbl"';
1762
-                break;
1763
-            default:
1764
-                $size = ' class="medium-lbl"';
1765
-                break;
1766
-        }
1767
-        return $size;
1768
-    }
1769
-
1770
-
1771
-    /**
1772
-     *  _load_system_dropdowns
1773
-     *
1774
-     * @param EE_Question_Form_Input $QFI
1775
-     * @return array
1776
-     * @throws EE_Error
1777
-     * @throws ReflectionException
1778
-     */
1779
-    private static function _load_system_dropdowns($QFI)
1780
-    {
1781
-        $QST_system = $QFI->get('QST_system');
1782
-        switch ($QST_system) {
1783
-            case 'state':
1784
-                $QFI = self::generate_state_dropdown($QFI);
1785
-                break;
1786
-            case 'country':
1787
-                $QFI = self::generate_country_dropdown($QFI);
1788
-                break;
1789
-            case 'admin-state':
1790
-                $QFI = self::generate_state_dropdown($QFI, true);
1791
-                break;
1792
-            case 'admin-country':
1793
-                $QFI = self::generate_country_dropdown($QFI, true);
1794
-                break;
1795
-        }
1796
-        return $QFI;
1797
-    }
1798
-
1799
-
1800
-    /**
1801
-     * This preps dropdowns that are specialized.
1802
-     *
1803
-     * @param EE_Question_Form_Input $QFI
1804
-     *
1805
-     * @return EE_Question_Form_Input
1806
-     * @throws EE_Error
1807
-     * @throws ReflectionException
1808
-     * @since  4.6.0
1809
-     */
1810
-    protected static function _load_specialized_dropdowns($QFI)
1811
-    {
1812
-        switch ($QFI->get('QST_type')) {
1813
-            case 'STATE':
1814
-                $QFI = self::generate_state_dropdown($QFI);
1815
-                break;
1816
-            case 'COUNTRY':
1817
-                $QFI = self::generate_country_dropdown($QFI);
1818
-                break;
1819
-        }
1820
-        return $QFI;
1821
-    }
1822
-
1823
-
1824
-    /**
1825
-     *    generate_state_dropdown
1826
-     *
1827
-     * @param EE_Question_Form_Input $QST
1828
-     * @param bool                   $get_all
1829
-     * @return EE_Question_Form_Input
1830
-     * @throws EE_Error
1831
-     * @throws ReflectionException
1832
-     */
1833
-    public static function generate_state_dropdown($QST, $get_all = false)
1834
-    {
1835
-        $states = $get_all
1836
-            ? EEM_State::instance()->get_all_states()
1837
-            : EEM_State::instance()->get_all_states_of_active_countries();
1838
-        if ($states && count($states) != count($QST->options())) {
1839
-            $QST->set('QST_type', 'DROPDOWN');
1840
-            // if multiple countries, we'll create option groups within the dropdown
1841
-            foreach ($states as $state) {
1842
-                if ($state instanceof EE_State) {
1843
-                    $QSO = EE_Question_Option::new_instance(
1844
-                        [
1845
-                            'QSO_value'   => $state->ID(),
1846
-                            'QSO_desc'    => $state->name(),
1847
-                            'QST_ID'      => $QST->get('QST_ID'),
1848
-                            'QSO_deleted' => false,
1849
-                        ]
1850
-                    );
1851
-                    // set option group
1852
-                    $QSO->set_opt_group($state->country()->name());
1853
-                    // add option to question
1854
-                    $QST->add_temp_option($QSO);
1855
-                }
1856
-            }
1857
-        }
1858
-        return $QST;
1859
-    }
1860
-
1861
-
1862
-    /**
1863
-     *    generate_country_dropdown
1864
-     *
1865
-     * @param      $QST
1866
-     * @param bool $get_all
1867
-     * @return array
1868
-     * @throws EE_Error
1869
-     * @throws ReflectionException
1870
-     * @internal param array $question
1871
-     */
1872
-    public static function generate_country_dropdown($QST, $get_all = false)
1873
-    {
1874
-        $countries = $get_all
1875
-            ? EEM_Country::instance()->get_all_countries()
1876
-            : EEM_Country::instance()->get_all_active_countries();
1877
-        if ($countries && count($countries) != count($QST->options())) {
1878
-            $QST->set('QST_type', 'DROPDOWN');
1879
-            // now add countries
1880
-            foreach ($countries as $country) {
1881
-                if ($country instanceof EE_Country) {
1882
-                    $QSO = EE_Question_Option::new_instance(
1883
-                        [
1884
-                            'QSO_value'   => $country->ID(),
1885
-                            'QSO_desc'    => $country->name(),
1886
-                            'QST_ID'      => $QST->get('QST_ID'),
1887
-                            'QSO_deleted' => false,
1888
-                        ]
1889
-                    );
1890
-                    $QST->add_temp_option($QSO);
1891
-                }
1892
-            }
1893
-        }
1894
-        return $QST;
1895
-    }
1896
-
1897
-
1898
-    /**
1899
-     *  generates options for a month dropdown selector with numbers from 01 to 12
1900
-     *
1901
-     * @return array()
1902
-     */
1903
-    public static function two_digit_months_dropdown_options()
1904
-    {
1905
-        $options = [];
1906
-        for ($x = 1; $x <= 12; $x++) {
1907
-            $mm             = str_pad($x, 2, '0', STR_PAD_LEFT);
1908
-            $options[ $mm ] = $mm;
1909
-        }
1910
-        return EEH_Form_Fields::prep_answer_options($options);
1911
-    }
1912
-
1913
-
1914
-    /**
1915
-     *  generates a year dropdown selector with numbers for the next ten years
1916
-     *
1917
-     * @return array
1918
-     */
1919
-    public static function next_decade_two_digit_year_dropdown_options()
1920
-    {
1921
-        $options      = [];
1922
-        $current_year = date('y');
1923
-        $next_decade  = $current_year + 10;
1924
-        for ($x = $current_year; $x <= $next_decade; $x++) {
1925
-            $yy             = str_pad($x, 2, '0', STR_PAD_LEFT);
1926
-            $options[ $yy ] = $yy;
1927
-        }
1928
-        return EEH_Form_Fields::prep_answer_options($options);
1929
-    }
1930
-
1931
-
1932
-    /**
1933
-     * generates a month/year dropdown selector for all registrations matching the given criteria.  Typically used for
1934
-     * list table filter.
1935
-     *
1936
-     * @param string  $cur_date     any currently selected date can be entered here.
1937
-     * @param string  $status       Registration status
1938
-     * @param integer $evt_category Event Category ID if the Event Category filter is selected
1939
-     * @return string                html
1940
-     * @throws EE_Error
1941
-     */
1942
-    public static function generate_registration_months_dropdown($cur_date = '', $status = '', $evt_category = 0)
1943
-    {
1944
-        $_where = [];
1945
-        if (! empty($status)) {
1946
-            $_where['STS_ID'] = $status;
1947
-        }
1948
-
1949
-        if ($evt_category > 0) {
1950
-            $_where['Event.Term_Taxonomy.term_id'] = $evt_category;
1951
-        }
1952
-
1953
-        $regdtts = EEM_Registration::instance()->get_reg_months_and_years($_where);
1954
-
1955
-        // setup vals for select input helper
1956
-        $options = [
1957
-            0 => [
1958
-                'text' => esc_html__('Select a Month/Year', 'event_espresso'),
1959
-                'id'   => '',
1960
-            ],
1961
-        ];
1962
-
1963
-        foreach ($regdtts as $regdtt) {
1964
-            $date      = $regdtt->reg_month . ' ' . $regdtt->reg_year;
1965
-            $options[] = [
1966
-                'text' => $date,
1967
-                'id'   => $date,
1968
-            ];
1969
-        }
1970
-
1971
-        return self::select_input('month_range', $options, $cur_date);
1972
-    }
1973
-
1974
-
1975
-    /**
1976
-     * generates a month/year dropdown selector for all events matching the given criteria
1977
-     * Typically used for list table filter
1978
-     *
1979
-     * @param string $cur_date          any currently selected date can be entered here.
1980
-     * @param string $status            "view" (i.e. all, today, month, draft)
1981
-     * @param int    $evt_category      category event belongs to
1982
-     * @param string $evt_active_status "upcoming", "expired", "active", or "inactive"
1983
-     * @return string                    html
1984
-     * @throws EE_Error
1985
-     */
1986
-    public static function generate_event_months_dropdown(
1987
-        $cur_date = '',
1988
-        $status = null,
1989
-        $evt_category = null,
1990
-        $evt_active_status = null
1991
-    ) {
1992
-        // determine what post_status our condition will have for the query.
1993
-        // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
1994
-        switch ($status) {
1995
-            case 'month':
1996
-            case 'today':
1997
-            case null:
1998
-            case 'all':
1999
-                $where['Event.status'] = ['NOT IN', ['trash']];
2000
-                break;
2001
-            case 'draft':
2002
-                $where['Event.status'] = ['IN', ['draft', 'auto-draft']];
2003
-                break;
2004
-            default:
2005
-                $where['Event.status'] = $status;
2006
-        }
2007
-
2008
-        // phpcs:enable
2009
-
2010
-        // categories?
2011
-
2012
-
2013
-        if (! empty($evt_category)) {
2014
-            $where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
2015
-            $where['Event.Term_Taxonomy.term_id']  = $evt_category;
2016
-        }
2017
-
2018
-
2019
-        //      $where['DTT_is_primary'] = 1;
2020
-
2021
-        $DTTS = EEM_Datetime::instance()->get_dtt_months_and_years($where, $evt_active_status);
2022
-
2023
-        // let's setup vals for select input helper
2024
-        $options = [
2025
-            0 => [
2026
-                'text' => esc_html__('Select a Month/Year', 'event_espresso'),
2027
-                'id'   => "",
2028
-            ],
2029
-        ];
2030
-
2031
-
2032
-        // translate month and date
2033
-        global $wp_locale;
2034
-
2035
-        foreach ($DTTS as $DTT) {
2036
-            $localized_date = $wp_locale->get_month($DTT->dtt_month_num) . ' ' . $DTT->dtt_year;
2037
-            $id             = $DTT->dtt_month . ' ' . $DTT->dtt_year;
2038
-            $options[]      = [
2039
-                'text' => $localized_date,
2040
-                'id'   => $id,
2041
-            ];
2042
-        }
2043
-
2044
-
2045
-        return self::select_input('month_range', $options, $cur_date);
2046
-    }
2047
-
2048
-
2049
-    /**
2050
-     * generates the dropdown selector for event categories
2051
-     * typically used as a filter on list tables.
2052
-     *
2053
-     * @param integer $current_cat currently selected category
2054
-     * @return string               html for dropdown
2055
-     * @throws EE_Error
2056
-     * @throws ReflectionException
2057
-     */
2058
-    public static function generate_event_category_dropdown($current_cat = -1)
2059
-    {
2060
-        $categories = EEM_Term::instance()->get_all_ee_categories(true);
2061
-        $options    = [
2062
-            '0' => [
2063
-                'text' => esc_html__('All Categories', 'event_espresso'),
2064
-                'id'   => -1,
2065
-            ],
2066
-        ];
2067
-
2068
-        // setup categories for dropdown
2069
-        foreach ($categories as $category) {
2070
-            $options[] = [
2071
-                'text' => $category->get('name'),
2072
-                'id'   => $category->ID(),
2073
-            ];
2074
-        }
2075
-
2076
-        return self::select_input('EVT_CAT', $options, $current_cat);
2077
-    }
2078
-
2079
-
2080
-    /**
2081
-     *    generate a submit button with or without it's own microform
2082
-     *    this is the only way to create buttons that are compatible across all themes
2083
-     *
2084
-     * @access    public
2085
-     * @param string      $url              - the form action
2086
-     * @param string      $ID               - some kind of unique ID, appended with "-sbmt" for the input and "-frm"
2087
-     *                                      for the form
2088
-     * @param string      $class            - css classes (separated by spaces if more than one)
2089
-     * @param string      $text             - what appears on the button
2090
-     * @param string      $nonce_action     - if using nonces
2091
-     * @param bool|string $input_only       - whether to print form header and footer. TRUE returns the input without
2092
-     *                                      the form
2093
-     * @param string      $extra_attributes - any extra attributes that need to be attached to the form input
2094
-     * @return    string
2095
-     */
2096
-    public static function submit_button(
2097
-        $url = '',
2098
-        $ID = '',
2099
-        $class = '',
2100
-        $text = '',
2101
-        $nonce_action = '',
2102
-        $input_only = false,
2103
-        $extra_attributes = ''
2104
-    ) {
2105
-        $btn = '';
2106
-        if (empty($url) || empty($ID)) {
2107
-            return $btn;
2108
-        }
2109
-        $text = ! empty($text) ? $text : esc_html__('Submit', 'event_espresso');
2110
-        $btn  .= '<input id="' . $ID . '-btn" class="' . $class . '" '
2111
-                 . 'type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
2112
-        if (! $input_only) {
2113
-            $btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
2114
-            $btn_frm .= ! empty($nonce_action)
2115
-                ? wp_nonce_field($nonce_action, $nonce_action . '_nonce', true, false)
2116
-                : '';
2117
-            $btn_frm .= $btn;
2118
-            $btn_frm .= '</form>';
2119
-            $btn     = $btn_frm;
2120
-            unset($btn_frm);
2121
-        }
2122
-        return $btn;
2123
-    }
1089
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1090
+		return $label_html . $input_html;
1091
+	}
1092
+
1093
+
1094
+	/**
1095
+	 * generates HTML for a form textarea
1096
+	 *
1097
+	 * @param string $question    label content
1098
+	 * @param string $answer      form input value attribute
1099
+	 * @param string $name        form input name attribute
1100
+	 * @param string $id          form input css id attribute
1101
+	 * @param string $class       form input css class attribute
1102
+	 * @param array  $dimensions  array of form input rows and cols attributes : array( 'rows' => 3, 'cols' => 40 )
1103
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1104
+	 *                            required 'class', and required 'msg' attribute
1105
+	 * @param string $label_class css class attribute for the label
1106
+	 * @param string $disabled    disabled="disabled" or null
1107
+	 * @return string HTML
1108
+	 */
1109
+	public static function textarea(
1110
+		$question = false,
1111
+		$answer = null,
1112
+		$name = false,
1113
+		$id = '',
1114
+		$class = '',
1115
+		$dimensions = false,
1116
+		$required = false,
1117
+		$required_text = '',
1118
+		$label_class = '',
1119
+		$disabled = false,
1120
+		$system_ID = false,
1121
+		$use_html_entities = true,
1122
+		$add_mobile_label = false
1123
+	) {
1124
+		// need these
1125
+		if (! $question || ! $name) {
1126
+			return null;
1127
+		}
1128
+		// prep the answer
1129
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1130
+		// prep the required array
1131
+		$required = self::prep_required($required);
1132
+		// make sure $dimensions is an array
1133
+		$dimensions = is_array($dimensions) ? $dimensions : [];
1134
+		// and set some defaults
1135
+		$dimensions = array_merge(['rows' => 3, 'cols' => 40], $dimensions);
1136
+		// set disabled tag
1137
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1138
+		// ya gots ta have style man!!!
1139
+		$class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1140
+		$class     .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1141
+		$extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1142
+
1143
+		$label_html   = self::label($question, $required_text, $required['label'], $name, $label_class);
1144
+		$mobile_label = self::mobileLabel(
1145
+			$add_mobile_label,
1146
+			$question,
1147
+			$required_text,
1148
+			$required['label'],
1149
+			$label_class,
1150
+			$name
1151
+		);
1152
+
1153
+		$input_html = $mobile_label
1154
+			. '<textarea name="' . $name . '" id="' . $id . '" class="' . trim($class) . '" '
1155
+			. 'rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  '
1156
+			. 'aria-label="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>'
1157
+			 . esc_textarea($answer)
1158
+			  . '</textarea>';
1159
+
1160
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1161
+		return $label_html . $input_html;
1162
+	}
1163
+
1164
+
1165
+	/**
1166
+	 * generates HTML for a form select input
1167
+	 *
1168
+	 * @param string $question    label content
1169
+	 * @param string $answer      form input value attribute
1170
+	 * @param array  $options     array of answer options where array key = option value and array value = option
1171
+	 *                            display text
1172
+	 * @param string $name        form input name attribute
1173
+	 * @param string $id          form input css id attribute
1174
+	 * @param string $class       form input css class attribute
1175
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1176
+	 *                            required 'class', and required 'msg' attribute
1177
+	 * @param string $label_class css class attribute for the label
1178
+	 * @param string $disabled    disabled="disabled" or null
1179
+	 * @return string HTML
1180
+	 */
1181
+	public static function select(
1182
+		$question = false,
1183
+		$answer = null,
1184
+		$options = false,
1185
+		$name = false,
1186
+		$id = '',
1187
+		$class = '',
1188
+		$required = false,
1189
+		$required_text = '',
1190
+		$label_class = '',
1191
+		$disabled = false,
1192
+		$system_ID = false,
1193
+		$use_html_entities = true,
1194
+		$add_please_select_option = false,
1195
+		$add_mobile_label = false
1196
+	) {
1197
+
1198
+		// need these
1199
+		if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1200
+			return null;
1201
+		}
1202
+		// prep the answer
1203
+		$answer = is_array($answer)
1204
+			? self::prep_answer(array_shift($answer), $use_html_entities)
1205
+			: self::prep_answer($answer, $use_html_entities);
1206
+		// prep the required array
1207
+		$required = self::prep_required($required);
1208
+		// set disabled tag
1209
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1210
+		// ya gots ta have style man!!!
1211
+		$class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1212
+		$class = self::appendInputSizeClass($class, $options);
1213
+		$extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1214
+
1215
+		$label_html   = self::label($question, $required_text, $required['label'], $name, $label_class);
1216
+		$mobile_label = self::mobileLabel(
1217
+			$add_mobile_label,
1218
+			$question,
1219
+			$required_text,
1220
+			$required['label'],
1221
+			$label_class,
1222
+			$name
1223
+		);
1224
+
1225
+		$input_html = $mobile_label
1226
+			. '<select name="' . $name . '" id="' . $id . '" class="' . trim($class) . ' ' . $required['class'] . '" '
1227
+			. 'aria-label="' . esc_attr($required['msg']) . '"' . $disabled . ' ' . $extra . '>';
1228
+		// recursively count array elements, to determine total number of options
1229
+		$only_option = count($options, 1) == 1;
1230
+		if (! $only_option) {
1231
+			// if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
1232
+			$selected   = $answer === null ? ' selected' : '';
1233
+			$input_html .= $add_please_select_option
1234
+				? "\n\t\t\t\t"
1235
+				  . '<option value=""' . $selected . '>'
1236
+				  . esc_html__(' - please select - ', 'event_espresso')
1237
+				  . '</option>'
1238
+				: '';
1239
+		}
1240
+		foreach ($options as $key => $value) {
1241
+			// if value is an array, then create option groups, else create regular ol' options
1242
+			$input_html .= is_array($value)
1243
+				? self::_generate_select_option_group(
1244
+					$key,
1245
+					$value,
1246
+					$answer,
1247
+					$use_html_entities
1248
+				)
1249
+				: self::_generate_select_option(
1250
+					$value->value(),
1251
+					$value->desc(),
1252
+					$answer,
1253
+					$only_option,
1254
+					$use_html_entities
1255
+				);
1256
+		}
1257
+
1258
+		$input_html .= "\n\t\t\t" . '</select>';
1259
+
1260
+		$input_html =
1261
+			apply_filters(
1262
+				'FHEE__EEH_Form_Fields__select__before_end_wrapper',
1263
+				$input_html,
1264
+				$question,
1265
+				$answer,
1266
+				$name,
1267
+				$id,
1268
+				$class,
1269
+				$system_ID
1270
+			);
1271
+
1272
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1273
+		return $label_html . $input_html;
1274
+	}
1275
+
1276
+
1277
+	/**
1278
+	 *  _generate_select_option_group
1279
+	 *
1280
+	 *  if  $value for a select box is an array, then the key will be used as the optgroup label
1281
+	 *  and the value array will be looped thru and the elements sent to _generate_select_option
1282
+	 *
1283
+	 * @param mixed   $opt_group
1284
+	 * @param mixed   $QSOs
1285
+	 * @param mixed   $answer
1286
+	 * @param boolean $use_html_entities
1287
+	 * @return string
1288
+	 */
1289
+	private static function _generate_select_option_group($opt_group, $QSOs, $answer, $use_html_entities = true)
1290
+	{
1291
+		$html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value($opt_group) . '">';
1292
+		foreach ($QSOs as $QSO) {
1293
+			$html .= self::_generate_select_option($QSO->value(), $QSO->desc(), $answer, false, $use_html_entities);
1294
+		}
1295
+		$html .= "\n\t\t\t\t" . '</optgroup>';
1296
+		return $html;
1297
+	}
1298
+
1299
+
1300
+	/**
1301
+	 *  _generate_select_option
1302
+	 *
1303
+	 * @param mixed   $key
1304
+	 * @param mixed   $value
1305
+	 * @param mixed   $answer
1306
+	 * @param int     $only_option
1307
+	 * @param boolean $use_html_entities
1308
+	 * @return string
1309
+	 */
1310
+	private static function _generate_select_option(
1311
+		$key,
1312
+		$value,
1313
+		$answer,
1314
+		$only_option = false,
1315
+		$use_html_entities = true
1316
+	) {
1317
+		$key      = self::prep_answer($key, $use_html_entities);
1318
+		$value    = self::prep_answer($value, $use_html_entities);
1319
+		$value    = ! empty($value) ? $value : $key;
1320
+		$selected = ($answer == $key || $only_option) ? 'selected' : '';
1321
+		return "\n\t\t\t\t"
1322
+			   . '<option value="' . self::prep_option_value($key) . '" ' . $selected . '> '
1323
+			   . $value
1324
+			   . '&nbsp;&nbsp;&nbsp;</option>';
1325
+	}
1326
+
1327
+
1328
+	/**
1329
+	 * generates HTML for form radio button inputs
1330
+	 *
1331
+	 * @param bool|string $question    label content
1332
+	 * @param string      $answer      form input value attribute
1333
+	 * @param array|bool  $options     array of answer options where array key = option value and array value = option
1334
+	 *                                 display text
1335
+	 * @param bool|string $name        form input name attribute
1336
+	 * @param string      $id          form input css id attribute
1337
+	 * @param string      $class       form input css class attribute
1338
+	 * @param array|bool  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1339
+	 *                                 required 'class', and required 'msg' attribute
1340
+	 * @param string      $required_text
1341
+	 * @param string      $label_class css class attribute for the label
1342
+	 * @param bool|string $disabled    disabled="disabled" or null
1343
+	 * @param bool        $system_ID
1344
+	 * @param bool        $use_html_entities
1345
+	 * @param bool        $label_b4
1346
+	 * @param bool        $use_desc_4_label
1347
+	 * @return string HTML
1348
+	 */
1349
+	public static function radio(
1350
+		$question = false,
1351
+		$answer = null,
1352
+		$options = false,
1353
+		$name = false,
1354
+		$id = '',
1355
+		$class = '',
1356
+		$required = false,
1357
+		$required_text = '',
1358
+		$label_class = '',
1359
+		$disabled = false,
1360
+		$system_ID = false,
1361
+		$use_html_entities = true,
1362
+		$label_b4 = false,
1363
+		$use_desc_4_label = false,
1364
+		$add_mobile_label = false
1365
+	) {
1366
+		// need these
1367
+		if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1368
+			return null;
1369
+		}
1370
+		// prep the answer
1371
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1372
+		// prep the required array
1373
+		$required = self::prep_required($required);
1374
+		// set disabled tag
1375
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1376
+		// ya gots ta have style man!!!
1377
+		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
1378
+		$class       = ! empty($class) ? $class : 'espresso-radio-btn-inp';
1379
+		$extra       = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1380
+
1381
+		$label_html = self::label($question, $required_text, $required['label'], '', $label_class);
1382
+		$mobile_label = self::mobileLabel(
1383
+			$add_mobile_label,
1384
+			$question,
1385
+			$required_text,
1386
+			$required['label'],
1387
+			$label_class
1388
+		);
1389
+
1390
+		$input_html = $mobile_label
1391
+			. '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $class . '-ul">';
1392
+
1393
+		$class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1394
+		$class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1395
+
1396
+		foreach ($options as $OPT) {
1397
+			if ($OPT instanceof EE_Question_Option) {
1398
+				$value   = self::prep_option_value($OPT->value());
1399
+				$label   = $use_desc_4_label ? $OPT->desc() : $OPT->value();
1400
+				$size    = $use_desc_4_label
1401
+					? self::get_label_size_class($OPT->value() . ' ' . $OPT->desc())
1402
+					: self::get_label_size_class($OPT->value());
1403
+				$desc    = $OPT->desc();// no self::prep_answer
1404
+				$answer  = is_numeric($value) && empty($answer) ? 0 : $answer;
1405
+				$checked = (string) $value == (string) $answer ? ' checked' : '';
1406
+				$opt     = '-' . sanitize_key($value);
1407
+
1408
+				$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1409
+				$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
1410
+				$input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>&nbsp;&nbsp;' : '';
1411
+				$input_html .= "\n\t\t\t\t\t\t"
1412
+							   . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" '
1413
+							   . 'class="' . $class . '" value="' . $value . '" '
1414
+							   . 'aria-label="' . esc_attr($required['msg']) . '" ' . $disabled
1415
+							   . $checked . ' ' . $extra . '/>';
1416
+				$input_html .= ! $label_b4
1417
+					? "\n\t\t\t\t\t\t"
1418
+					  . '&nbsp;&nbsp;<span class="espresso-radio-btn-desc">'
1419
+					  . $label
1420
+					  . '</span>'
1421
+					: '';
1422
+				$input_html .= "\n\t\t\t\t\t" . '</label>';
1423
+				$input_html .= $use_desc_4_label
1424
+					? ''
1425
+					: '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
1426
+				$input_html .= "\n\t\t\t\t" . '</li>';
1427
+			}
1428
+		}
1429
+
1430
+		$input_html .= "\n\t\t\t" . '</ul>';
1431
+
1432
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1433
+		return $label_html . $input_html;
1434
+	}
1435
+
1436
+
1437
+	/**
1438
+	 * generates HTML for form checkbox inputs
1439
+	 *
1440
+	 * @param string $question    label content
1441
+	 * @param string $answer      form input value attribute
1442
+	 * @param array  $options     array of options where array key = option value and array value = option display text
1443
+	 * @param string $name        form input name attribute
1444
+	 * @param string $id          form input css id attribute
1445
+	 * @param string $class       form input css class attribute
1446
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1447
+	 *                            required 'class', and required 'msg' attribute
1448
+	 * @param string $label_class css class attribute for the label
1449
+	 * @param string $disabled    disabled="disabled" or null
1450
+	 * @return string HTML
1451
+	 */
1452
+	public static function checkbox(
1453
+		$question = false,
1454
+		$answer = null,
1455
+		$options = false,
1456
+		$name = false,
1457
+		$id = '',
1458
+		$class = '',
1459
+		$required = false,
1460
+		$required_text = '',
1461
+		$label_class = '',
1462
+		$disabled = false,
1463
+		$label_b4 = false,
1464
+		$system_ID = false,
1465
+		$use_html_entities = true,
1466
+		$add_mobile_label = false
1467
+	) {
1468
+		// need these
1469
+		if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1470
+			return null;
1471
+		}
1472
+		$answer = maybe_unserialize($answer);
1473
+
1474
+		// prep the answer(s)
1475
+		$answer = is_array($answer) ? $answer : [sanitize_key($answer) => $answer];
1476
+
1477
+		foreach ($answer as $key => $value) {
1478
+			$key            = self::prep_option_value($key);
1479
+			$answer[ $key ] = self::prep_answer($value, $use_html_entities);
1480
+		}
1481
+
1482
+		// prep the required array
1483
+		$required = self::prep_required($required);
1484
+		// set disabled tag
1485
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1486
+		// ya gots ta have style man!!!
1487
+		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
1488
+		$class       = empty($class) ? 'espresso-radio-btn-inp' : $class;
1489
+		$extra       = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1490
+
1491
+		$label_html   = self::label($question, $required_text, $required['label'], '', $label_class);
1492
+		$mobile_label = self::mobileLabel(
1493
+			$add_mobile_label,
1494
+			$question,
1495
+			$required_text,
1496
+			$required['label'],
1497
+			$label_class
1498
+		);
1499
+
1500
+		$input_html = $mobile_label
1501
+			. '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $class . '-ul">';
1502
+
1503
+		$class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1504
+		$class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1505
+
1506
+		foreach ($options as $OPT) {
1507
+			$value = $OPT->value();// self::prep_option_value( $OPT->value() );
1508
+			$size  = self::get_label_size_class($OPT->value() . ' ' . $OPT->desc());
1509
+			$text  = self::prep_answer($OPT->value());
1510
+			$desc  = $OPT->desc();
1511
+			$opt   = '-' . sanitize_key($value);
1512
+
1513
+			$checked = is_array($answer) && in_array($text, $answer) ? ' checked' : '';
1514
+
1515
+			$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1516
+			$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
1517
+			$input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>&nbsp;&nbsp;' : '';
1518
+			$input_html .= "\n\t\t\t\t\t\t"
1519
+						   . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" '
1520
+						   . 'id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" '
1521
+						   . 'aria-label="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
1522
+			$input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t" . '&nbsp;&nbsp;<span>' . $text . '</span>' : '';
1523
+			$input_html .= "\n\t\t\t\t\t" . '</label>';
1524
+			if (! empty($desc) && $desc != $text) {
1525
+				$input_html .= "\n\t\t\t\t\t"
1526
+							   . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">'
1527
+							   . $desc
1528
+							   . '</div>';
1529
+			}
1530
+			$input_html .= "\n\t\t\t\t" . '</li>';
1531
+		}
1532
+
1533
+		$input_html .= "\n\t\t\t" . '</ul>';
1534
+
1535
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1536
+		return $label_html . $input_html;
1537
+	}
1538
+
1539
+
1540
+	/**
1541
+	 * generates HTML for a form datepicker input
1542
+	 *
1543
+	 * @param string $question    label content
1544
+	 * @param string $answer      form input value attribute
1545
+	 * @param string $name        form input name attribute
1546
+	 * @param string $id          form input css id attribute
1547
+	 * @param string $class       form input css class attribute
1548
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1549
+	 *                            required 'class', and required 'msg' attribute
1550
+	 * @param string $label_class css class attribute for the label
1551
+	 * @param string $disabled    disabled="disabled" or null
1552
+	 * @return string HTML
1553
+	 */
1554
+	public static function datepicker(
1555
+		$question = false,
1556
+		$answer = null,
1557
+		$name = false,
1558
+		$id = '',
1559
+		$class = '',
1560
+		$required = false,
1561
+		$required_text = '',
1562
+		$label_class = '',
1563
+		$disabled = false,
1564
+		$system_ID = false,
1565
+		$use_html_entities = true,
1566
+		$add_mobile_label = false
1567
+	) {
1568
+		// need these
1569
+		if (! $question || ! $name) {
1570
+			return null;
1571
+		}
1572
+		// prep the answer
1573
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1574
+		// prep the required array
1575
+		$required = self::prep_required($required);
1576
+		// set disabled tag
1577
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1578
+		// ya gots ta have style man!!!
1579
+		$txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1580
+		$class     = empty($class) ? $txt_class : $class;
1581
+		$class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1582
+		$class = self::appendInputSizeClass($class, $answer);
1583
+		$extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1584
+
1585
+		$label_html   = self::label($question, $required_text, $required['label'], '', $label_class);
1586
+		$mobile_label = self::mobileLabel(
1587
+			$add_mobile_label,
1588
+			$question,
1589
+			$required_text,
1590
+			$required['label'],
1591
+			$label_class,
1592
+			$name
1593
+		);
1594
+
1595
+		$input_html = $mobile_label
1596
+			. '<input type="text" name="' . $name . '" id="' . $id . '" '
1597
+			. 'class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  '
1598
+			. 'aria-label="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
1599
+
1600
+		// enqueue scripts
1601
+		wp_register_style(
1602
+			'espresso-ui-theme',
1603
+			EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1604
+			[],
1605
+			EVENT_ESPRESSO_VERSION
1606
+		);
1607
+		wp_enqueue_style('espresso-ui-theme');
1608
+		wp_enqueue_script('jquery-ui-datepicker');
1609
+
1610
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1611
+		return $label_html . $input_html;
1612
+	}
1613
+
1614
+
1615
+	/**
1616
+	 *  remove_label_keep_required_msg
1617
+	 *  this will strip out a form input's label HTML while keeping the required text HTML that MUST be before the label
1618
+	 *
1619
+	 * @access public
1620
+	 * @return     string
1621
+	 */
1622
+	public static function remove_label_keep_required_msg($label_html, $required_text)
1623
+	{
1624
+		return $required_text;
1625
+	}
1626
+
1627
+
1628
+	/**
1629
+	 * Simply returns the HTML for a hidden input of the given name and value.
1630
+	 *
1631
+	 * @param string $name
1632
+	 * @param string $value
1633
+	 * @return string HTML
1634
+	 */
1635
+	public static function hidden_input($name, $value, $id = '')
1636
+	{
1637
+		$id = ! empty($id) ? $id : $name;
1638
+		return '<input id="' . $id . '" type="hidden" name="' . $name . '" value="' . $value . '"/>';
1639
+	}
1640
+
1641
+
1642
+	/**
1643
+	 * prep_question
1644
+	 *
1645
+	 * @param string $question
1646
+	 * @return string
1647
+	 */
1648
+	public static function prep_question($question)
1649
+	{
1650
+		return $question;
1651
+	}
1652
+
1653
+
1654
+	/**
1655
+	 *  prep_answer
1656
+	 *
1657
+	 * @param mixed $answer
1658
+	 * @return string
1659
+	 */
1660
+	public static function prep_answer($answer, $use_html_entities = true)
1661
+	{
1662
+		// make sure we convert bools first.  Otherwise (bool) false becomes an empty string which is NOT desired,
1663
+		// we want "0".
1664
+		if (is_bool($answer)) {
1665
+			$answer = $answer ? 1 : 0;
1666
+		}
1667
+		$answer = trim(stripslashes(str_replace('&#039;', "'", $answer)));
1668
+		return $use_html_entities ? htmlentities($answer, ENT_QUOTES, 'UTF-8') : $answer;
1669
+	}
1670
+
1671
+
1672
+	/**
1673
+	 *  prep_answer_options
1674
+	 *
1675
+	 * @param array $QSOs array of EE_Question_Option objects
1676
+	 * @return array
1677
+	 */
1678
+	public static function prep_answer_options($QSOs = [])
1679
+	{
1680
+		$prepped_answer_options = [];
1681
+		if (is_array($QSOs) && ! empty($QSOs)) {
1682
+			foreach ($QSOs as $key => $QSO) {
1683
+				if (! $QSO instanceof EE_Question_Option) {
1684
+					$QSO = EE_Question_Option::new_instance(
1685
+						[
1686
+							'QSO_value' => is_array($QSO) && isset($QSO['id'])
1687
+								? (string) $QSO['id']
1688
+								: (string) $key,
1689
+							'QSO_desc'  => is_array($QSO) && isset($QSO['text'])
1690
+								? (string) $QSO['text']
1691
+								: (string) $QSO,
1692
+						]
1693
+					);
1694
+				}
1695
+				if ($QSO->opt_group()) {
1696
+					$prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
1697
+				} else {
1698
+					$prepped_answer_options[] = $QSO;
1699
+				}
1700
+			}
1701
+		}
1702
+		//      d( $prepped_answer_options );
1703
+		return $prepped_answer_options;
1704
+	}
1705
+
1706
+
1707
+	/**
1708
+	 *  prep_option_value
1709
+	 *
1710
+	 * @param string $option_value
1711
+	 * @return string
1712
+	 */
1713
+	public static function prep_option_value($option_value)
1714
+	{
1715
+		return esc_attr(trim(stripslashes($option_value)));
1716
+	}
1717
+
1718
+
1719
+	/**
1720
+	 *  prep_required
1721
+	 *
1722
+	 * @param string|array $required
1723
+	 * @return array
1724
+	 */
1725
+	public static function prep_required($required = [])
1726
+	{
1727
+		// make sure required is an array
1728
+		$required = is_array($required) ? $required : [];
1729
+		// and set some defaults
1730
+		return array_merge(['label' => '', 'class' => '', 'msg' => ''], $required);
1731
+	}
1732
+
1733
+
1734
+	/**
1735
+	 *  get_label_size_class
1736
+	 *
1737
+	 * @param string $value
1738
+	 * @return string
1739
+	 */
1740
+	public static function get_label_size_class($value = false)
1741
+	{
1742
+		if ($value === false || $value === '') {
1743
+			return ' class="medium-lbl"';
1744
+		}
1745
+		// determine length of option value
1746
+		$val_size = strlen($value);
1747
+		switch ($val_size) {
1748
+			case $val_size < 3:
1749
+				$size = ' class="nano-lbl"';
1750
+				break;
1751
+			case $val_size < 6:
1752
+				$size = ' class="micro-lbl"';
1753
+				break;
1754
+			case $val_size < 12:
1755
+				$size = ' class="tiny-lbl"';
1756
+				break;
1757
+			case $val_size < 25:
1758
+				$size = ' class="small-lbl"';
1759
+				break;
1760
+			case $val_size > 100:
1761
+				$size = ' class="big-lbl"';
1762
+				break;
1763
+			default:
1764
+				$size = ' class="medium-lbl"';
1765
+				break;
1766
+		}
1767
+		return $size;
1768
+	}
1769
+
1770
+
1771
+	/**
1772
+	 *  _load_system_dropdowns
1773
+	 *
1774
+	 * @param EE_Question_Form_Input $QFI
1775
+	 * @return array
1776
+	 * @throws EE_Error
1777
+	 * @throws ReflectionException
1778
+	 */
1779
+	private static function _load_system_dropdowns($QFI)
1780
+	{
1781
+		$QST_system = $QFI->get('QST_system');
1782
+		switch ($QST_system) {
1783
+			case 'state':
1784
+				$QFI = self::generate_state_dropdown($QFI);
1785
+				break;
1786
+			case 'country':
1787
+				$QFI = self::generate_country_dropdown($QFI);
1788
+				break;
1789
+			case 'admin-state':
1790
+				$QFI = self::generate_state_dropdown($QFI, true);
1791
+				break;
1792
+			case 'admin-country':
1793
+				$QFI = self::generate_country_dropdown($QFI, true);
1794
+				break;
1795
+		}
1796
+		return $QFI;
1797
+	}
1798
+
1799
+
1800
+	/**
1801
+	 * This preps dropdowns that are specialized.
1802
+	 *
1803
+	 * @param EE_Question_Form_Input $QFI
1804
+	 *
1805
+	 * @return EE_Question_Form_Input
1806
+	 * @throws EE_Error
1807
+	 * @throws ReflectionException
1808
+	 * @since  4.6.0
1809
+	 */
1810
+	protected static function _load_specialized_dropdowns($QFI)
1811
+	{
1812
+		switch ($QFI->get('QST_type')) {
1813
+			case 'STATE':
1814
+				$QFI = self::generate_state_dropdown($QFI);
1815
+				break;
1816
+			case 'COUNTRY':
1817
+				$QFI = self::generate_country_dropdown($QFI);
1818
+				break;
1819
+		}
1820
+		return $QFI;
1821
+	}
1822
+
1823
+
1824
+	/**
1825
+	 *    generate_state_dropdown
1826
+	 *
1827
+	 * @param EE_Question_Form_Input $QST
1828
+	 * @param bool                   $get_all
1829
+	 * @return EE_Question_Form_Input
1830
+	 * @throws EE_Error
1831
+	 * @throws ReflectionException
1832
+	 */
1833
+	public static function generate_state_dropdown($QST, $get_all = false)
1834
+	{
1835
+		$states = $get_all
1836
+			? EEM_State::instance()->get_all_states()
1837
+			: EEM_State::instance()->get_all_states_of_active_countries();
1838
+		if ($states && count($states) != count($QST->options())) {
1839
+			$QST->set('QST_type', 'DROPDOWN');
1840
+			// if multiple countries, we'll create option groups within the dropdown
1841
+			foreach ($states as $state) {
1842
+				if ($state instanceof EE_State) {
1843
+					$QSO = EE_Question_Option::new_instance(
1844
+						[
1845
+							'QSO_value'   => $state->ID(),
1846
+							'QSO_desc'    => $state->name(),
1847
+							'QST_ID'      => $QST->get('QST_ID'),
1848
+							'QSO_deleted' => false,
1849
+						]
1850
+					);
1851
+					// set option group
1852
+					$QSO->set_opt_group($state->country()->name());
1853
+					// add option to question
1854
+					$QST->add_temp_option($QSO);
1855
+				}
1856
+			}
1857
+		}
1858
+		return $QST;
1859
+	}
1860
+
1861
+
1862
+	/**
1863
+	 *    generate_country_dropdown
1864
+	 *
1865
+	 * @param      $QST
1866
+	 * @param bool $get_all
1867
+	 * @return array
1868
+	 * @throws EE_Error
1869
+	 * @throws ReflectionException
1870
+	 * @internal param array $question
1871
+	 */
1872
+	public static function generate_country_dropdown($QST, $get_all = false)
1873
+	{
1874
+		$countries = $get_all
1875
+			? EEM_Country::instance()->get_all_countries()
1876
+			: EEM_Country::instance()->get_all_active_countries();
1877
+		if ($countries && count($countries) != count($QST->options())) {
1878
+			$QST->set('QST_type', 'DROPDOWN');
1879
+			// now add countries
1880
+			foreach ($countries as $country) {
1881
+				if ($country instanceof EE_Country) {
1882
+					$QSO = EE_Question_Option::new_instance(
1883
+						[
1884
+							'QSO_value'   => $country->ID(),
1885
+							'QSO_desc'    => $country->name(),
1886
+							'QST_ID'      => $QST->get('QST_ID'),
1887
+							'QSO_deleted' => false,
1888
+						]
1889
+					);
1890
+					$QST->add_temp_option($QSO);
1891
+				}
1892
+			}
1893
+		}
1894
+		return $QST;
1895
+	}
1896
+
1897
+
1898
+	/**
1899
+	 *  generates options for a month dropdown selector with numbers from 01 to 12
1900
+	 *
1901
+	 * @return array()
1902
+	 */
1903
+	public static function two_digit_months_dropdown_options()
1904
+	{
1905
+		$options = [];
1906
+		for ($x = 1; $x <= 12; $x++) {
1907
+			$mm             = str_pad($x, 2, '0', STR_PAD_LEFT);
1908
+			$options[ $mm ] = $mm;
1909
+		}
1910
+		return EEH_Form_Fields::prep_answer_options($options);
1911
+	}
1912
+
1913
+
1914
+	/**
1915
+	 *  generates a year dropdown selector with numbers for the next ten years
1916
+	 *
1917
+	 * @return array
1918
+	 */
1919
+	public static function next_decade_two_digit_year_dropdown_options()
1920
+	{
1921
+		$options      = [];
1922
+		$current_year = date('y');
1923
+		$next_decade  = $current_year + 10;
1924
+		for ($x = $current_year; $x <= $next_decade; $x++) {
1925
+			$yy             = str_pad($x, 2, '0', STR_PAD_LEFT);
1926
+			$options[ $yy ] = $yy;
1927
+		}
1928
+		return EEH_Form_Fields::prep_answer_options($options);
1929
+	}
1930
+
1931
+
1932
+	/**
1933
+	 * generates a month/year dropdown selector for all registrations matching the given criteria.  Typically used for
1934
+	 * list table filter.
1935
+	 *
1936
+	 * @param string  $cur_date     any currently selected date can be entered here.
1937
+	 * @param string  $status       Registration status
1938
+	 * @param integer $evt_category Event Category ID if the Event Category filter is selected
1939
+	 * @return string                html
1940
+	 * @throws EE_Error
1941
+	 */
1942
+	public static function generate_registration_months_dropdown($cur_date = '', $status = '', $evt_category = 0)
1943
+	{
1944
+		$_where = [];
1945
+		if (! empty($status)) {
1946
+			$_where['STS_ID'] = $status;
1947
+		}
1948
+
1949
+		if ($evt_category > 0) {
1950
+			$_where['Event.Term_Taxonomy.term_id'] = $evt_category;
1951
+		}
1952
+
1953
+		$regdtts = EEM_Registration::instance()->get_reg_months_and_years($_where);
1954
+
1955
+		// setup vals for select input helper
1956
+		$options = [
1957
+			0 => [
1958
+				'text' => esc_html__('Select a Month/Year', 'event_espresso'),
1959
+				'id'   => '',
1960
+			],
1961
+		];
1962
+
1963
+		foreach ($regdtts as $regdtt) {
1964
+			$date      = $regdtt->reg_month . ' ' . $regdtt->reg_year;
1965
+			$options[] = [
1966
+				'text' => $date,
1967
+				'id'   => $date,
1968
+			];
1969
+		}
1970
+
1971
+		return self::select_input('month_range', $options, $cur_date);
1972
+	}
1973
+
1974
+
1975
+	/**
1976
+	 * generates a month/year dropdown selector for all events matching the given criteria
1977
+	 * Typically used for list table filter
1978
+	 *
1979
+	 * @param string $cur_date          any currently selected date can be entered here.
1980
+	 * @param string $status            "view" (i.e. all, today, month, draft)
1981
+	 * @param int    $evt_category      category event belongs to
1982
+	 * @param string $evt_active_status "upcoming", "expired", "active", or "inactive"
1983
+	 * @return string                    html
1984
+	 * @throws EE_Error
1985
+	 */
1986
+	public static function generate_event_months_dropdown(
1987
+		$cur_date = '',
1988
+		$status = null,
1989
+		$evt_category = null,
1990
+		$evt_active_status = null
1991
+	) {
1992
+		// determine what post_status our condition will have for the query.
1993
+		// phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
1994
+		switch ($status) {
1995
+			case 'month':
1996
+			case 'today':
1997
+			case null:
1998
+			case 'all':
1999
+				$where['Event.status'] = ['NOT IN', ['trash']];
2000
+				break;
2001
+			case 'draft':
2002
+				$where['Event.status'] = ['IN', ['draft', 'auto-draft']];
2003
+				break;
2004
+			default:
2005
+				$where['Event.status'] = $status;
2006
+		}
2007
+
2008
+		// phpcs:enable
2009
+
2010
+		// categories?
2011
+
2012
+
2013
+		if (! empty($evt_category)) {
2014
+			$where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
2015
+			$where['Event.Term_Taxonomy.term_id']  = $evt_category;
2016
+		}
2017
+
2018
+
2019
+		//      $where['DTT_is_primary'] = 1;
2020
+
2021
+		$DTTS = EEM_Datetime::instance()->get_dtt_months_and_years($where, $evt_active_status);
2022
+
2023
+		// let's setup vals for select input helper
2024
+		$options = [
2025
+			0 => [
2026
+				'text' => esc_html__('Select a Month/Year', 'event_espresso'),
2027
+				'id'   => "",
2028
+			],
2029
+		];
2030
+
2031
+
2032
+		// translate month and date
2033
+		global $wp_locale;
2034
+
2035
+		foreach ($DTTS as $DTT) {
2036
+			$localized_date = $wp_locale->get_month($DTT->dtt_month_num) . ' ' . $DTT->dtt_year;
2037
+			$id             = $DTT->dtt_month . ' ' . $DTT->dtt_year;
2038
+			$options[]      = [
2039
+				'text' => $localized_date,
2040
+				'id'   => $id,
2041
+			];
2042
+		}
2043
+
2044
+
2045
+		return self::select_input('month_range', $options, $cur_date);
2046
+	}
2047
+
2048
+
2049
+	/**
2050
+	 * generates the dropdown selector for event categories
2051
+	 * typically used as a filter on list tables.
2052
+	 *
2053
+	 * @param integer $current_cat currently selected category
2054
+	 * @return string               html for dropdown
2055
+	 * @throws EE_Error
2056
+	 * @throws ReflectionException
2057
+	 */
2058
+	public static function generate_event_category_dropdown($current_cat = -1)
2059
+	{
2060
+		$categories = EEM_Term::instance()->get_all_ee_categories(true);
2061
+		$options    = [
2062
+			'0' => [
2063
+				'text' => esc_html__('All Categories', 'event_espresso'),
2064
+				'id'   => -1,
2065
+			],
2066
+		];
2067
+
2068
+		// setup categories for dropdown
2069
+		foreach ($categories as $category) {
2070
+			$options[] = [
2071
+				'text' => $category->get('name'),
2072
+				'id'   => $category->ID(),
2073
+			];
2074
+		}
2075
+
2076
+		return self::select_input('EVT_CAT', $options, $current_cat);
2077
+	}
2078
+
2079
+
2080
+	/**
2081
+	 *    generate a submit button with or without it's own microform
2082
+	 *    this is the only way to create buttons that are compatible across all themes
2083
+	 *
2084
+	 * @access    public
2085
+	 * @param string      $url              - the form action
2086
+	 * @param string      $ID               - some kind of unique ID, appended with "-sbmt" for the input and "-frm"
2087
+	 *                                      for the form
2088
+	 * @param string      $class            - css classes (separated by spaces if more than one)
2089
+	 * @param string      $text             - what appears on the button
2090
+	 * @param string      $nonce_action     - if using nonces
2091
+	 * @param bool|string $input_only       - whether to print form header and footer. TRUE returns the input without
2092
+	 *                                      the form
2093
+	 * @param string      $extra_attributes - any extra attributes that need to be attached to the form input
2094
+	 * @return    string
2095
+	 */
2096
+	public static function submit_button(
2097
+		$url = '',
2098
+		$ID = '',
2099
+		$class = '',
2100
+		$text = '',
2101
+		$nonce_action = '',
2102
+		$input_only = false,
2103
+		$extra_attributes = ''
2104
+	) {
2105
+		$btn = '';
2106
+		if (empty($url) || empty($ID)) {
2107
+			return $btn;
2108
+		}
2109
+		$text = ! empty($text) ? $text : esc_html__('Submit', 'event_espresso');
2110
+		$btn  .= '<input id="' . $ID . '-btn" class="' . $class . '" '
2111
+				 . 'type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
2112
+		if (! $input_only) {
2113
+			$btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
2114
+			$btn_frm .= ! empty($nonce_action)
2115
+				? wp_nonce_field($nonce_action, $nonce_action . '_nonce', true, false)
2116
+				: '';
2117
+			$btn_frm .= $btn;
2118
+			$btn_frm .= '</form>';
2119
+			$btn     = $btn_frm;
2120
+			unset($btn_frm);
2121
+		}
2122
+		return $btn;
2123
+	}
2124 2124
 }
Please login to merge, or discard this patch.
Spacing   +136 added lines, -136 removed lines patch added patch discarded remove patch
@@ -108,8 +108,8 @@  discard block
 block discarded – undo
108 108
             $type           = $input_value['input'];
109 109
             $value          = $input_value['value'];
110 110
 
111
-            $id    = $form_id ? $form_id . '-' . $input_key : $input_key;
112
-            $class = $required ? 'required ' . $css_class : $css_class;
111
+            $id    = $form_id ? $form_id.'-'.$input_key : $input_key;
112
+            $class = $required ? 'required '.$css_class : $css_class;
113 113
 
114 114
             // what type of input are we dealing with ?
115 115
             switch ($type) {
@@ -161,8 +161,8 @@  discard block
 block discarded – undo
161 161
             }
162 162
         } // end foreach( $input_vars as $input_key => $input_value )
163 163
 
164
-        if (! empty($inputs)) {
165
-            $glue   = "
164
+        if ( ! empty($inputs)) {
165
+            $glue = "
166 166
                 </li>
167 167
                 <li>
168 168
                     ";
@@ -175,7 +175,7 @@  discard block
 block discarded – undo
175 175
             </ul>
176 176
             ";
177 177
         }
178
-        return $output . implode("\n", $hidden_inputs);
178
+        return $output.implode("\n", $hidden_inputs);
179 179
     }
180 180
 
181 181
 
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
             // generate label
257 257
             $label = ! empty($label) ? self::adminLabel($id, $label, $required) : '';
258 258
             // generate field name
259
-            $name = ! empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
259
+            $name = ! empty($unique_id) ? $field_name.'['.$unique_id.']' : $field_name;
260 260
 
261 261
             // we determine what we're building based on the type
262 262
             switch ($type) {
@@ -267,14 +267,14 @@  discard block
 block discarded – undo
267 267
                         foreach ($value as $key => $val) {
268 268
                             $c_input .= self::adminMulti(
269 269
                                 $default,
270
-                                isset($classes[ $key ]) ? $classes[ $key ] : '',
271
-                                $field_name . '_' . $value,
270
+                                isset($classes[$key]) ? $classes[$key] : '',
271
+                                $field_name.'_'.$value,
272 272
                                 $name,
273 273
                                 $required,
274 274
                                 $tab_index,
275 275
                                 $type,
276 276
                                 $val,
277
-                                isset($labels[ $key ]) ? $labels[ $key ] : ''
277
+                                isset($labels[$key]) ? $labels[$key] : ''
278 278
                             );
279 279
                         }
280 280
                         $field = $c_input;
@@ -300,7 +300,7 @@  discard block
 block discarded – undo
300 300
                 case 'select':
301 301
                     $options = [];
302 302
                     foreach ($value as $key => $val) {
303
-                        $options[ $val ] = isset($labels[ $key ]) ? $labels[ $key ] : '';
303
+                        $options[$val] = isset($labels[$key]) ? $labels[$key] : '';
304 304
                     }
305 305
                     $field = self::adminSelect($default, $class, $id, $name, $required, $tab_index, $options);
306 306
                     break;
@@ -326,7 +326,7 @@  discard block
 block discarded – undo
326 326
                     $field = self::adminText($class, $id, $name, $required, $tab_index, $value);
327 327
             }
328 328
 
329
-            $form_fields[ $field_name ] = ['label' => $label, 'field' => $field . $extra_desc];
329
+            $form_fields[$field_name] = ['label' => $label, 'field' => $field.$extra_desc];
330 330
         }
331 331
 
332 332
         return $form_fields;
@@ -395,7 +395,7 @@  discard block
 block discarded – undo
395 395
         }
396 396
         $label = esc_html($label);
397 397
         $label_class = self::appendInputSizeClass('', $label);
398
-        $label_class = $label_class ? ' class="' . $label_class . '"' : '';
398
+        $label_class = $label_class ? ' class="'.$label_class.'"' : '';
399 399
         return "
400 400
         <label for='$id'{$label_class}>
401 401
             {$input}
@@ -544,7 +544,7 @@  discard block
 block discarded – undo
544 544
         $autosize = true
545 545
     ) {
546 546
         // if $values was submitted in the wrong format, convert it over
547
-        if (! empty($values) && (! array_key_exists(0, $values) || ! is_array($values[0]))) {
547
+        if ( ! empty($values) && ( ! array_key_exists(0, $values) || ! is_array($values[0]))) {
548 548
             $converted_values = [];
549 549
             foreach ($values as $id => $text) {
550 550
                 $converted_values[] = ['id' => $id, 'text' => $text];
@@ -553,19 +553,19 @@  discard block
 block discarded – undo
553 553
         }
554 554
 
555 555
         $field =
556
-            '<select id="' . EEH_Formatter::ee_tep_output_string($name)
557
-            . '" name="' . EEH_Formatter::ee_tep_output_string($name)
556
+            '<select id="'.EEH_Formatter::ee_tep_output_string($name)
557
+            . '" name="'.EEH_Formatter::ee_tep_output_string($name)
558 558
             . '"';
559 559
 
560 560
         if (EEH_Formatter::ee_tep_not_null($parameters)) {
561
-            $field .= ' ' . $parameters;
561
+            $field .= ' '.$parameters;
562 562
         }
563 563
         $class = $autosize ? self::appendInputSizeClass($class, $values) : '';
564 564
 
565
-        $field .= ' class="' . $class . '">';
565
+        $field .= ' class="'.$class.'">';
566 566
 
567
-        if (empty($default) && isset($GLOBALS[ $name ])) {
568
-            $default = stripslashes($GLOBALS[ $name ]);
567
+        if (empty($default) && isset($GLOBALS[$name])) {
568
+            $default = stripslashes($GLOBALS[$name]);
569 569
         }
570 570
 
571 571
         $field .= self::selectInputOption($values, $default);
@@ -581,7 +581,7 @@  discard block
 block discarded – undo
581 581
             $id = is_scalar($values['id']) ? $values['id'] : '';
582 582
             $text = is_scalar($values['text']) ? $values['text'] : '';
583 583
             $selected = $default == $values['id'] ? ' selected = "selected"' : '';
584
-            $html_class = isset($values['class']) ? ' class="' . $values['class'] . '"' : '';
584
+            $html_class = isset($values['class']) ? ' class="'.$values['class'].'"' : '';
585 585
             return "<option value='{$id}'{$selected}{$html_class}>{$text}</option>";
586 586
         }
587 587
         $options = '';
@@ -611,7 +611,7 @@  discard block
 block discarded – undo
611 611
             return $chars;
612 612
         }
613 613
         // not a primitive? return something big
614
-        if (! is_scalar($value)) {
614
+        if ( ! is_scalar($value)) {
615 615
             return 500;
616 616
         }
617 617
         return strlen((string) $value);
@@ -661,11 +661,11 @@  discard block
 block discarded – undo
661 661
         $after_question_group_questions  =
662 662
             apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
663 663
 
664
-        if (! empty($question_groups)) {
664
+        if ( ! empty($question_groups)) {
665 665
             // loop thru question groups
666 666
             foreach ($question_groups as $QSG) {
667 667
                 // check that questions exist
668
-                if (! empty($QSG['QSG_questions'])) {
668
+                if ( ! empty($QSG['QSG_questions'])) {
669 669
                     // use fieldsets
670 670
                     $html .= "\n\t"
671 671
                              . '<'
@@ -690,7 +690,7 @@  discard block
 block discarded – undo
690 690
                     $html .= $before_question_group_questions;
691 691
                     // loop thru questions
692 692
                     foreach ($QSG['QSG_questions'] as $question) {
693
-                        $QFI  = new EE_Question_Form_Input(
693
+                        $QFI = new EE_Question_Form_Input(
694 694
                             $question['qst_obj'],
695 695
                             $question['ans_obj'],
696 696
                             $question
@@ -698,7 +698,7 @@  discard block
 block discarded – undo
698 698
                         $html .= self::generate_form_input($QFI);
699 699
                     }
700 700
                     $html .= $after_question_group_questions;
701
-                    $html .= "\n\t" . '</' . $group_wrapper . '>';
701
+                    $html .= "\n\t".'</'.$group_wrapper.'>';
702 702
                 }
703 703
             }
704 704
         }
@@ -738,25 +738,25 @@  discard block
 block discarded – undo
738 738
             'input_id'    => '',
739 739
             'input_class' => '',
740 740
         ];
741
-        $q_meta         = array_merge($default_q_meta, $q_meta);
741
+        $q_meta = array_merge($default_q_meta, $q_meta);
742 742
 
743
-        if (! empty($question_groups)) {
743
+        if ( ! empty($question_groups)) {
744 744
             // loop thru question groups
745 745
             foreach ($question_groups as $QSG) {
746 746
                 if ($QSG instanceof EE_Question_Group) {
747 747
                     // check that questions exist
748 748
 
749 749
                     $where = ['QST_deleted' => 0];
750
-                    if (! $from_admin) {
750
+                    if ( ! $from_admin) {
751 751
                         $where['QST_admin_only'] = 0;
752 752
                     }
753 753
                     $questions =
754 754
                         $QSG->questions([$where, 'order_by' => ['Question_Group_Question.QGQ_order' => 'ASC']]);
755
-                    if (! empty($questions)) {
755
+                    if ( ! empty($questions)) {
756 756
                         // use fieldsets
757 757
                         $html .= "\n\t"
758
-                                 . '<' . $group_wrapper . ' class="espresso-question-group-wrap" '
759
-                                 . 'id="' . $QSG->get('QSG_identifier') . '">';
758
+                                 . '<'.$group_wrapper.' class="espresso-question-group-wrap" '
759
+                                 . 'id="'.$QSG->get('QSG_identifier').'">';
760 760
                         // group_name
761 761
                         if ($QSG->show_group_name()) {
762 762
                             $html .= "\n\t\t"
@@ -781,21 +781,21 @@  discard block
 block discarded – undo
781 781
                             /** @var RequestInterface $request */
782 782
                             $request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
783 783
                             $request_qstn = $request->getRequestParam('qstn', [], 'string', true);
784
-                            if (! empty($request_qstn) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
784
+                            if ( ! empty($request_qstn) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
785 785
                                 // check for answer in $request_qstn in case we are reprocessing a form after an error
786
-                                if (isset($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])) {
787
-                                    $answer = is_array($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])
788
-                                        ? $request_qstn[ $q_meta['input_id'] ][ $qstn_id ]
789
-                                        : sanitize_text_field($request_qstn[ $q_meta['input_id'] ][ $qstn_id ]);
786
+                                if (isset($request_qstn[$q_meta['input_id']][$qstn_id])) {
787
+                                    $answer = is_array($request_qstn[$q_meta['input_id']][$qstn_id])
788
+                                        ? $request_qstn[$q_meta['input_id']][$qstn_id]
789
+                                        : sanitize_text_field($request_qstn[$q_meta['input_id']][$qstn_id]);
790 790
                                 }
791 791
                             } elseif (isset($q_meta['attendee']) && $q_meta['attendee']) {
792 792
                                 // attendee data from the session
793 793
                                 $answer =
794
-                                    isset($q_meta['attendee'][ $qstn_id ]) ? $q_meta['attendee'][ $qstn_id ] : null;
794
+                                    isset($q_meta['attendee'][$qstn_id]) ? $q_meta['attendee'][$qstn_id] : null;
795 795
                             }
796 796
 
797 797
 
798
-                            $QFI  = new EE_Question_Form_Input(
798
+                            $QFI = new EE_Question_Form_Input(
799 799
                                 $QST,
800 800
                                 EE_Answer::new_instance(
801 801
                                     [
@@ -810,7 +810,7 @@  discard block
 block discarded – undo
810 810
                             $html .= self::generate_form_input($QFI);
811 811
                         }
812 812
                         $html .= $after_question_group_questions;
813
-                        $html .= "\n\t" . '</' . $group_wrapper . '>';
813
+                        $html .= "\n\t".'</'.$group_wrapper.'>';
814 814
                     }
815 815
                 }
816 816
             }
@@ -858,7 +858,7 @@  discard block
 block discarded – undo
858 858
             $QFI->get('QST_required_text') != ''
859 859
                 ? $QFI->get('QST_required_text')
860 860
                 : esc_html__('This field is required', 'event_espresso');
861
-        $required_text     = $QST_required
861
+        $required_text = $QST_required
862 862
             ? "\n\t\t\t"
863 863
               . '<div class="required-text hidden">'
864 864
               . self::prep_answer($required_text, $use_html_entities)
@@ -994,7 +994,7 @@  discard block
 block discarded – undo
994 994
     ): string {
995 995
         $for   = ! empty($name) ? " for='{$name}'" : '';
996 996
         $class = ! empty($label_class) ? " class='{$label_class}'" : '';
997
-        $label = self::prep_question($question) . $required_label;
997
+        $label = self::prep_question($question).$required_label;
998 998
         $label_html = "
999 999
             {$required_text}
1000 1000
             <label{$for}{$class}>{$label}</label>";
@@ -1049,7 +1049,7 @@  discard block
 block discarded – undo
1049 1049
         $add_mobile_label = false
1050 1050
     ) {
1051 1051
         // need these
1052
-        if (! $question || ! $name) {
1052
+        if ( ! $question || ! $name) {
1053 1053
             return null;
1054 1054
         }
1055 1055
         // prep the answer
@@ -1061,10 +1061,10 @@  discard block
 block discarded – undo
1061 1061
         // ya gots ta have style man!!!
1062 1062
         $txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
1063 1063
         $class     = empty($class) ? $txt_class : $class;
1064
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1064
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
1065 1065
         $class = self::appendInputSizeClass($class, $answer);
1066
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1067
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1066
+        $class .= ! empty($required['class']) ? ' '.$required['class'] : '';
1067
+        $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1068 1068
 
1069 1069
         $label_html = self::label($question, $required_text, $required['label'], $name, $label_class);
1070 1070
         $mobile_label = self::mobileLabel(
@@ -1076,18 +1076,18 @@  discard block
 block discarded – undo
1076 1076
             $name
1077 1077
         );
1078 1078
 
1079
-        $input_html = $mobile_label . '
1079
+        $input_html = $mobile_label.'
1080 1080
             <input  type="text"
1081
-                    name="' . $name . '"
1082
-                    id="' . $id . '"
1083
-                    class="' . trim($class) . '"
1084
-                    value="' . esc_attr($answer) . '"
1085
-                    aria-label="' . esc_attr($required['msg']) . '"
1086
-                    ' . $disabled . ' ' . $extra . '
1081
+                    name="' . $name.'"
1082
+                    id="' . $id.'"
1083
+                    class="' . trim($class).'"
1084
+                    value="' . esc_attr($answer).'"
1085
+                    aria-label="' . esc_attr($required['msg']).'"
1086
+                    ' . $disabled.' '.$extra.'
1087 1087
             />';
1088 1088
 
1089 1089
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1090
-        return $label_html . $input_html;
1090
+        return $label_html.$input_html;
1091 1091
     }
1092 1092
 
1093 1093
 
@@ -1122,7 +1122,7 @@  discard block
 block discarded – undo
1122 1122
         $add_mobile_label = false
1123 1123
     ) {
1124 1124
         // need these
1125
-        if (! $question || ! $name) {
1125
+        if ( ! $question || ! $name) {
1126 1126
             return null;
1127 1127
         }
1128 1128
         // prep the answer
@@ -1136,9 +1136,9 @@  discard block
 block discarded – undo
1136 1136
         // set disabled tag
1137 1137
         $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1138 1138
         // ya gots ta have style man!!!
1139
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1140
-        $class     .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1141
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1139
+        $class     .= ! empty($system_ID) ? ' '.$system_ID : '';
1140
+        $class     .= ! empty($required['class']) ? ' '.$required['class'] : '';
1141
+        $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1142 1142
 
1143 1143
         $label_html   = self::label($question, $required_text, $required['label'], $name, $label_class);
1144 1144
         $mobile_label = self::mobileLabel(
@@ -1151,14 +1151,14 @@  discard block
 block discarded – undo
1151 1151
         );
1152 1152
 
1153 1153
         $input_html = $mobile_label
1154
-            . '<textarea name="' . $name . '" id="' . $id . '" class="' . trim($class) . '" '
1155
-            . 'rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  '
1156
-            . 'aria-label="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>'
1154
+            . '<textarea name="'.$name.'" id="'.$id.'" class="'.trim($class).'" '
1155
+            . 'rows="'.$dimensions['rows'].'" cols="'.$dimensions['cols'].'"  '
1156
+            . 'aria-label="'.$required['msg'].'" '.$disabled.' '.$extra.'>'
1157 1157
              . esc_textarea($answer)
1158 1158
               . '</textarea>';
1159 1159
 
1160 1160
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1161
-        return $label_html . $input_html;
1161
+        return $label_html.$input_html;
1162 1162
     }
1163 1163
 
1164 1164
 
@@ -1196,7 +1196,7 @@  discard block
 block discarded – undo
1196 1196
     ) {
1197 1197
 
1198 1198
         // need these
1199
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1199
+        if ( ! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1200 1200
             return null;
1201 1201
         }
1202 1202
         // prep the answer
@@ -1208,9 +1208,9 @@  discard block
 block discarded – undo
1208 1208
         // set disabled tag
1209 1209
         $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1210 1210
         // ya gots ta have style man!!!
1211
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1211
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
1212 1212
         $class = self::appendInputSizeClass($class, $options);
1213
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1213
+        $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1214 1214
 
1215 1215
         $label_html   = self::label($question, $required_text, $required['label'], $name, $label_class);
1216 1216
         $mobile_label = self::mobileLabel(
@@ -1223,16 +1223,16 @@  discard block
 block discarded – undo
1223 1223
         );
1224 1224
 
1225 1225
         $input_html = $mobile_label
1226
-            . '<select name="' . $name . '" id="' . $id . '" class="' . trim($class) . ' ' . $required['class'] . '" '
1227
-            . 'aria-label="' . esc_attr($required['msg']) . '"' . $disabled . ' ' . $extra . '>';
1226
+            . '<select name="'.$name.'" id="'.$id.'" class="'.trim($class).' '.$required['class'].'" '
1227
+            . 'aria-label="'.esc_attr($required['msg']).'"'.$disabled.' '.$extra.'>';
1228 1228
         // recursively count array elements, to determine total number of options
1229 1229
         $only_option = count($options, 1) == 1;
1230
-        if (! $only_option) {
1230
+        if ( ! $only_option) {
1231 1231
             // if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
1232
-            $selected   = $answer === null ? ' selected' : '';
1232
+            $selected = $answer === null ? ' selected' : '';
1233 1233
             $input_html .= $add_please_select_option
1234 1234
                 ? "\n\t\t\t\t"
1235
-                  . '<option value=""' . $selected . '>'
1235
+                  . '<option value=""'.$selected.'>'
1236 1236
                   . esc_html__(' - please select - ', 'event_espresso')
1237 1237
                   . '</option>'
1238 1238
                 : '';
@@ -1255,7 +1255,7 @@  discard block
 block discarded – undo
1255 1255
                 );
1256 1256
         }
1257 1257
 
1258
-        $input_html .= "\n\t\t\t" . '</select>';
1258
+        $input_html .= "\n\t\t\t".'</select>';
1259 1259
 
1260 1260
         $input_html =
1261 1261
             apply_filters(
@@ -1270,7 +1270,7 @@  discard block
 block discarded – undo
1270 1270
             );
1271 1271
 
1272 1272
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1273
-        return $label_html . $input_html;
1273
+        return $label_html.$input_html;
1274 1274
     }
1275 1275
 
1276 1276
 
@@ -1288,11 +1288,11 @@  discard block
 block discarded – undo
1288 1288
      */
1289 1289
     private static function _generate_select_option_group($opt_group, $QSOs, $answer, $use_html_entities = true)
1290 1290
     {
1291
-        $html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value($opt_group) . '">';
1291
+        $html = "\n\t\t\t\t".'<optgroup label="'.self::prep_option_value($opt_group).'">';
1292 1292
         foreach ($QSOs as $QSO) {
1293 1293
             $html .= self::_generate_select_option($QSO->value(), $QSO->desc(), $answer, false, $use_html_entities);
1294 1294
         }
1295
-        $html .= "\n\t\t\t\t" . '</optgroup>';
1295
+        $html .= "\n\t\t\t\t".'</optgroup>';
1296 1296
         return $html;
1297 1297
     }
1298 1298
 
@@ -1319,7 +1319,7 @@  discard block
 block discarded – undo
1319 1319
         $value    = ! empty($value) ? $value : $key;
1320 1320
         $selected = ($answer == $key || $only_option) ? 'selected' : '';
1321 1321
         return "\n\t\t\t\t"
1322
-               . '<option value="' . self::prep_option_value($key) . '" ' . $selected . '> '
1322
+               . '<option value="'.self::prep_option_value($key).'" '.$selected.'> '
1323 1323
                . $value
1324 1324
                . '&nbsp;&nbsp;&nbsp;</option>';
1325 1325
     }
@@ -1364,7 +1364,7 @@  discard block
 block discarded – undo
1364 1364
         $add_mobile_label = false
1365 1365
     ) {
1366 1366
         // need these
1367
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1367
+        if ( ! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1368 1368
             return null;
1369 1369
         }
1370 1370
         // prep the answer
@@ -1388,49 +1388,49 @@  discard block
 block discarded – undo
1388 1388
         );
1389 1389
 
1390 1390
         $input_html = $mobile_label
1391
-            . '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $class . '-ul">';
1391
+            . '<ul id="'.$id.'-ul" class="espresso-radio-btn-options-ul '.$class.'-ul">';
1392 1392
 
1393
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1394
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1393
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
1394
+        $class .= ! empty($required['class']) ? ' '.$required['class'] : '';
1395 1395
 
1396 1396
         foreach ($options as $OPT) {
1397 1397
             if ($OPT instanceof EE_Question_Option) {
1398 1398
                 $value   = self::prep_option_value($OPT->value());
1399 1399
                 $label   = $use_desc_4_label ? $OPT->desc() : $OPT->value();
1400 1400
                 $size    = $use_desc_4_label
1401
-                    ? self::get_label_size_class($OPT->value() . ' ' . $OPT->desc())
1401
+                    ? self::get_label_size_class($OPT->value().' '.$OPT->desc())
1402 1402
                     : self::get_label_size_class($OPT->value());
1403
-                $desc    = $OPT->desc();// no self::prep_answer
1403
+                $desc    = $OPT->desc(); // no self::prep_answer
1404 1404
                 $answer  = is_numeric($value) && empty($answer) ? 0 : $answer;
1405 1405
                 $checked = (string) $value == (string) $answer ? ' checked' : '';
1406
-                $opt     = '-' . sanitize_key($value);
1406
+                $opt     = '-'.sanitize_key($value);
1407 1407
 
1408
-                $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1409
-                $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
1410
-                $input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>&nbsp;&nbsp;' : '';
1408
+                $input_html .= "\n\t\t\t\t".'<li'.$size.'>';
1409
+                $input_html .= "\n\t\t\t\t\t".'<label class="'.$radio_class.' espresso-radio-btn-lbl">';
1410
+                $input_html .= $label_b4 ? "\n\t\t\t\t\t\t".'<span>'.$label.'</span>&nbsp;&nbsp;' : '';
1411 1411
                 $input_html .= "\n\t\t\t\t\t\t"
1412
-                               . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" '
1413
-                               . 'class="' . $class . '" value="' . $value . '" '
1414
-                               . 'aria-label="' . esc_attr($required['msg']) . '" ' . $disabled
1415
-                               . $checked . ' ' . $extra . '/>';
1412
+                               . '<input type="radio" name="'.$name.'" id="'.$id.$opt.'" '
1413
+                               . 'class="'.$class.'" value="'.$value.'" '
1414
+                               . 'aria-label="'.esc_attr($required['msg']).'" '.$disabled
1415
+                               . $checked.' '.$extra.'/>';
1416 1416
                 $input_html .= ! $label_b4
1417 1417
                     ? "\n\t\t\t\t\t\t"
1418 1418
                       . '&nbsp;&nbsp;<span class="espresso-radio-btn-desc">'
1419 1419
                       . $label
1420 1420
                       . '</span>'
1421 1421
                     : '';
1422
-                $input_html .= "\n\t\t\t\t\t" . '</label>';
1422
+                $input_html .= "\n\t\t\t\t\t".'</label>';
1423 1423
                 $input_html .= $use_desc_4_label
1424 1424
                     ? ''
1425
-                    : '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
1426
-                $input_html .= "\n\t\t\t\t" . '</li>';
1425
+                    : '<span class="espresso-radio-btn-option-desc small-text grey-text">'.$desc.'</span>';
1426
+                $input_html .= "\n\t\t\t\t".'</li>';
1427 1427
             }
1428 1428
         }
1429 1429
 
1430
-        $input_html .= "\n\t\t\t" . '</ul>';
1430
+        $input_html .= "\n\t\t\t".'</ul>';
1431 1431
 
1432 1432
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1433
-        return $label_html . $input_html;
1433
+        return $label_html.$input_html;
1434 1434
     }
1435 1435
 
1436 1436
 
@@ -1466,7 +1466,7 @@  discard block
 block discarded – undo
1466 1466
         $add_mobile_label = false
1467 1467
     ) {
1468 1468
         // need these
1469
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1469
+        if ( ! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1470 1470
             return null;
1471 1471
         }
1472 1472
         $answer = maybe_unserialize($answer);
@@ -1476,7 +1476,7 @@  discard block
 block discarded – undo
1476 1476
 
1477 1477
         foreach ($answer as $key => $value) {
1478 1478
             $key            = self::prep_option_value($key);
1479
-            $answer[ $key ] = self::prep_answer($value, $use_html_entities);
1479
+            $answer[$key] = self::prep_answer($value, $use_html_entities);
1480 1480
         }
1481 1481
 
1482 1482
         // prep the required array
@@ -1498,42 +1498,42 @@  discard block
 block discarded – undo
1498 1498
         );
1499 1499
 
1500 1500
         $input_html = $mobile_label
1501
-            . '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $class . '-ul">';
1501
+            . '<ul id="'.$id.'-ul" class="espresso-checkbox-options-ul '.$class.'-ul">';
1502 1502
 
1503
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1504
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1503
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
1504
+        $class .= ! empty($required['class']) ? ' '.$required['class'] : '';
1505 1505
 
1506 1506
         foreach ($options as $OPT) {
1507
-            $value = $OPT->value();// self::prep_option_value( $OPT->value() );
1508
-            $size  = self::get_label_size_class($OPT->value() . ' ' . $OPT->desc());
1507
+            $value = $OPT->value(); // self::prep_option_value( $OPT->value() );
1508
+            $size  = self::get_label_size_class($OPT->value().' '.$OPT->desc());
1509 1509
             $text  = self::prep_answer($OPT->value());
1510 1510
             $desc  = $OPT->desc();
1511
-            $opt   = '-' . sanitize_key($value);
1511
+            $opt   = '-'.sanitize_key($value);
1512 1512
 
1513 1513
             $checked = is_array($answer) && in_array($text, $answer) ? ' checked' : '';
1514 1514
 
1515
-            $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1516
-            $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
1517
-            $input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>&nbsp;&nbsp;' : '';
1515
+            $input_html .= "\n\t\t\t\t".'<li'.$size.'>';
1516
+            $input_html .= "\n\t\t\t\t\t".'<label class="'.$radio_class.' espresso-checkbox-lbl">';
1517
+            $input_html .= $label_b4 ? "\n\t\t\t\t\t\t".'<span>'.$text.'</span>&nbsp;&nbsp;' : '';
1518 1518
             $input_html .= "\n\t\t\t\t\t\t"
1519
-                           . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" '
1520
-                           . 'id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" '
1521
-                           . 'aria-label="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
1522
-            $input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t" . '&nbsp;&nbsp;<span>' . $text . '</span>' : '';
1523
-            $input_html .= "\n\t\t\t\t\t" . '</label>';
1524
-            if (! empty($desc) && $desc != $text) {
1519
+                           . '<input type="checkbox" name="'.$name.'['.$OPT->ID().']" '
1520
+                           . 'id="'.$id.$opt.'" class="'.$class.'" value="'.$value.'" '
1521
+                           . 'aria-label="'.esc_attr($required['msg']).'" '.$disabled.$checked.' '.$extra.'/>';
1522
+            $input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t".'&nbsp;&nbsp;<span>'.$text.'</span>' : '';
1523
+            $input_html .= "\n\t\t\t\t\t".'</label>';
1524
+            if ( ! empty($desc) && $desc != $text) {
1525 1525
                 $input_html .= "\n\t\t\t\t\t"
1526 1526
                                . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">'
1527 1527
                                . $desc
1528 1528
                                . '</div>';
1529 1529
             }
1530
-            $input_html .= "\n\t\t\t\t" . '</li>';
1530
+            $input_html .= "\n\t\t\t\t".'</li>';
1531 1531
         }
1532 1532
 
1533
-        $input_html .= "\n\t\t\t" . '</ul>';
1533
+        $input_html .= "\n\t\t\t".'</ul>';
1534 1534
 
1535 1535
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1536
-        return $label_html . $input_html;
1536
+        return $label_html.$input_html;
1537 1537
     }
1538 1538
 
1539 1539
 
@@ -1566,7 +1566,7 @@  discard block
 block discarded – undo
1566 1566
         $add_mobile_label = false
1567 1567
     ) {
1568 1568
         // need these
1569
-        if (! $question || ! $name) {
1569
+        if ( ! $question || ! $name) {
1570 1570
             return null;
1571 1571
         }
1572 1572
         // prep the answer
@@ -1578,7 +1578,7 @@  discard block
 block discarded – undo
1578 1578
         // ya gots ta have style man!!!
1579 1579
         $txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1580 1580
         $class     = empty($class) ? $txt_class : $class;
1581
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1581
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
1582 1582
         $class = self::appendInputSizeClass($class, $answer);
1583 1583
         $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1584 1584
 
@@ -1593,14 +1593,14 @@  discard block
 block discarded – undo
1593 1593
         );
1594 1594
 
1595 1595
         $input_html = $mobile_label
1596
-            . '<input type="text" name="' . $name . '" id="' . $id . '" '
1597
-            . 'class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  '
1598
-            . 'aria-label="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
1596
+            . '<input type="text" name="'.$name.'" id="'.$id.'" '
1597
+            . 'class="'.$class.' '.$required['class'].' datepicker" value="'.$answer.'"  '
1598
+            . 'aria-label="'.esc_attr($required['msg']).'" '.$disabled.' '.$extra.'/>';
1599 1599
 
1600 1600
         // enqueue scripts
1601 1601
         wp_register_style(
1602 1602
             'espresso-ui-theme',
1603
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1603
+            EE_GLOBAL_ASSETS_URL.'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1604 1604
             [],
1605 1605
             EVENT_ESPRESSO_VERSION
1606 1606
         );
@@ -1608,7 +1608,7 @@  discard block
 block discarded – undo
1608 1608
         wp_enqueue_script('jquery-ui-datepicker');
1609 1609
 
1610 1610
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1611
-        return $label_html . $input_html;
1611
+        return $label_html.$input_html;
1612 1612
     }
1613 1613
 
1614 1614
 
@@ -1635,7 +1635,7 @@  discard block
 block discarded – undo
1635 1635
     public static function hidden_input($name, $value, $id = '')
1636 1636
     {
1637 1637
         $id = ! empty($id) ? $id : $name;
1638
-        return '<input id="' . $id . '" type="hidden" name="' . $name . '" value="' . $value . '"/>';
1638
+        return '<input id="'.$id.'" type="hidden" name="'.$name.'" value="'.$value.'"/>';
1639 1639
     }
1640 1640
 
1641 1641
 
@@ -1680,7 +1680,7 @@  discard block
 block discarded – undo
1680 1680
         $prepped_answer_options = [];
1681 1681
         if (is_array($QSOs) && ! empty($QSOs)) {
1682 1682
             foreach ($QSOs as $key => $QSO) {
1683
-                if (! $QSO instanceof EE_Question_Option) {
1683
+                if ( ! $QSO instanceof EE_Question_Option) {
1684 1684
                     $QSO = EE_Question_Option::new_instance(
1685 1685
                         [
1686 1686
                             'QSO_value' => is_array($QSO) && isset($QSO['id'])
@@ -1693,7 +1693,7 @@  discard block
 block discarded – undo
1693 1693
                     );
1694 1694
                 }
1695 1695
                 if ($QSO->opt_group()) {
1696
-                    $prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
1696
+                    $prepped_answer_options[$QSO->opt_group()][] = $QSO;
1697 1697
                 } else {
1698 1698
                     $prepped_answer_options[] = $QSO;
1699 1699
                 }
@@ -1905,7 +1905,7 @@  discard block
 block discarded – undo
1905 1905
         $options = [];
1906 1906
         for ($x = 1; $x <= 12; $x++) {
1907 1907
             $mm             = str_pad($x, 2, '0', STR_PAD_LEFT);
1908
-            $options[ $mm ] = $mm;
1908
+            $options[$mm] = $mm;
1909 1909
         }
1910 1910
         return EEH_Form_Fields::prep_answer_options($options);
1911 1911
     }
@@ -1923,7 +1923,7 @@  discard block
 block discarded – undo
1923 1923
         $next_decade  = $current_year + 10;
1924 1924
         for ($x = $current_year; $x <= $next_decade; $x++) {
1925 1925
             $yy             = str_pad($x, 2, '0', STR_PAD_LEFT);
1926
-            $options[ $yy ] = $yy;
1926
+            $options[$yy] = $yy;
1927 1927
         }
1928 1928
         return EEH_Form_Fields::prep_answer_options($options);
1929 1929
     }
@@ -1942,7 +1942,7 @@  discard block
 block discarded – undo
1942 1942
     public static function generate_registration_months_dropdown($cur_date = '', $status = '', $evt_category = 0)
1943 1943
     {
1944 1944
         $_where = [];
1945
-        if (! empty($status)) {
1945
+        if ( ! empty($status)) {
1946 1946
             $_where['STS_ID'] = $status;
1947 1947
         }
1948 1948
 
@@ -1961,7 +1961,7 @@  discard block
 block discarded – undo
1961 1961
         ];
1962 1962
 
1963 1963
         foreach ($regdtts as $regdtt) {
1964
-            $date      = $regdtt->reg_month . ' ' . $regdtt->reg_year;
1964
+            $date      = $regdtt->reg_month.' '.$regdtt->reg_year;
1965 1965
             $options[] = [
1966 1966
                 'text' => $date,
1967 1967
                 'id'   => $date,
@@ -2010,7 +2010,7 @@  discard block
 block discarded – undo
2010 2010
         // categories?
2011 2011
 
2012 2012
 
2013
-        if (! empty($evt_category)) {
2013
+        if ( ! empty($evt_category)) {
2014 2014
             $where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
2015 2015
             $where['Event.Term_Taxonomy.term_id']  = $evt_category;
2016 2016
         }
@@ -2033,8 +2033,8 @@  discard block
 block discarded – undo
2033 2033
         global $wp_locale;
2034 2034
 
2035 2035
         foreach ($DTTS as $DTT) {
2036
-            $localized_date = $wp_locale->get_month($DTT->dtt_month_num) . ' ' . $DTT->dtt_year;
2037
-            $id             = $DTT->dtt_month . ' ' . $DTT->dtt_year;
2036
+            $localized_date = $wp_locale->get_month($DTT->dtt_month_num).' '.$DTT->dtt_year;
2037
+            $id             = $DTT->dtt_month.' '.$DTT->dtt_year;
2038 2038
             $options[]      = [
2039 2039
                 'text' => $localized_date,
2040 2040
                 'id'   => $id,
@@ -2107,16 +2107,16 @@  discard block
 block discarded – undo
2107 2107
             return $btn;
2108 2108
         }
2109 2109
         $text = ! empty($text) ? $text : esc_html__('Submit', 'event_espresso');
2110
-        $btn  .= '<input id="' . $ID . '-btn" class="' . $class . '" '
2111
-                 . 'type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
2112
-        if (! $input_only) {
2113
-            $btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
2110
+        $btn .= '<input id="'.$ID.'-btn" class="'.$class.'" '
2111
+                 . 'type="submit" value="'.$text.'" '.$extra_attributes.'/>';
2112
+        if ( ! $input_only) {
2113
+            $btn_frm = '<form id="'.$ID.'-frm" method="POST" action="'.$url.'">';
2114 2114
             $btn_frm .= ! empty($nonce_action)
2115
-                ? wp_nonce_field($nonce_action, $nonce_action . '_nonce', true, false)
2115
+                ? wp_nonce_field($nonce_action, $nonce_action.'_nonce', true, false)
2116 2116
                 : '';
2117 2117
             $btn_frm .= $btn;
2118 2118
             $btn_frm .= '</form>';
2119
-            $btn     = $btn_frm;
2119
+            $btn = $btn_frm;
2120 2120
             unset($btn_frm);
2121 2121
         }
2122 2122
         return $btn;
Please login to merge, or discard this patch.
core/helpers/EEH_Event_View.helper.php 1 patch
Indentation   +614 added lines, -614 removed lines patch added patch discarded remove patch
@@ -9,364 +9,364 @@  discard block
 block discarded – undo
9 9
  */
10 10
 class EEH_Event_View extends EEH_Base
11 11
 {
12
-    /**
13
-     * @var EE_Event $_event
14
-     */
15
-    private static $_event = null;
16
-
17
-
18
-    /**
19
-     * get_event
20
-     * attempts to retrieve an EE_Event object any way it can
21
-     *
22
-     * @param int|WP_Post $EVT_ID
23
-     * @return EE_Event|null
24
-     * @throws EE_Error
25
-     * @throws ReflectionException
26
-     */
27
-    public static function get_event($EVT_ID = 0)
28
-    {
29
-        // international newspaper?
30
-        global $post;
31
-        $EVT_ID = $EVT_ID instanceof WP_Post && $EVT_ID->post_type === 'espresso_events'
32
-            ? $EVT_ID->ID
33
-            : absint($EVT_ID);
34
-        // do we already have the Event  you are looking for?
35
-        if (EEH_Event_View::$_event instanceof EE_Event && $EVT_ID && EEH_Event_View::$_event->ID() === $EVT_ID) {
36
-            return EEH_Event_View::$_event;
37
-        }
38
-        // reset property so that the new event is cached.
39
-        EEH_Event_View::$_event = null;
40
-        if (! $EVT_ID && $post instanceof EE_Event) {
41
-            EEH_Event_View::$_event = $post;
42
-            return EEH_Event_View::$_event;
43
-        }
44
-        // if the post type is for an event and it has a cached event and we don't have a different incoming $EVT_ID
45
-        // then let's just use that cached event on the $post object.
46
-        if (
47
-            $post instanceof WP_Post
48
-            && $post->post_type === 'espresso_events'
49
-            && isset($post->EE_Event)
50
-            && (
51
-                $EVT_ID === 0
52
-                || $EVT_ID === $post->ID
53
-            )
54
-        ) {
55
-            EEH_Event_View::$_event = $post->EE_Event;
56
-            return EEH_Event_View::$_event;
57
-        }
58
-        // If the event we have isn't an event but we do have an EVT_ID, let's try getting the event using the ID.
59
-        if (! EEH_Event_View::$_event instanceof EE_Event && $EVT_ID) {
60
-            EEH_Event_View::$_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
61
-        }
62
-        return EEH_Event_View::$_event;
63
-    }
64
-
65
-
66
-    /**
67
-     *    display_ticket_selector
68
-     *
69
-     * @param int $EVT_ID
70
-     * @return    boolean
71
-     * @throws EE_Error
72
-     * @throws EE_Error
73
-     * @throws ReflectionException
74
-     */
75
-    public static function display_ticket_selector($EVT_ID = 0)
76
-    {
77
-        $event = EEH_Event_View::get_event($EVT_ID);
78
-        return $event instanceof EE_Event && $event->display_ticket_selector();
79
-    }
80
-
81
-
82
-    /**
83
-     *    event_status
84
-     *
85
-     * @param int $EVT_ID
86
-     * @return    string
87
-     * @throws EE_Error
88
-     * @throws EE_Error
89
-     * @throws ReflectionException
90
-     */
91
-    public static function event_status($EVT_ID = 0)
92
-    {
93
-        $event = EEH_Event_View::get_event($EVT_ID);
94
-        return $event instanceof EE_Event ? $event->pretty_active_status(false) : '';
95
-    }
96
-
97
-
98
-    /**
99
-     *  event_active_status
100
-     *
101
-     * @param int $EVT_ID
102
-     * @return     string
103
-     * @throws EE_Error
104
-     * @throws EE_Error
105
-     * @throws ReflectionException
106
-     */
107
-    public static function event_active_status($EVT_ID = 0, $echo = true)
108
-    {
109
-        $event = EEH_Event_View::get_event($EVT_ID);
110
-        return $event instanceof EE_Event ? $event->pretty_active_status($echo) : 'inactive';
111
-    }
112
-
113
-
114
-    /**
115
-     *  event_has_content_or_excerpt
116
-     *
117
-     * @param int $EVT_ID
118
-     * @return     bool
119
-     * @throws EE_Error
120
-     * @throws EE_Error
121
-     * @throws ReflectionException
122
-     */
123
-    public static function event_has_content_or_excerpt($EVT_ID = 0)
124
-    {
125
-        $event                  = EEH_Event_View::get_event($EVT_ID);
126
-        $has_content_or_excerpt = false;
127
-        if ($event instanceof EE_Event) {
128
-            $has_content_or_excerpt = $event->description() != '' || $event->short_description(null, null, true) != '';
129
-        }
130
-        if (
131
-            is_archive()
132
-            && ! (espresso_display_full_description_in_event_list()
133
-                  || espresso_display_excerpt_in_event_list())
134
-        ) {
135
-            $has_content_or_excerpt = false;
136
-        }
137
-        return $has_content_or_excerpt;
138
-    }
139
-
140
-
141
-    /**
142
-     *    event_active_status
143
-     *
144
-     * @param null $num_words
145
-     * @param null $more
146
-     * @return    string
147
-     */
148
-    public static function event_content_or_excerpt($num_words = null, $more = null)
149
-    {
150
-        global $post;
151
-        ob_start();
152
-        if ((is_single()) || (is_archive() && espresso_display_full_description_in_event_list())) {
153
-            // admin has chosen "full description"
154
-            // for the "Event Espresso - Events > Templates > Display Description" option
155
-            the_content();
156
-        } elseif ((is_archive() && espresso_display_excerpt_in_event_list())) {
157
-            if (has_excerpt($post->ID)) {
158
-                // admin has chosen "excerpt (short desc)"
159
-                // for the "Event Espresso - Events > Templates > Display Description" option
160
-                // AND an excerpt actually exists
161
-                the_excerpt();
162
-            } else {
163
-                // admin has chosen "excerpt (short desc)"
164
-                // for the "Event Espresso - Events > Templates > Display Description" option
165
-                // but NO excerpt actually exists, so we need to create one
166
-                if (! empty($num_words)) {
167
-                    if (empty($more)) {
168
-                        $more_link_text = esc_html__('(more&hellip;)', 'event_espresso');
169
-                        $more           = ' <a href="' . get_permalink() . '"';
170
-                        $more           .= ' class="more-link"';
171
-                        $more           .= EED_Events_Archive::link_target();
172
-                        $more           .= '>' . $more_link_text . '</a>';
173
-                        $more           = apply_filters('the_content_more_link', $more, $more_link_text);
174
-                    }
175
-                    $content = str_replace('NOMORELINK', '', get_the_content('NOMORELINK'));
176
-
177
-                    $content = wp_trim_words($content, $num_words, ' ') . $more;
178
-                } else {
179
-                    $content = get_the_content();
180
-                }
181
-                global $allowedtags;
182
-                // make sure links are allowed
183
-                $allowedtags['a'] = isset($allowedtags['a'])
184
-                    ? $allowedtags['a']
185
-                    : [];
186
-                // as well as target attribute
187
-                $allowedtags['a']['target'] = isset($allowedtags['a']['target'])
188
-                    ? $allowedtags['a']['target']
189
-                    : false;
190
-                // but get previous value so we can reset it
191
-                $prev_value                 = $allowedtags['a']['target'];
192
-                $allowedtags['a']['target'] = true;
193
-                $content                    = wp_kses($content, $allowedtags);
194
-                $content                    = strip_shortcodes($content);
195
-                echo apply_filters('the_content', $content);
196
-                $allowedtags['a']['target'] = $prev_value;
197
-            }
198
-        } else {
199
-            // admin has chosen "none"
200
-            // for the "Event Espresso - Events > Templates > Display Description" option
201
-            echo apply_filters('the_content', '');
202
-        }
203
-        return ob_get_clean();
204
-    }
205
-
206
-
207
-    /**
208
-     *  event_tickets_available
209
-     *
210
-     * @param int $EVT_ID
211
-     * @return     EE_Ticket[]
212
-     * @throws EE_Error
213
-     * @throws ReflectionException
214
-     */
215
-    public static function event_tickets_available($EVT_ID = 0)
216
-    {
217
-        $event                          = EEH_Event_View::get_event($EVT_ID);
218
-        $tickets_available_for_purchase = [];
219
-        if ($event instanceof EE_Event) {
220
-            $datetimes = EEH_Event_View::get_all_date_obj($EVT_ID, false);
221
-            foreach ($datetimes as $datetime) {
222
-                $tickets_available_for_purchase =
223
-                    array_merge($tickets_available_for_purchase, $datetime->ticket_types_available_for_purchase());
224
-            }
225
-        }
226
-        return $tickets_available_for_purchase;
227
-    }
228
-
229
-
230
-    /**
231
-     *    the_event_date
232
-     *
233
-     * @param int  $EVT_ID
234
-     * @param bool $hide_uncategorized
235
-     * @return    string
236
-     * @throws EE_Error
237
-     * @throws ReflectionException
238
-     */
239
-    public static function event_categories($EVT_ID = 0, $hide_uncategorized = true)
240
-    {
241
-        $category_links = [];
242
-        $event          = EEH_Event_View::get_event($EVT_ID);
243
-        if ($event instanceof EE_Event) {
244
-            $event_categories = get_the_terms($event->ID(), 'espresso_event_categories');
245
-            if ($event_categories) {
246
-                // loop thru terms and create links
247
-                foreach ($event_categories as $term) {
248
-                    $url = get_term_link($term, 'espresso_venue_categories');
249
-                    if (
250
-                        ! is_wp_error($url)
251
-                        && (
252
-                            (
253
-                                $hide_uncategorized
254
-                                && strtolower($term->name) != esc_html__('uncategorized', 'event_espresso')
255
-                            )
256
-                            || ! $hide_uncategorized
257
-                        )
258
-                    ) {
259
-                        $category_links[] = '<a href="' . esc_url_raw($url) . '" '
260
-                                            . 'rel="tag" ' . EED_Events_Archive::link_target() . '>'
261
-                                            . esc_html($term->name)
262
-                                            . '</a>';
263
-                    }
264
-                }
265
-            }
266
-        }
267
-        return implode(', ', $category_links);
268
-    }
269
-
270
-
271
-    /**
272
-     *    the_event_date - first date by date order
273
-     *
274
-     * @param string $date_format
275
-     * @param string $time_format
276
-     * @param int    $EVT_ID
277
-     * @return    string
278
-     * @throws EE_Error
279
-     * @throws ReflectionException
280
-     */
281
-    public static function the_event_date($date_format = 'D M jS', $time_format = 'g:i a', $EVT_ID = 0)
282
-    {
283
-        $datetime = EEH_Event_View::get_primary_date_obj($EVT_ID);
284
-        $format   = ! empty($date_format) && ! empty($time_format)
285
-                ? $date_format . ' ' . $time_format
286
-                : $date_format . $time_format;
287
-        return $datetime instanceof EE_Datetime ? $datetime->get_i18n_datetime('DTT_EVT_start', $format) : '';
288
-    }
289
-
290
-
291
-    /**
292
-     *    the_event_end_date - last date by date order
293
-     *
294
-     * @param string $date_format
295
-     * @param string $time_format
296
-     * @param int    $EVT_ID
297
-     * @return    string
298
-     * @throws EE_Error
299
-     * @throws ReflectionException
300
-     */
301
-    public static function the_event_end_date($date_format = 'D M jS', $time_format = 'g:i a', $EVT_ID = 0)
302
-    {
303
-        $datetime = EEH_Event_View::get_last_date_obj($EVT_ID);
304
-        $format   =
305
-            ! empty($date_format) && ! empty($time_format)
306
-                ? $date_format . ' ' . $time_format
307
-                : $date_format
308
-                  . $time_format;
309
-        return $datetime instanceof EE_Datetime ? $datetime->get_i18n_datetime('DTT_EVT_end', $format) : '';
310
-    }
311
-
312
-
313
-    /**
314
-     *    the_earliest_event_date - first date chronologically
315
-     *
316
-     * @param string $date_format
317
-     * @param string $time_format
318
-     * @param int    $EVT_ID
319
-     * @return    string
320
-     * @throws EE_Error
321
-     * @throws ReflectionException
322
-     */
323
-    public static function the_earliest_event_date($date_format = 'D M jS', $time_format = 'g:i a', $EVT_ID = 0)
324
-    {
325
-        $datetime = EEH_Event_View::get_earliest_date_obj($EVT_ID);
326
-        $format   =
327
-            ! empty($date_format) && ! empty($time_format)
328
-                ? $date_format . ' ' . $time_format
329
-                : $date_format
330
-                  . $time_format;
331
-        return $datetime instanceof EE_Datetime ? $datetime->get_i18n_datetime('DTT_EVT_start', $format) : '';
332
-    }
333
-
334
-
335
-    /**
336
-     *    the_latest_event_date - latest date chronologically
337
-     *
338
-     * @param string $date_format
339
-     * @param string $time_format
340
-     * @param int    $EVT_ID
341
-     * @return    string
342
-     * @throws EE_Error
343
-     * @throws ReflectionException
344
-     */
345
-    public static function the_latest_event_date($date_format = 'D M jS', $time_format = 'g:i a', $EVT_ID = 0)
346
-    {
347
-        $datetime = EEH_Event_View::get_latest_date_obj($EVT_ID);
348
-        $format   =
349
-            ! empty($date_format) && ! empty($time_format)
350
-                ? $date_format . ' ' . $time_format
351
-                : $date_format
352
-                  . $time_format;
353
-        return $datetime instanceof EE_Datetime ? $datetime->get_i18n_datetime('DTT_EVT_end', $format) : '';
354
-    }
355
-
356
-
357
-    /**
358
-     *    event_date_as_calendar_page
359
-     *
360
-     * @param int $EVT_ID
361
-     * @return    void
362
-     * @throws EE_Error
363
-     * @throws ReflectionException
364
-     */
365
-    public static function event_date_as_calendar_page($EVT_ID = 0)
366
-    {
367
-        $datetime = EEH_Event_View::get_primary_date_obj($EVT_ID);
368
-        if ($datetime instanceof EE_Datetime) {
369
-            ?>
12
+	/**
13
+	 * @var EE_Event $_event
14
+	 */
15
+	private static $_event = null;
16
+
17
+
18
+	/**
19
+	 * get_event
20
+	 * attempts to retrieve an EE_Event object any way it can
21
+	 *
22
+	 * @param int|WP_Post $EVT_ID
23
+	 * @return EE_Event|null
24
+	 * @throws EE_Error
25
+	 * @throws ReflectionException
26
+	 */
27
+	public static function get_event($EVT_ID = 0)
28
+	{
29
+		// international newspaper?
30
+		global $post;
31
+		$EVT_ID = $EVT_ID instanceof WP_Post && $EVT_ID->post_type === 'espresso_events'
32
+			? $EVT_ID->ID
33
+			: absint($EVT_ID);
34
+		// do we already have the Event  you are looking for?
35
+		if (EEH_Event_View::$_event instanceof EE_Event && $EVT_ID && EEH_Event_View::$_event->ID() === $EVT_ID) {
36
+			return EEH_Event_View::$_event;
37
+		}
38
+		// reset property so that the new event is cached.
39
+		EEH_Event_View::$_event = null;
40
+		if (! $EVT_ID && $post instanceof EE_Event) {
41
+			EEH_Event_View::$_event = $post;
42
+			return EEH_Event_View::$_event;
43
+		}
44
+		// if the post type is for an event and it has a cached event and we don't have a different incoming $EVT_ID
45
+		// then let's just use that cached event on the $post object.
46
+		if (
47
+			$post instanceof WP_Post
48
+			&& $post->post_type === 'espresso_events'
49
+			&& isset($post->EE_Event)
50
+			&& (
51
+				$EVT_ID === 0
52
+				|| $EVT_ID === $post->ID
53
+			)
54
+		) {
55
+			EEH_Event_View::$_event = $post->EE_Event;
56
+			return EEH_Event_View::$_event;
57
+		}
58
+		// If the event we have isn't an event but we do have an EVT_ID, let's try getting the event using the ID.
59
+		if (! EEH_Event_View::$_event instanceof EE_Event && $EVT_ID) {
60
+			EEH_Event_View::$_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
61
+		}
62
+		return EEH_Event_View::$_event;
63
+	}
64
+
65
+
66
+	/**
67
+	 *    display_ticket_selector
68
+	 *
69
+	 * @param int $EVT_ID
70
+	 * @return    boolean
71
+	 * @throws EE_Error
72
+	 * @throws EE_Error
73
+	 * @throws ReflectionException
74
+	 */
75
+	public static function display_ticket_selector($EVT_ID = 0)
76
+	{
77
+		$event = EEH_Event_View::get_event($EVT_ID);
78
+		return $event instanceof EE_Event && $event->display_ticket_selector();
79
+	}
80
+
81
+
82
+	/**
83
+	 *    event_status
84
+	 *
85
+	 * @param int $EVT_ID
86
+	 * @return    string
87
+	 * @throws EE_Error
88
+	 * @throws EE_Error
89
+	 * @throws ReflectionException
90
+	 */
91
+	public static function event_status($EVT_ID = 0)
92
+	{
93
+		$event = EEH_Event_View::get_event($EVT_ID);
94
+		return $event instanceof EE_Event ? $event->pretty_active_status(false) : '';
95
+	}
96
+
97
+
98
+	/**
99
+	 *  event_active_status
100
+	 *
101
+	 * @param int $EVT_ID
102
+	 * @return     string
103
+	 * @throws EE_Error
104
+	 * @throws EE_Error
105
+	 * @throws ReflectionException
106
+	 */
107
+	public static function event_active_status($EVT_ID = 0, $echo = true)
108
+	{
109
+		$event = EEH_Event_View::get_event($EVT_ID);
110
+		return $event instanceof EE_Event ? $event->pretty_active_status($echo) : 'inactive';
111
+	}
112
+
113
+
114
+	/**
115
+	 *  event_has_content_or_excerpt
116
+	 *
117
+	 * @param int $EVT_ID
118
+	 * @return     bool
119
+	 * @throws EE_Error
120
+	 * @throws EE_Error
121
+	 * @throws ReflectionException
122
+	 */
123
+	public static function event_has_content_or_excerpt($EVT_ID = 0)
124
+	{
125
+		$event                  = EEH_Event_View::get_event($EVT_ID);
126
+		$has_content_or_excerpt = false;
127
+		if ($event instanceof EE_Event) {
128
+			$has_content_or_excerpt = $event->description() != '' || $event->short_description(null, null, true) != '';
129
+		}
130
+		if (
131
+			is_archive()
132
+			&& ! (espresso_display_full_description_in_event_list()
133
+				  || espresso_display_excerpt_in_event_list())
134
+		) {
135
+			$has_content_or_excerpt = false;
136
+		}
137
+		return $has_content_or_excerpt;
138
+	}
139
+
140
+
141
+	/**
142
+	 *    event_active_status
143
+	 *
144
+	 * @param null $num_words
145
+	 * @param null $more
146
+	 * @return    string
147
+	 */
148
+	public static function event_content_or_excerpt($num_words = null, $more = null)
149
+	{
150
+		global $post;
151
+		ob_start();
152
+		if ((is_single()) || (is_archive() && espresso_display_full_description_in_event_list())) {
153
+			// admin has chosen "full description"
154
+			// for the "Event Espresso - Events > Templates > Display Description" option
155
+			the_content();
156
+		} elseif ((is_archive() && espresso_display_excerpt_in_event_list())) {
157
+			if (has_excerpt($post->ID)) {
158
+				// admin has chosen "excerpt (short desc)"
159
+				// for the "Event Espresso - Events > Templates > Display Description" option
160
+				// AND an excerpt actually exists
161
+				the_excerpt();
162
+			} else {
163
+				// admin has chosen "excerpt (short desc)"
164
+				// for the "Event Espresso - Events > Templates > Display Description" option
165
+				// but NO excerpt actually exists, so we need to create one
166
+				if (! empty($num_words)) {
167
+					if (empty($more)) {
168
+						$more_link_text = esc_html__('(more&hellip;)', 'event_espresso');
169
+						$more           = ' <a href="' . get_permalink() . '"';
170
+						$more           .= ' class="more-link"';
171
+						$more           .= EED_Events_Archive::link_target();
172
+						$more           .= '>' . $more_link_text . '</a>';
173
+						$more           = apply_filters('the_content_more_link', $more, $more_link_text);
174
+					}
175
+					$content = str_replace('NOMORELINK', '', get_the_content('NOMORELINK'));
176
+
177
+					$content = wp_trim_words($content, $num_words, ' ') . $more;
178
+				} else {
179
+					$content = get_the_content();
180
+				}
181
+				global $allowedtags;
182
+				// make sure links are allowed
183
+				$allowedtags['a'] = isset($allowedtags['a'])
184
+					? $allowedtags['a']
185
+					: [];
186
+				// as well as target attribute
187
+				$allowedtags['a']['target'] = isset($allowedtags['a']['target'])
188
+					? $allowedtags['a']['target']
189
+					: false;
190
+				// but get previous value so we can reset it
191
+				$prev_value                 = $allowedtags['a']['target'];
192
+				$allowedtags['a']['target'] = true;
193
+				$content                    = wp_kses($content, $allowedtags);
194
+				$content                    = strip_shortcodes($content);
195
+				echo apply_filters('the_content', $content);
196
+				$allowedtags['a']['target'] = $prev_value;
197
+			}
198
+		} else {
199
+			// admin has chosen "none"
200
+			// for the "Event Espresso - Events > Templates > Display Description" option
201
+			echo apply_filters('the_content', '');
202
+		}
203
+		return ob_get_clean();
204
+	}
205
+
206
+
207
+	/**
208
+	 *  event_tickets_available
209
+	 *
210
+	 * @param int $EVT_ID
211
+	 * @return     EE_Ticket[]
212
+	 * @throws EE_Error
213
+	 * @throws ReflectionException
214
+	 */
215
+	public static function event_tickets_available($EVT_ID = 0)
216
+	{
217
+		$event                          = EEH_Event_View::get_event($EVT_ID);
218
+		$tickets_available_for_purchase = [];
219
+		if ($event instanceof EE_Event) {
220
+			$datetimes = EEH_Event_View::get_all_date_obj($EVT_ID, false);
221
+			foreach ($datetimes as $datetime) {
222
+				$tickets_available_for_purchase =
223
+					array_merge($tickets_available_for_purchase, $datetime->ticket_types_available_for_purchase());
224
+			}
225
+		}
226
+		return $tickets_available_for_purchase;
227
+	}
228
+
229
+
230
+	/**
231
+	 *    the_event_date
232
+	 *
233
+	 * @param int  $EVT_ID
234
+	 * @param bool $hide_uncategorized
235
+	 * @return    string
236
+	 * @throws EE_Error
237
+	 * @throws ReflectionException
238
+	 */
239
+	public static function event_categories($EVT_ID = 0, $hide_uncategorized = true)
240
+	{
241
+		$category_links = [];
242
+		$event          = EEH_Event_View::get_event($EVT_ID);
243
+		if ($event instanceof EE_Event) {
244
+			$event_categories = get_the_terms($event->ID(), 'espresso_event_categories');
245
+			if ($event_categories) {
246
+				// loop thru terms and create links
247
+				foreach ($event_categories as $term) {
248
+					$url = get_term_link($term, 'espresso_venue_categories');
249
+					if (
250
+						! is_wp_error($url)
251
+						&& (
252
+							(
253
+								$hide_uncategorized
254
+								&& strtolower($term->name) != esc_html__('uncategorized', 'event_espresso')
255
+							)
256
+							|| ! $hide_uncategorized
257
+						)
258
+					) {
259
+						$category_links[] = '<a href="' . esc_url_raw($url) . '" '
260
+											. 'rel="tag" ' . EED_Events_Archive::link_target() . '>'
261
+											. esc_html($term->name)
262
+											. '</a>';
263
+					}
264
+				}
265
+			}
266
+		}
267
+		return implode(', ', $category_links);
268
+	}
269
+
270
+
271
+	/**
272
+	 *    the_event_date - first date by date order
273
+	 *
274
+	 * @param string $date_format
275
+	 * @param string $time_format
276
+	 * @param int    $EVT_ID
277
+	 * @return    string
278
+	 * @throws EE_Error
279
+	 * @throws ReflectionException
280
+	 */
281
+	public static function the_event_date($date_format = 'D M jS', $time_format = 'g:i a', $EVT_ID = 0)
282
+	{
283
+		$datetime = EEH_Event_View::get_primary_date_obj($EVT_ID);
284
+		$format   = ! empty($date_format) && ! empty($time_format)
285
+				? $date_format . ' ' . $time_format
286
+				: $date_format . $time_format;
287
+		return $datetime instanceof EE_Datetime ? $datetime->get_i18n_datetime('DTT_EVT_start', $format) : '';
288
+	}
289
+
290
+
291
+	/**
292
+	 *    the_event_end_date - last date by date order
293
+	 *
294
+	 * @param string $date_format
295
+	 * @param string $time_format
296
+	 * @param int    $EVT_ID
297
+	 * @return    string
298
+	 * @throws EE_Error
299
+	 * @throws ReflectionException
300
+	 */
301
+	public static function the_event_end_date($date_format = 'D M jS', $time_format = 'g:i a', $EVT_ID = 0)
302
+	{
303
+		$datetime = EEH_Event_View::get_last_date_obj($EVT_ID);
304
+		$format   =
305
+			! empty($date_format) && ! empty($time_format)
306
+				? $date_format . ' ' . $time_format
307
+				: $date_format
308
+				  . $time_format;
309
+		return $datetime instanceof EE_Datetime ? $datetime->get_i18n_datetime('DTT_EVT_end', $format) : '';
310
+	}
311
+
312
+
313
+	/**
314
+	 *    the_earliest_event_date - first date chronologically
315
+	 *
316
+	 * @param string $date_format
317
+	 * @param string $time_format
318
+	 * @param int    $EVT_ID
319
+	 * @return    string
320
+	 * @throws EE_Error
321
+	 * @throws ReflectionException
322
+	 */
323
+	public static function the_earliest_event_date($date_format = 'D M jS', $time_format = 'g:i a', $EVT_ID = 0)
324
+	{
325
+		$datetime = EEH_Event_View::get_earliest_date_obj($EVT_ID);
326
+		$format   =
327
+			! empty($date_format) && ! empty($time_format)
328
+				? $date_format . ' ' . $time_format
329
+				: $date_format
330
+				  . $time_format;
331
+		return $datetime instanceof EE_Datetime ? $datetime->get_i18n_datetime('DTT_EVT_start', $format) : '';
332
+	}
333
+
334
+
335
+	/**
336
+	 *    the_latest_event_date - latest date chronologically
337
+	 *
338
+	 * @param string $date_format
339
+	 * @param string $time_format
340
+	 * @param int    $EVT_ID
341
+	 * @return    string
342
+	 * @throws EE_Error
343
+	 * @throws ReflectionException
344
+	 */
345
+	public static function the_latest_event_date($date_format = 'D M jS', $time_format = 'g:i a', $EVT_ID = 0)
346
+	{
347
+		$datetime = EEH_Event_View::get_latest_date_obj($EVT_ID);
348
+		$format   =
349
+			! empty($date_format) && ! empty($time_format)
350
+				? $date_format . ' ' . $time_format
351
+				: $date_format
352
+				  . $time_format;
353
+		return $datetime instanceof EE_Datetime ? $datetime->get_i18n_datetime('DTT_EVT_end', $format) : '';
354
+	}
355
+
356
+
357
+	/**
358
+	 *    event_date_as_calendar_page
359
+	 *
360
+	 * @param int $EVT_ID
361
+	 * @return    void
362
+	 * @throws EE_Error
363
+	 * @throws ReflectionException
364
+	 */
365
+	public static function event_date_as_calendar_page($EVT_ID = 0)
366
+	{
367
+		$datetime = EEH_Event_View::get_primary_date_obj($EVT_ID);
368
+		if ($datetime instanceof EE_Datetime) {
369
+			?>
370 370
             <div class="event-date-calendar-page-dv">
371 371
                 <div class="event-date-calendar-page-month-dv">
372 372
                     <?php echo esc_html($datetime->get_i18n_datetime('DTT_EVT_start', 'M')); ?>
@@ -376,260 +376,260 @@  discard block
 block discarded – undo
376 376
                 </div>
377 377
             </div>
378 378
             <?php
379
-        }
380
-    }
381
-
382
-
383
-    /**
384
-     *    get_primary_date_obj - orders date by DTT_order
385
-     *
386
-     * @param int $EVT_ID
387
-     * @return EE_Datetime
388
-     * @throws EE_Error
389
-     * @throws ReflectionException
390
-     */
391
-    public static function get_primary_date_obj($EVT_ID = 0)
392
-    {
393
-        $event = EEH_Event_View::get_event($EVT_ID);
394
-        if ($event instanceof EE_Event) {
395
-            $datetimes = $event->get_many_related(
396
-                'Datetime',
397
-                [
398
-                    'limit'    => 1,
399
-                    'order_by' => ['DTT_order' => 'ASC'],
400
-                ]
401
-            );
402
-            return reset($datetimes);
403
-        }
404
-        return null;
405
-    }
406
-
407
-
408
-    /**
409
-     *    get_last_date_obj - orders date by DTT_order
410
-     *
411
-     * @param int $EVT_ID
412
-     * @return EE_Datetime
413
-     * @throws EE_Error
414
-     * @throws ReflectionException
415
-     */
416
-    public static function get_last_date_obj($EVT_ID = 0)
417
-    {
418
-        $event = EEH_Event_View::get_event($EVT_ID);
419
-        if ($event instanceof EE_Event) {
420
-            $datetimes = $event->get_many_related(
421
-                'Datetime',
422
-                [
423
-                    'limit'    => 1,
424
-                    'order_by' => ['DTT_order' => 'DESC'],
425
-                ]
426
-            );
427
-            return end($datetimes);
428
-        }
429
-        return null;
430
-    }
431
-
432
-
433
-    /**
434
-     *    get_earliest_date_obj - orders date chronologically
435
-     *
436
-     * @param int $EVT_ID
437
-     * @return EE_Datetime
438
-     * @throws EE_Error
439
-     * @throws ReflectionException
440
-     */
441
-    public static function get_earliest_date_obj($EVT_ID = 0)
442
-    {
443
-        $event = EEH_Event_View::get_event($EVT_ID);
444
-        if ($event instanceof EE_Event) {
445
-            $datetimes = $event->get_many_related(
446
-                'Datetime',
447
-                [
448
-                    'limit'    => 1,
449
-                    'order_by' => ['DTT_EVT_start' => 'ASC'],
450
-                ]
451
-            );
452
-            return reset($datetimes);
453
-        }
454
-        return null;
455
-    }
456
-
457
-
458
-    /**
459
-     *    get_latest_date_obj - orders date chronologically
460
-     *
461
-     * @param int $EVT_ID
462
-     * @return EE_Datetime
463
-     * @throws EE_Error
464
-     * @throws ReflectionException
465
-     */
466
-    public static function get_latest_date_obj($EVT_ID = 0)
467
-    {
468
-        $event = EEH_Event_View::get_event($EVT_ID);
469
-        if ($event instanceof EE_Event) {
470
-            $datetimes = $event->get_many_related(
471
-                'Datetime',
472
-                [
473
-                    'limit'    => 1,
474
-                    'order_by' => ['DTT_EVT_start' => 'DESC'],
475
-                ]
476
-            );
477
-            return end($datetimes);
478
-        }
479
-        return null;
480
-    }
481
-
482
-
483
-    /**
484
-     *    get_next_upcoming_date_obj - return the next upcoming datetime
485
-     *
486
-     * @param int $EVT_ID
487
-     * @return    EE_Datetime|null
488
-     * @throws EE_Error
489
-     * @throws EE_Error
490
-     */
491
-    public static function get_next_upcoming_date_obj($EVT_ID = 0)
492
-    {
493
-        $datetime = EEM_Datetime::instance()->get_one(
494
-            [
495
-                [
496
-                    'Event.EVT_ID'  => $EVT_ID,
497
-                    'DTT_EVT_start' => ['>=', current_time('mysql', true)],
498
-                ],
499
-                'order_by' => ['DTT_EVT_start' => 'asc'],
500
-            ]
501
-        );
502
-        return $datetime instanceof EE_Datetime ? $datetime : null;
503
-    }
504
-
505
-
506
-    /**
507
-     *    get_all_date_obj
508
-     *
509
-     * @param int  $EVT_ID
510
-     * @param null $include_expired
511
-     * @param bool $include_deleted
512
-     * @param null $limit
513
-     * @return EE_Datetime[]
514
-     * @throws EE_Error
515
-     * @throws EE_Error
516
-     * @throws ReflectionException
517
-     */
518
-    public static function get_all_date_obj(
519
-        $EVT_ID = 0,
520
-        $include_expired = null,
521
-        $include_deleted = false,
522
-        $limit = null
523
-    ) {
524
-        $event = EEH_Event_View::get_event($EVT_ID);
525
-        if ($include_expired === null) {
526
-            if ($event instanceof EE_Event && $event->is_expired()) {
527
-                $include_expired = true;
528
-            } else {
529
-                $include_expired = false;
530
-            }
531
-        }
532
-
533
-        if ($event instanceof EE_Event) {
534
-            return $event->datetimes_ordered($include_expired, $include_deleted, $limit);
535
-        }
536
-        return [];
537
-    }
538
-
539
-
540
-    /**
541
-     *    event_link_url
542
-     *
543
-     * @param int $EVT_ID
544
-     * @return string
545
-     * @throws EE_Error
546
-     * @throws ReflectionException
547
-     */
548
-    public static function event_link_url($EVT_ID = 0)
549
-    {
550
-        $event = EEH_Event_View::get_event($EVT_ID);
551
-        if ($event instanceof EE_Event) {
552
-            $url = $event->external_url() !== null && $event->external_url() !== ''
553
-                ? $event->external_url()
554
-                : get_permalink($event->ID());
555
-            $url = preg_match("~^(?:f|ht)tps?://~i", $url) ? $url : 'https://' . $url;
556
-            return esc_url_raw($url);
557
-        }
558
-        return '';
559
-    }
560
-
561
-
562
-    /**
563
-     *    event_phone
564
-     *
565
-     * @param int $EVT_ID
566
-     * @return    string
567
-     * @throws EE_Error
568
-     * @throws EE_Error
569
-     * @throws ReflectionException
570
-     */
571
-    public static function event_phone($EVT_ID = 0)
572
-    {
573
-        $event = EEH_Event_View::get_event($EVT_ID);
574
-        if ($event instanceof EE_Event) {
575
-            return EEH_Schema::telephone($event->phone());
576
-        }
577
-        return null;
578
-    }
579
-
580
-
581
-    /**
582
-     *    edit_event_link
583
-     *
584
-     * @param int    $EVT_ID
585
-     * @param string $link
586
-     * @param string $before
587
-     * @param string $after
588
-     * @return    string
589
-     * @throws EE_Error
590
-     * @throws ReflectionException
591
-     */
592
-    public static function edit_event_link($EVT_ID = 0, $link = '', $before = '', $after = '')
593
-    {
594
-        $event = EEH_Event_View::get_event($EVT_ID);
595
-        if ($event instanceof EE_Event) {
596
-            // can the user edit this post ?
597
-            if (current_user_can('edit_post', $event->ID())) {
598
-                // set link text
599
-                $link_text = ! empty($link) ? $link : esc_html__('edit this event', 'event_espresso');
600
-                // generate nonce
601
-                $nonce = wp_create_nonce('edit_nonce');
602
-                // generate url to event editor for this event
603
-                $url =
604
-                    add_query_arg(
605
-                        [
606
-                            'page'       => 'espresso_events',
607
-                            'action'     => 'edit',
608
-                            'post'       => $event->ID(),
609
-                            'edit_nonce' => $nonce,
610
-                        ],
611
-                        admin_url()
612
-                    );
613
-                // get edit CPT text
614
-                $post_type_obj = get_post_type_object('espresso_events');
615
-                // build final link html
616
-                $link = '<a class="post-edit-link" href="' . $url . '" ';
617
-                $link .= ' title="' . esc_attr($post_type_obj->labels->edit_item) . '"';
618
-                $link .= EED_Events_Archive::link_target();
619
-                $link .= '>' . $link_text . '</a>';
620
-                // put it all together
621
-                return $before . apply_filters('edit_post_link', $link, $event->ID()) . $after;
622
-            }
623
-        }
624
-        return '';
625
-    }
626
-
627
-
628
-    /**
629
-     * @return string
630
-     */
631
-    public static function event_archive_url()
632
-    {
633
-        return get_post_type_archive_link('espresso_events');
634
-    }
379
+		}
380
+	}
381
+
382
+
383
+	/**
384
+	 *    get_primary_date_obj - orders date by DTT_order
385
+	 *
386
+	 * @param int $EVT_ID
387
+	 * @return EE_Datetime
388
+	 * @throws EE_Error
389
+	 * @throws ReflectionException
390
+	 */
391
+	public static function get_primary_date_obj($EVT_ID = 0)
392
+	{
393
+		$event = EEH_Event_View::get_event($EVT_ID);
394
+		if ($event instanceof EE_Event) {
395
+			$datetimes = $event->get_many_related(
396
+				'Datetime',
397
+				[
398
+					'limit'    => 1,
399
+					'order_by' => ['DTT_order' => 'ASC'],
400
+				]
401
+			);
402
+			return reset($datetimes);
403
+		}
404
+		return null;
405
+	}
406
+
407
+
408
+	/**
409
+	 *    get_last_date_obj - orders date by DTT_order
410
+	 *
411
+	 * @param int $EVT_ID
412
+	 * @return EE_Datetime
413
+	 * @throws EE_Error
414
+	 * @throws ReflectionException
415
+	 */
416
+	public static function get_last_date_obj($EVT_ID = 0)
417
+	{
418
+		$event = EEH_Event_View::get_event($EVT_ID);
419
+		if ($event instanceof EE_Event) {
420
+			$datetimes = $event->get_many_related(
421
+				'Datetime',
422
+				[
423
+					'limit'    => 1,
424
+					'order_by' => ['DTT_order' => 'DESC'],
425
+				]
426
+			);
427
+			return end($datetimes);
428
+		}
429
+		return null;
430
+	}
431
+
432
+
433
+	/**
434
+	 *    get_earliest_date_obj - orders date chronologically
435
+	 *
436
+	 * @param int $EVT_ID
437
+	 * @return EE_Datetime
438
+	 * @throws EE_Error
439
+	 * @throws ReflectionException
440
+	 */
441
+	public static function get_earliest_date_obj($EVT_ID = 0)
442
+	{
443
+		$event = EEH_Event_View::get_event($EVT_ID);
444
+		if ($event instanceof EE_Event) {
445
+			$datetimes = $event->get_many_related(
446
+				'Datetime',
447
+				[
448
+					'limit'    => 1,
449
+					'order_by' => ['DTT_EVT_start' => 'ASC'],
450
+				]
451
+			);
452
+			return reset($datetimes);
453
+		}
454
+		return null;
455
+	}
456
+
457
+
458
+	/**
459
+	 *    get_latest_date_obj - orders date chronologically
460
+	 *
461
+	 * @param int $EVT_ID
462
+	 * @return EE_Datetime
463
+	 * @throws EE_Error
464
+	 * @throws ReflectionException
465
+	 */
466
+	public static function get_latest_date_obj($EVT_ID = 0)
467
+	{
468
+		$event = EEH_Event_View::get_event($EVT_ID);
469
+		if ($event instanceof EE_Event) {
470
+			$datetimes = $event->get_many_related(
471
+				'Datetime',
472
+				[
473
+					'limit'    => 1,
474
+					'order_by' => ['DTT_EVT_start' => 'DESC'],
475
+				]
476
+			);
477
+			return end($datetimes);
478
+		}
479
+		return null;
480
+	}
481
+
482
+
483
+	/**
484
+	 *    get_next_upcoming_date_obj - return the next upcoming datetime
485
+	 *
486
+	 * @param int $EVT_ID
487
+	 * @return    EE_Datetime|null
488
+	 * @throws EE_Error
489
+	 * @throws EE_Error
490
+	 */
491
+	public static function get_next_upcoming_date_obj($EVT_ID = 0)
492
+	{
493
+		$datetime = EEM_Datetime::instance()->get_one(
494
+			[
495
+				[
496
+					'Event.EVT_ID'  => $EVT_ID,
497
+					'DTT_EVT_start' => ['>=', current_time('mysql', true)],
498
+				],
499
+				'order_by' => ['DTT_EVT_start' => 'asc'],
500
+			]
501
+		);
502
+		return $datetime instanceof EE_Datetime ? $datetime : null;
503
+	}
504
+
505
+
506
+	/**
507
+	 *    get_all_date_obj
508
+	 *
509
+	 * @param int  $EVT_ID
510
+	 * @param null $include_expired
511
+	 * @param bool $include_deleted
512
+	 * @param null $limit
513
+	 * @return EE_Datetime[]
514
+	 * @throws EE_Error
515
+	 * @throws EE_Error
516
+	 * @throws ReflectionException
517
+	 */
518
+	public static function get_all_date_obj(
519
+		$EVT_ID = 0,
520
+		$include_expired = null,
521
+		$include_deleted = false,
522
+		$limit = null
523
+	) {
524
+		$event = EEH_Event_View::get_event($EVT_ID);
525
+		if ($include_expired === null) {
526
+			if ($event instanceof EE_Event && $event->is_expired()) {
527
+				$include_expired = true;
528
+			} else {
529
+				$include_expired = false;
530
+			}
531
+		}
532
+
533
+		if ($event instanceof EE_Event) {
534
+			return $event->datetimes_ordered($include_expired, $include_deleted, $limit);
535
+		}
536
+		return [];
537
+	}
538
+
539
+
540
+	/**
541
+	 *    event_link_url
542
+	 *
543
+	 * @param int $EVT_ID
544
+	 * @return string
545
+	 * @throws EE_Error
546
+	 * @throws ReflectionException
547
+	 */
548
+	public static function event_link_url($EVT_ID = 0)
549
+	{
550
+		$event = EEH_Event_View::get_event($EVT_ID);
551
+		if ($event instanceof EE_Event) {
552
+			$url = $event->external_url() !== null && $event->external_url() !== ''
553
+				? $event->external_url()
554
+				: get_permalink($event->ID());
555
+			$url = preg_match("~^(?:f|ht)tps?://~i", $url) ? $url : 'https://' . $url;
556
+			return esc_url_raw($url);
557
+		}
558
+		return '';
559
+	}
560
+
561
+
562
+	/**
563
+	 *    event_phone
564
+	 *
565
+	 * @param int $EVT_ID
566
+	 * @return    string
567
+	 * @throws EE_Error
568
+	 * @throws EE_Error
569
+	 * @throws ReflectionException
570
+	 */
571
+	public static function event_phone($EVT_ID = 0)
572
+	{
573
+		$event = EEH_Event_View::get_event($EVT_ID);
574
+		if ($event instanceof EE_Event) {
575
+			return EEH_Schema::telephone($event->phone());
576
+		}
577
+		return null;
578
+	}
579
+
580
+
581
+	/**
582
+	 *    edit_event_link
583
+	 *
584
+	 * @param int    $EVT_ID
585
+	 * @param string $link
586
+	 * @param string $before
587
+	 * @param string $after
588
+	 * @return    string
589
+	 * @throws EE_Error
590
+	 * @throws ReflectionException
591
+	 */
592
+	public static function edit_event_link($EVT_ID = 0, $link = '', $before = '', $after = '')
593
+	{
594
+		$event = EEH_Event_View::get_event($EVT_ID);
595
+		if ($event instanceof EE_Event) {
596
+			// can the user edit this post ?
597
+			if (current_user_can('edit_post', $event->ID())) {
598
+				// set link text
599
+				$link_text = ! empty($link) ? $link : esc_html__('edit this event', 'event_espresso');
600
+				// generate nonce
601
+				$nonce = wp_create_nonce('edit_nonce');
602
+				// generate url to event editor for this event
603
+				$url =
604
+					add_query_arg(
605
+						[
606
+							'page'       => 'espresso_events',
607
+							'action'     => 'edit',
608
+							'post'       => $event->ID(),
609
+							'edit_nonce' => $nonce,
610
+						],
611
+						admin_url()
612
+					);
613
+				// get edit CPT text
614
+				$post_type_obj = get_post_type_object('espresso_events');
615
+				// build final link html
616
+				$link = '<a class="post-edit-link" href="' . $url . '" ';
617
+				$link .= ' title="' . esc_attr($post_type_obj->labels->edit_item) . '"';
618
+				$link .= EED_Events_Archive::link_target();
619
+				$link .= '>' . $link_text . '</a>';
620
+				// put it all together
621
+				return $before . apply_filters('edit_post_link', $link, $event->ID()) . $after;
622
+			}
623
+		}
624
+		return '';
625
+	}
626
+
627
+
628
+	/**
629
+	 * @return string
630
+	 */
631
+	public static function event_archive_url()
632
+	{
633
+		return get_post_type_archive_link('espresso_events');
634
+	}
635 635
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_List_Table.core.php 1 patch
Indentation   +920 added lines, -920 removed lines patch added patch discarded remove patch
@@ -4,7 +4,7 @@  discard block
 block discarded – undo
4 4
 use EventEspresso\core\services\request\RequestInterface;
5 5
 
6 6
 if (! class_exists('WP_List_Table')) {
7
-    require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
7
+	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
8 8
 }
9 9
 
10 10
 
@@ -22,925 +22,925 @@  discard block
 block discarded – undo
22 22
  */
23 23
 abstract class EE_Admin_List_Table extends WP_List_Table
24 24
 {
25
-    const ACTION_COPY    = 'duplicate';
26
-
27
-    const ACTION_DELETE  = 'delete';
28
-
29
-    const ACTION_EDIT    = 'edit';
30
-
31
-    const ACTION_RESTORE = 'restore';
32
-
33
-    const ACTION_TRASH   = 'trash';
34
-
35
-    protected static $actions = [
36
-        self::ACTION_COPY,
37
-        self::ACTION_DELETE,
38
-        self::ACTION_EDIT,
39
-        self::ACTION_RESTORE,
40
-        self::ACTION_TRASH,
41
-    ];
42
-
43
-    /**
44
-     * holds the data that will be processed for the table
45
-     *
46
-     * @var array $_data
47
-     */
48
-    protected $_data;
49
-
50
-
51
-    /**
52
-     * This holds the value of all the data available for the given view (for all pages).
53
-     *
54
-     * @var int $_all_data_count
55
-     */
56
-    protected $_all_data_count;
57
-
58
-
59
-    /**
60
-     * Will contain the count of trashed items for the view label.
61
-     *
62
-     * @var int $_trashed_count
63
-     */
64
-    protected $_trashed_count;
65
-
66
-
67
-    /**
68
-     * This is what will be referenced as the slug for the current screen
69
-     *
70
-     * @var string $_screen
71
-     */
72
-    protected $_screen;
73
-
74
-
75
-    /**
76
-     * this is the EE_Admin_Page object
77
-     *
78
-     * @var EE_Admin_Page $_admin_page
79
-     */
80
-    protected $_admin_page;
81
-
82
-
83
-    /**
84
-     * The current view
85
-     *
86
-     * @var string $_view
87
-     */
88
-    protected $_view;
89
-
90
-
91
-    /**
92
-     * array of possible views for this table
93
-     *
94
-     * @var array $_views
95
-     */
96
-    protected $_views;
97
-
98
-
99
-    /**
100
-     * An array of key => value pairs containing information about the current table
101
-     * array(
102
-     *        'plural' => 'plural label',
103
-     *        'singular' => 'singular label',
104
-     *        'ajax' => false, //whether to use ajax or not
105
-     *        'screen' => null, //string used to reference what screen this is
106
-     *        (WP_List_table converts to screen object)
107
-     * )
108
-     *
109
-     * @var array $_wp_list_args
110
-     */
111
-    protected $_wp_list_args;
112
-
113
-    /**
114
-     * an array of column names
115
-     * array(
116
-     *    'internal-name' => 'Title'
117
-     * )
118
-     *
119
-     * @var array $_columns
120
-     */
121
-    protected $_columns;
122
-
123
-    /**
124
-     * An array of sortable columns
125
-     * array(
126
-     *    'internal-name' => 'orderby' //or
127
-     *    'internal-name' => array( 'orderby', true )
128
-     * )
129
-     *
130
-     * @var array $_sortable_columns
131
-     */
132
-    protected $_sortable_columns;
133
-
134
-    /**
135
-     * callback method used to perform AJAX row reordering
136
-     *
137
-     * @var string $_ajax_sorting_callback
138
-     */
139
-    protected $_ajax_sorting_callback;
140
-
141
-    /**
142
-     * An array of hidden columns (if needed)
143
-     * array('internal-name', 'internal-name')
144
-     *
145
-     * @var array $_hidden_columns
146
-     */
147
-    protected $_hidden_columns;
148
-
149
-    /**
150
-     * holds the per_page value
151
-     *
152
-     * @var int $_per_page
153
-     */
154
-    protected $_per_page;
155
-
156
-    /**
157
-     * holds what page number is currently being viewed
158
-     *
159
-     * @var int $_current_page
160
-     */
161
-    protected $_current_page;
162
-
163
-    /**
164
-     * the reference string for the nonce_action
165
-     *
166
-     * @var string $_nonce_action_ref
167
-     */
168
-    protected $_nonce_action_ref;
169
-
170
-    /**
171
-     * property to hold incoming request data (as set by the admin_page_core)
172
-     *
173
-     * @var array $_req_data
174
-     */
175
-    protected $_req_data;
176
-
177
-
178
-    /**
179
-     * yes / no array for admin form fields
180
-     *
181
-     * @var array $_yes_no
182
-     */
183
-    protected $_yes_no = [];
184
-
185
-    /**
186
-     * Array describing buttons that should appear at the bottom of the page
187
-     * Keys are strings that represent the button's function (specifically a key in _labels['buttons']),
188
-     * and the values are another array with the following keys
189
-     * array(
190
-     *    'route' => 'page_route',
191
-     *    'extra_request' => array('evt_id' => 1 ); //extra request vars that need to be included in the button.
192
-     * )
193
-     *
194
-     * @var array $_bottom_buttons
195
-     */
196
-    protected $_bottom_buttons = [];
197
-
198
-
199
-    /**
200
-     * Used to indicate what should be the primary column for the list table.
201
-     * If not present then falls back to what WP calculates
202
-     * as the primary column.
203
-     *
204
-     * @type string $_primary_column
205
-     */
206
-    protected $_primary_column = '';
207
-
208
-
209
-    /**
210
-     * Used to indicate whether the table has a checkbox column or not.
211
-     *
212
-     * @type bool $_has_checkbox_column
213
-     */
214
-    protected $_has_checkbox_column = false;
215
-
216
-
217
-    /**
218
-     * @param EE_Admin_Page $admin_page we use this for obtaining everything we need in the list table
219
-     */
220
-    public function __construct(EE_Admin_Page $admin_page)
221
-    {
222
-        $this->_admin_page   = $admin_page;
223
-        $this->_req_data     = $this->_admin_page->get_request_data();
224
-        $this->_view         = $this->_admin_page->get_view();
225
-        $this->_views        = empty($this->_views) ? $this->_admin_page->get_list_table_view_RLs() : $this->_views;
226
-        $this->_current_page = $this->get_pagenum();
227
-        $this->_screen       = $this->_admin_page->get_current_page() . '_' . $this->_admin_page->get_current_view();
228
-        $this->_yes_no       = [
229
-            esc_html__('No', 'event_espresso'),
230
-            esc_html__('Yes', 'event_espresso')
231
-        ];
232
-
233
-        $this->_per_page = $this->get_items_per_page($this->_screen . '_per_page');
234
-
235
-        $this->_setup_data();
236
-        $this->_add_view_counts();
237
-
238
-        $this->_nonce_action_ref = $this->_view;
239
-
240
-        $this->_set_properties();
241
-
242
-        // set primary column
243
-        add_filter('list_table_primary_column', [$this, 'set_primary_column']);
244
-
245
-        // set parent defaults
246
-        parent::__construct($this->_wp_list_args);
247
-
248
-        $this->prepare_items();
249
-    }
250
-
251
-
252
-    /**
253
-     * _setup_data
254
-     * this method is used to setup the $_data, $_all_data_count, and _per_page properties
255
-     *
256
-     * @return void
257
-     * @uses $this->_admin_page
258
-     */
259
-    abstract protected function _setup_data();
260
-
261
-
262
-    /**
263
-     * set the properties that this class needs to be able to execute wp_list_table properly
264
-     * properties set:
265
-     * _wp_list_args = what the arguments required for the parent _wp_list_table.
266
-     * _columns = set the columns in an array.
267
-     * _sortable_columns = columns that are sortable (array).
268
-     * _hidden_columns = columns that are hidden (array)
269
-     * _default_orderby = the default orderby for sorting.
270
-     *
271
-     * @abstract
272
-     * @access protected
273
-     * @return void
274
-     */
275
-    abstract protected function _set_properties();
276
-
277
-
278
-    /**
279
-     * _get_table_filters
280
-     * We use this to assemble and return any filters that are associated with this table that help further refine what
281
-     * gets shown in the table.
282
-     *
283
-     * @abstract
284
-     * @access protected
285
-     * @return string
286
-     */
287
-    abstract protected function _get_table_filters();
288
-
289
-
290
-    /**
291
-     * this is a method that child class will do to add counts to the views array so when views are displayed the
292
-     * counts of the views is accurate.
293
-     *
294
-     * @abstract
295
-     * @access protected
296
-     * @return void
297
-     */
298
-    abstract protected function _add_view_counts();
299
-
300
-
301
-    /**
302
-     * _get_hidden_fields
303
-     * returns a html string of hidden fields so if any table filters are used the current view will be respected.
304
-     *
305
-     * @return string
306
-     */
307
-    protected function _get_hidden_fields()
308
-    {
309
-        $action = isset($this->_req_data['route']) ? $this->_req_data['route'] : '';
310
-        $action = empty($action) && isset($this->_req_data['action']) ? $this->_req_data['action'] : $action;
311
-        // if action is STILL empty, then we set it to default
312
-        $action = empty($action) ? 'default' : $action;
313
-        $field  = '<input type="hidden" name="page" value="' . esc_attr($this->_req_data['page']) . '" />' . "\n";
314
-        $field  .= '<input type="hidden" name="route" value="' . esc_attr($action) . '" />' . "\n";
315
-        $field  .= '<input type="hidden" name="perpage" value="' . esc_attr($this->_per_page) . '" />' . "\n";
316
-
317
-        $bulk_actions = $this->_get_bulk_actions();
318
-        foreach ($bulk_actions as $bulk_action => $label) {
319
-            $field .= '<input type="hidden" name="' . $bulk_action . '_nonce"'
320
-                      . ' value="' . wp_create_nonce($bulk_action . '_nonce') . '" />' . "\n";
321
-        }
322
-
323
-        return $field;
324
-    }
325
-
326
-
327
-    /**
328
-     * _set_column_info
329
-     * we're using this to set the column headers property.
330
-     *
331
-     * @access protected
332
-     * @return void
333
-     */
334
-    protected function _set_column_info()
335
-    {
336
-        $columns   = $this->get_columns();
337
-        $hidden    = $this->get_hidden_columns();
338
-        $_sortable = $this->get_sortable_columns();
339
-
340
-        /**
341
-         * Dynamic hook allowing for adding sortable columns in this list table.
342
-         * Note that $this->screen->id is in the format
343
-         * {sanitize_title($top_level_menu_label)}_page_{$espresso_admin_page_slug}.  So for the messages list
344
-         * table it is: event-espresso_page_espresso_messages.
345
-         * However, take note that if the top level menu label has been translated (i.e. "Event Espresso"). then the
346
-         * hook prefix ("event-espresso") will be different.
347
-         *
348
-         * @var array
349
-         */
350
-        $_sortable = apply_filters("FHEE_manage_{$this->screen->id}_sortable_columns", $_sortable, $this->_screen);
351
-
352
-        $sortable = [];
353
-        foreach ($_sortable as $id => $data) {
354
-            if (empty($data)) {
355
-                continue;
356
-            }
357
-            // fix for offset errors with WP_List_Table default get_columninfo()
358
-            if (is_array($data)) {
359
-                $_data[0] = key($data);
360
-                $_data[1] = isset($data[1]) ? $data[1] : false;
361
-            } else {
362
-                $_data[0] = $data;
363
-            }
364
-
365
-            $data = (array) $data;
366
-
367
-            if (! isset($data[1])) {
368
-                $_data[1] = false;
369
-            }
370
-
371
-            $sortable[ $id ] = $_data;
372
-        }
373
-        $primary               = $this->get_primary_column_name();
374
-        $this->_column_headers = [$columns, $hidden, $sortable, $primary];
375
-    }
376
-
377
-
378
-    /**
379
-     * Added for WP4.1 backward compat (@see https://events.codebasehq.com/projects/event-espresso/tickets/8814)
380
-     *
381
-     * @return string
382
-     */
383
-    protected function get_primary_column_name()
384
-    {
385
-        foreach (class_parents($this) as $parent) {
386
-            if ($parent === 'WP_List_Table' && method_exists($parent, 'get_primary_column_name')) {
387
-                return parent::get_primary_column_name();
388
-            }
389
-        }
390
-        return $this->_primary_column;
391
-    }
392
-
393
-
394
-    /**
395
-     * Added for WP4.1 backward compat (@see https://events.codebasehq.com/projects/event-espresso/tickets/8814)
396
-     *
397
-     * @param EE_Base_Class $item
398
-     * @param string        $column_name
399
-     * @param string        $primary
400
-     * @return string
401
-     */
402
-    protected function handle_row_actions($item, $column_name, $primary)
403
-    {
404
-        foreach (class_parents($this) as $parent) {
405
-            if ($parent === 'WP_List_Table' && method_exists($parent, 'handle_row_actions')) {
406
-                return parent::handle_row_actions($item, $column_name, $primary);
407
-            }
408
-        }
409
-        return '';
410
-    }
411
-
412
-
413
-    /**
414
-     * _get_bulk_actions
415
-     * This is a wrapper called by WP_List_Table::get_bulk_actions()
416
-     *
417
-     * @access protected
418
-     * @return array bulk_actions
419
-     */
420
-    protected function _get_bulk_actions(): array
421
-    {
422
-        $actions = [];
423
-        // the _views property should have the bulk_actions, so let's go through and extract them into a properly
424
-        // formatted array for the wp_list_table();
425
-        foreach ($this->_views as $view => $args) {
426
-            if ($this->_view === $view && isset($args['bulk_action']) && is_array($args['bulk_action'])) {
427
-                // each bulk action will correspond with a admin page route, so we can check whatever the capability is
428
-                // for that page route and skip adding the bulk action if no access for the current logged in user.
429
-                foreach ($args['bulk_action'] as $route => $label) {
430
-                    if ($this->_admin_page->check_user_access($route, true)) {
431
-                        $actions[ $route ] = $label;
432
-                    }
433
-                }
434
-            }
435
-        }
436
-        return $actions;
437
-    }
438
-
439
-
440
-    /**
441
-     * Generate the table navigation above or below the table.
442
-     * Overrides the parent table nav in WP_List_Table so we can hide the bulk action div if there are no bulk actions.
443
-     *
444
-     * @throws EE_Error
445
-     * @since 4.9.44.rc.001
446
-     */
447
-    public function display_tablenav($which)
448
-    {
449
-        if ('top' === $which) {
450
-            wp_nonce_field('bulk-' . $this->_args['plural']);
451
-        }
452
-        ?>
25
+	const ACTION_COPY    = 'duplicate';
26
+
27
+	const ACTION_DELETE  = 'delete';
28
+
29
+	const ACTION_EDIT    = 'edit';
30
+
31
+	const ACTION_RESTORE = 'restore';
32
+
33
+	const ACTION_TRASH   = 'trash';
34
+
35
+	protected static $actions = [
36
+		self::ACTION_COPY,
37
+		self::ACTION_DELETE,
38
+		self::ACTION_EDIT,
39
+		self::ACTION_RESTORE,
40
+		self::ACTION_TRASH,
41
+	];
42
+
43
+	/**
44
+	 * holds the data that will be processed for the table
45
+	 *
46
+	 * @var array $_data
47
+	 */
48
+	protected $_data;
49
+
50
+
51
+	/**
52
+	 * This holds the value of all the data available for the given view (for all pages).
53
+	 *
54
+	 * @var int $_all_data_count
55
+	 */
56
+	protected $_all_data_count;
57
+
58
+
59
+	/**
60
+	 * Will contain the count of trashed items for the view label.
61
+	 *
62
+	 * @var int $_trashed_count
63
+	 */
64
+	protected $_trashed_count;
65
+
66
+
67
+	/**
68
+	 * This is what will be referenced as the slug for the current screen
69
+	 *
70
+	 * @var string $_screen
71
+	 */
72
+	protected $_screen;
73
+
74
+
75
+	/**
76
+	 * this is the EE_Admin_Page object
77
+	 *
78
+	 * @var EE_Admin_Page $_admin_page
79
+	 */
80
+	protected $_admin_page;
81
+
82
+
83
+	/**
84
+	 * The current view
85
+	 *
86
+	 * @var string $_view
87
+	 */
88
+	protected $_view;
89
+
90
+
91
+	/**
92
+	 * array of possible views for this table
93
+	 *
94
+	 * @var array $_views
95
+	 */
96
+	protected $_views;
97
+
98
+
99
+	/**
100
+	 * An array of key => value pairs containing information about the current table
101
+	 * array(
102
+	 *        'plural' => 'plural label',
103
+	 *        'singular' => 'singular label',
104
+	 *        'ajax' => false, //whether to use ajax or not
105
+	 *        'screen' => null, //string used to reference what screen this is
106
+	 *        (WP_List_table converts to screen object)
107
+	 * )
108
+	 *
109
+	 * @var array $_wp_list_args
110
+	 */
111
+	protected $_wp_list_args;
112
+
113
+	/**
114
+	 * an array of column names
115
+	 * array(
116
+	 *    'internal-name' => 'Title'
117
+	 * )
118
+	 *
119
+	 * @var array $_columns
120
+	 */
121
+	protected $_columns;
122
+
123
+	/**
124
+	 * An array of sortable columns
125
+	 * array(
126
+	 *    'internal-name' => 'orderby' //or
127
+	 *    'internal-name' => array( 'orderby', true )
128
+	 * )
129
+	 *
130
+	 * @var array $_sortable_columns
131
+	 */
132
+	protected $_sortable_columns;
133
+
134
+	/**
135
+	 * callback method used to perform AJAX row reordering
136
+	 *
137
+	 * @var string $_ajax_sorting_callback
138
+	 */
139
+	protected $_ajax_sorting_callback;
140
+
141
+	/**
142
+	 * An array of hidden columns (if needed)
143
+	 * array('internal-name', 'internal-name')
144
+	 *
145
+	 * @var array $_hidden_columns
146
+	 */
147
+	protected $_hidden_columns;
148
+
149
+	/**
150
+	 * holds the per_page value
151
+	 *
152
+	 * @var int $_per_page
153
+	 */
154
+	protected $_per_page;
155
+
156
+	/**
157
+	 * holds what page number is currently being viewed
158
+	 *
159
+	 * @var int $_current_page
160
+	 */
161
+	protected $_current_page;
162
+
163
+	/**
164
+	 * the reference string for the nonce_action
165
+	 *
166
+	 * @var string $_nonce_action_ref
167
+	 */
168
+	protected $_nonce_action_ref;
169
+
170
+	/**
171
+	 * property to hold incoming request data (as set by the admin_page_core)
172
+	 *
173
+	 * @var array $_req_data
174
+	 */
175
+	protected $_req_data;
176
+
177
+
178
+	/**
179
+	 * yes / no array for admin form fields
180
+	 *
181
+	 * @var array $_yes_no
182
+	 */
183
+	protected $_yes_no = [];
184
+
185
+	/**
186
+	 * Array describing buttons that should appear at the bottom of the page
187
+	 * Keys are strings that represent the button's function (specifically a key in _labels['buttons']),
188
+	 * and the values are another array with the following keys
189
+	 * array(
190
+	 *    'route' => 'page_route',
191
+	 *    'extra_request' => array('evt_id' => 1 ); //extra request vars that need to be included in the button.
192
+	 * )
193
+	 *
194
+	 * @var array $_bottom_buttons
195
+	 */
196
+	protected $_bottom_buttons = [];
197
+
198
+
199
+	/**
200
+	 * Used to indicate what should be the primary column for the list table.
201
+	 * If not present then falls back to what WP calculates
202
+	 * as the primary column.
203
+	 *
204
+	 * @type string $_primary_column
205
+	 */
206
+	protected $_primary_column = '';
207
+
208
+
209
+	/**
210
+	 * Used to indicate whether the table has a checkbox column or not.
211
+	 *
212
+	 * @type bool $_has_checkbox_column
213
+	 */
214
+	protected $_has_checkbox_column = false;
215
+
216
+
217
+	/**
218
+	 * @param EE_Admin_Page $admin_page we use this for obtaining everything we need in the list table
219
+	 */
220
+	public function __construct(EE_Admin_Page $admin_page)
221
+	{
222
+		$this->_admin_page   = $admin_page;
223
+		$this->_req_data     = $this->_admin_page->get_request_data();
224
+		$this->_view         = $this->_admin_page->get_view();
225
+		$this->_views        = empty($this->_views) ? $this->_admin_page->get_list_table_view_RLs() : $this->_views;
226
+		$this->_current_page = $this->get_pagenum();
227
+		$this->_screen       = $this->_admin_page->get_current_page() . '_' . $this->_admin_page->get_current_view();
228
+		$this->_yes_no       = [
229
+			esc_html__('No', 'event_espresso'),
230
+			esc_html__('Yes', 'event_espresso')
231
+		];
232
+
233
+		$this->_per_page = $this->get_items_per_page($this->_screen . '_per_page');
234
+
235
+		$this->_setup_data();
236
+		$this->_add_view_counts();
237
+
238
+		$this->_nonce_action_ref = $this->_view;
239
+
240
+		$this->_set_properties();
241
+
242
+		// set primary column
243
+		add_filter('list_table_primary_column', [$this, 'set_primary_column']);
244
+
245
+		// set parent defaults
246
+		parent::__construct($this->_wp_list_args);
247
+
248
+		$this->prepare_items();
249
+	}
250
+
251
+
252
+	/**
253
+	 * _setup_data
254
+	 * this method is used to setup the $_data, $_all_data_count, and _per_page properties
255
+	 *
256
+	 * @return void
257
+	 * @uses $this->_admin_page
258
+	 */
259
+	abstract protected function _setup_data();
260
+
261
+
262
+	/**
263
+	 * set the properties that this class needs to be able to execute wp_list_table properly
264
+	 * properties set:
265
+	 * _wp_list_args = what the arguments required for the parent _wp_list_table.
266
+	 * _columns = set the columns in an array.
267
+	 * _sortable_columns = columns that are sortable (array).
268
+	 * _hidden_columns = columns that are hidden (array)
269
+	 * _default_orderby = the default orderby for sorting.
270
+	 *
271
+	 * @abstract
272
+	 * @access protected
273
+	 * @return void
274
+	 */
275
+	abstract protected function _set_properties();
276
+
277
+
278
+	/**
279
+	 * _get_table_filters
280
+	 * We use this to assemble and return any filters that are associated with this table that help further refine what
281
+	 * gets shown in the table.
282
+	 *
283
+	 * @abstract
284
+	 * @access protected
285
+	 * @return string
286
+	 */
287
+	abstract protected function _get_table_filters();
288
+
289
+
290
+	/**
291
+	 * this is a method that child class will do to add counts to the views array so when views are displayed the
292
+	 * counts of the views is accurate.
293
+	 *
294
+	 * @abstract
295
+	 * @access protected
296
+	 * @return void
297
+	 */
298
+	abstract protected function _add_view_counts();
299
+
300
+
301
+	/**
302
+	 * _get_hidden_fields
303
+	 * returns a html string of hidden fields so if any table filters are used the current view will be respected.
304
+	 *
305
+	 * @return string
306
+	 */
307
+	protected function _get_hidden_fields()
308
+	{
309
+		$action = isset($this->_req_data['route']) ? $this->_req_data['route'] : '';
310
+		$action = empty($action) && isset($this->_req_data['action']) ? $this->_req_data['action'] : $action;
311
+		// if action is STILL empty, then we set it to default
312
+		$action = empty($action) ? 'default' : $action;
313
+		$field  = '<input type="hidden" name="page" value="' . esc_attr($this->_req_data['page']) . '" />' . "\n";
314
+		$field  .= '<input type="hidden" name="route" value="' . esc_attr($action) . '" />' . "\n";
315
+		$field  .= '<input type="hidden" name="perpage" value="' . esc_attr($this->_per_page) . '" />' . "\n";
316
+
317
+		$bulk_actions = $this->_get_bulk_actions();
318
+		foreach ($bulk_actions as $bulk_action => $label) {
319
+			$field .= '<input type="hidden" name="' . $bulk_action . '_nonce"'
320
+					  . ' value="' . wp_create_nonce($bulk_action . '_nonce') . '" />' . "\n";
321
+		}
322
+
323
+		return $field;
324
+	}
325
+
326
+
327
+	/**
328
+	 * _set_column_info
329
+	 * we're using this to set the column headers property.
330
+	 *
331
+	 * @access protected
332
+	 * @return void
333
+	 */
334
+	protected function _set_column_info()
335
+	{
336
+		$columns   = $this->get_columns();
337
+		$hidden    = $this->get_hidden_columns();
338
+		$_sortable = $this->get_sortable_columns();
339
+
340
+		/**
341
+		 * Dynamic hook allowing for adding sortable columns in this list table.
342
+		 * Note that $this->screen->id is in the format
343
+		 * {sanitize_title($top_level_menu_label)}_page_{$espresso_admin_page_slug}.  So for the messages list
344
+		 * table it is: event-espresso_page_espresso_messages.
345
+		 * However, take note that if the top level menu label has been translated (i.e. "Event Espresso"). then the
346
+		 * hook prefix ("event-espresso") will be different.
347
+		 *
348
+		 * @var array
349
+		 */
350
+		$_sortable = apply_filters("FHEE_manage_{$this->screen->id}_sortable_columns", $_sortable, $this->_screen);
351
+
352
+		$sortable = [];
353
+		foreach ($_sortable as $id => $data) {
354
+			if (empty($data)) {
355
+				continue;
356
+			}
357
+			// fix for offset errors with WP_List_Table default get_columninfo()
358
+			if (is_array($data)) {
359
+				$_data[0] = key($data);
360
+				$_data[1] = isset($data[1]) ? $data[1] : false;
361
+			} else {
362
+				$_data[0] = $data;
363
+			}
364
+
365
+			$data = (array) $data;
366
+
367
+			if (! isset($data[1])) {
368
+				$_data[1] = false;
369
+			}
370
+
371
+			$sortable[ $id ] = $_data;
372
+		}
373
+		$primary               = $this->get_primary_column_name();
374
+		$this->_column_headers = [$columns, $hidden, $sortable, $primary];
375
+	}
376
+
377
+
378
+	/**
379
+	 * Added for WP4.1 backward compat (@see https://events.codebasehq.com/projects/event-espresso/tickets/8814)
380
+	 *
381
+	 * @return string
382
+	 */
383
+	protected function get_primary_column_name()
384
+	{
385
+		foreach (class_parents($this) as $parent) {
386
+			if ($parent === 'WP_List_Table' && method_exists($parent, 'get_primary_column_name')) {
387
+				return parent::get_primary_column_name();
388
+			}
389
+		}
390
+		return $this->_primary_column;
391
+	}
392
+
393
+
394
+	/**
395
+	 * Added for WP4.1 backward compat (@see https://events.codebasehq.com/projects/event-espresso/tickets/8814)
396
+	 *
397
+	 * @param EE_Base_Class $item
398
+	 * @param string        $column_name
399
+	 * @param string        $primary
400
+	 * @return string
401
+	 */
402
+	protected function handle_row_actions($item, $column_name, $primary)
403
+	{
404
+		foreach (class_parents($this) as $parent) {
405
+			if ($parent === 'WP_List_Table' && method_exists($parent, 'handle_row_actions')) {
406
+				return parent::handle_row_actions($item, $column_name, $primary);
407
+			}
408
+		}
409
+		return '';
410
+	}
411
+
412
+
413
+	/**
414
+	 * _get_bulk_actions
415
+	 * This is a wrapper called by WP_List_Table::get_bulk_actions()
416
+	 *
417
+	 * @access protected
418
+	 * @return array bulk_actions
419
+	 */
420
+	protected function _get_bulk_actions(): array
421
+	{
422
+		$actions = [];
423
+		// the _views property should have the bulk_actions, so let's go through and extract them into a properly
424
+		// formatted array for the wp_list_table();
425
+		foreach ($this->_views as $view => $args) {
426
+			if ($this->_view === $view && isset($args['bulk_action']) && is_array($args['bulk_action'])) {
427
+				// each bulk action will correspond with a admin page route, so we can check whatever the capability is
428
+				// for that page route and skip adding the bulk action if no access for the current logged in user.
429
+				foreach ($args['bulk_action'] as $route => $label) {
430
+					if ($this->_admin_page->check_user_access($route, true)) {
431
+						$actions[ $route ] = $label;
432
+					}
433
+				}
434
+			}
435
+		}
436
+		return $actions;
437
+	}
438
+
439
+
440
+	/**
441
+	 * Generate the table navigation above or below the table.
442
+	 * Overrides the parent table nav in WP_List_Table so we can hide the bulk action div if there are no bulk actions.
443
+	 *
444
+	 * @throws EE_Error
445
+	 * @since 4.9.44.rc.001
446
+	 */
447
+	public function display_tablenav($which)
448
+	{
449
+		if ('top' === $which) {
450
+			wp_nonce_field('bulk-' . $this->_args['plural']);
451
+		}
452
+		?>
453 453
         <div class="tablenav <?php echo esc_attr($which); ?>">
454 454
             <?php if ($this->_get_bulk_actions()) { ?>
455 455
                 <div class="alignleft actions bulkactions">
456 456
                     <?php $this->bulk_actions(); ?>
457 457
                 </div>
458 458
             <?php }
459
-            $this->extra_tablenav($which);
460
-            $this->pagination($which);
461
-            ?>
459
+			$this->extra_tablenav($which);
460
+			$this->pagination($which);
461
+			?>
462 462
 
463 463
             <br class="clear" />
464 464
         </div>
465 465
         <?php
466
-    }
467
-
468
-
469
-    /**
470
-     * _filters
471
-     * This receives the filters array from children _get_table_filters() and assembles the string including the filter
472
-     * button.
473
-     *
474
-     * @access private
475
-     * @return void  echos html showing filters
476
-     */
477
-    private function _filters()
478
-    {
479
-        $classname = get_class($this);
480
-        $filters   = apply_filters(
481
-            "FHEE__{$classname}__filters",
482
-            (array) $this->_get_table_filters(),
483
-            $this,
484
-            $this->_screen
485
-        );
486
-
487
-        if (empty($filters)) {
488
-            return;
489
-        }
490
-        foreach ($filters as $filter) {
491
-            echo $filter; // already escaped
492
-        }
493
-        echo '
466
+	}
467
+
468
+
469
+	/**
470
+	 * _filters
471
+	 * This receives the filters array from children _get_table_filters() and assembles the string including the filter
472
+	 * button.
473
+	 *
474
+	 * @access private
475
+	 * @return void  echos html showing filters
476
+	 */
477
+	private function _filters()
478
+	{
479
+		$classname = get_class($this);
480
+		$filters   = apply_filters(
481
+			"FHEE__{$classname}__filters",
482
+			(array) $this->_get_table_filters(),
483
+			$this,
484
+			$this->_screen
485
+		);
486
+
487
+		if (empty($filters)) {
488
+			return;
489
+		}
490
+		foreach ($filters as $filter) {
491
+			echo $filter; // already escaped
492
+		}
493
+		echo '
494 494
         <span class="ee-list-table-filters__submit-buttons">';
495
-        // add filter button at end
496
-        echo '<input type="submit" class="button button--secondary" value="'
497
-             . esc_html__('Filter', 'event_espresso')
498
-             . '" id="post-query-submit" />';
499
-        // add reset filters button at end
500
-        echo '<a class="button button--secondary"  href="'
501
-             . esc_url_raw($this->_admin_page->get_current_page_view_url())
502
-             . '">'
503
-             . esc_html__('Reset Filters', 'event_espresso')
504
-             . '</a>';
505
-        echo '
495
+		// add filter button at end
496
+		echo '<input type="submit" class="button button--secondary" value="'
497
+			 . esc_html__('Filter', 'event_espresso')
498
+			 . '" id="post-query-submit" />';
499
+		// add reset filters button at end
500
+		echo '<a class="button button--secondary"  href="'
501
+			 . esc_url_raw($this->_admin_page->get_current_page_view_url())
502
+			 . '">'
503
+			 . esc_html__('Reset Filters', 'event_espresso')
504
+			 . '</a>';
505
+		echo '
506 506
         </span>';
507
-    }
508
-
509
-
510
-    /**
511
-     * Callback for 'list_table_primary_column' WordPress filter
512
-     * If child EE_Admin_List_Table classes set the _primary_column property then that will be set as the primary
513
-     * column when class is instantiated.
514
-     *
515
-     * @param string $column_name
516
-     * @return string
517
-     * @see WP_List_Table::get_primary_column_name
518
-     */
519
-    public function set_primary_column($column_name)
520
-    {
521
-        return ! empty($this->_primary_column) ? $this->_primary_column : $column_name;
522
-    }
523
-
524
-
525
-    /**
526
-     *
527
-     */
528
-    public function prepare_items()
529
-    {
530
-        $this->_set_column_info();
531
-        // $this->_column_headers = $this->get_column_info();
532
-        $total_items = $this->_all_data_count;
533
-        $this->process_bulk_action();
534
-
535
-        $this->items = $this->_data;
536
-        $this->set_pagination_args(
537
-            [
538
-                'total_items' => $total_items,
539
-                'per_page'    => $this->_per_page,
540
-                'total_pages' => ceil($total_items / $this->_per_page),
541
-            ]
542
-        );
543
-    }
544
-
545
-
546
-    /**
547
-     * @param object|array $item
548
-     * @return string html content for the column
549
-     */
550
-    protected function column_cb($item)
551
-    {
552
-        return '';
553
-    }
554
-
555
-
556
-    /**
557
-     * This column is the default for when there is no defined column method for a registered column.
558
-     * This can be overridden by child classes, but allows for hooking in for custom columns.
559
-     *
560
-     * @param EE_Base_Class $item
561
-     * @param string        $column_name The column being called.
562
-     * @return string html content for the column
563
-     */
564
-    public function column_default($item, $column_name)
565
-    {
566
-        /**
567
-         * Dynamic hook allowing for adding additional column content in this list table.
568
-         * Note that $this->screen->id is in the format
569
-         * {sanitize_title($top_level_menu_label)}_page_{$espresso_admin_page_slug}.  So for the messages list
570
-         * table it is: event-espresso_page_espresso_messages.
571
-         * However, take note that if the top level menu label has been translated (i.e. "Event Espresso"). then the
572
-         * hook prefix ("event-espresso") will be different.
573
-         */
574
-        ob_start();
575
-        do_action(
576
-            'AHEE__EE_Admin_List_Table__column_' . $column_name . '__' . $this->screen->id,
577
-            $item,
578
-            $this->_screen
579
-        );
580
-        return ob_get_clean();
581
-    }
582
-
583
-
584
-    /**
585
-     * Get a list of columns. The format is:
586
-     * 'internal-name' => 'Title'
587
-     *
588
-     * @return array
589
-     * @since  3.1.0
590
-     * @access public
591
-     * @abstract
592
-     */
593
-    public function get_columns()
594
-    {
595
-        /**
596
-         * Dynamic hook allowing for adding additional columns in this list table.
597
-         * Note that $this->screen->id is in the format
598
-         * {sanitize_title($top_level_menu_label)}_page_{$espresso_admin_page_slug}.  So for the messages list
599
-         * table it is: event-espresso_page_espresso_messages.
600
-         * However, take note that if the top level menu label has been translated (i.e. "Event Espresso"). then the
601
-         * hook prefix ("event-espresso") will be different.
602
-         *
603
-         * @var array
604
-         */
605
-        return apply_filters('FHEE_manage_' . $this->screen->id . '_columns', $this->_columns, $this->_screen);
606
-    }
607
-
608
-
609
-    /**
610
-     * Get an associative array ( id => link ) with the list
611
-     * of views available on this table.
612
-     *
613
-     * @return array
614
-     * @since  3.1.0
615
-     * @access protected
616
-     */
617
-    public function get_views()
618
-    {
619
-        return $this->_views;
620
-    }
621
-
622
-
623
-    /**
624
-     * Generate the views html.
625
-     */
626
-    public function display_views()
627
-    {
628
-        $views           = $this->get_views();
629
-        $assembled_views = [];
630
-
631
-        if (empty($views)) {
632
-            return;
633
-        }
634
-        echo "<ul class='subsubsub'>\n";
635
-        foreach ($views as $view) {
636
-            $count = isset($view['count']) && ! empty($view['count']) ? absint($view['count']) : 0;
637
-            if (isset($view['slug'], $view['class'], $view['url'], $view['label'])) {
638
-                $filter = "<li";
639
-                $filter .= $view['class'] ? " class='" . esc_attr($view['class']) . "'" : '';
640
-                $filter .= ">";
641
-                $filter .= '<a href="' . esc_url_raw($view['url']) . '">' . esc_html($view['label']) . '</a>';
642
-                $filter .= '<span class="count">(' . $count . ')</span>';
643
-                $filter .= '</li>';
644
-                $assembled_views[ $view['slug'] ] = $filter;
645
-            }
646
-        }
647
-
648
-        echo ! empty($assembled_views)
649
-            ? implode("<li style='margin:0 .5rem;'>|</li>", $assembled_views)
650
-            : '';
651
-        echo "</ul>";
652
-    }
653
-
654
-
655
-    /**
656
-     * Generates content for a single row of the table
657
-     *
658
-     * @param EE_Base_Class $item The current item
659
-     * @since  4.1
660
-     * @access public
661
-     */
662
-    public function single_row($item)
663
-    {
664
-        $row_class = $this->_get_row_class($item);
665
-        echo '<tr class="' . esc_attr($row_class) . '">';
666
-        $this->single_row_columns($item); // already escaped
667
-        echo '</tr>';
668
-    }
669
-
670
-
671
-    /**
672
-     * This simply sets up the row class for the table rows.
673
-     * Allows for easier overriding of child methods for setting up sorting.
674
-     *
675
-     * @param EE_Base_Class $item the current item
676
-     * @return string
677
-     */
678
-    protected function _get_row_class($item)
679
-    {
680
-        static $row_class = '';
681
-        $row_class = ($row_class === '' ? 'alternate' : '');
682
-
683
-        $new_row_class = $row_class;
684
-
685
-        if (! empty($this->_ajax_sorting_callback)) {
686
-            $new_row_class .= ' rowsortable';
687
-        }
688
-
689
-        return $new_row_class;
690
-    }
691
-
692
-
693
-    /**
694
-     * @return array
695
-     */
696
-    public function get_sortable_columns()
697
-    {
698
-        return (array) $this->_sortable_columns;
699
-    }
700
-
701
-
702
-    /**
703
-     * @return string
704
-     */
705
-    public function get_ajax_sorting_callback()
706
-    {
707
-        return $this->_ajax_sorting_callback;
708
-    }
709
-
710
-
711
-    /**
712
-     * @return array
713
-     */
714
-    public function get_hidden_columns()
715
-    {
716
-        $user_id     = get_current_user_id();
717
-        $has_default = get_user_option('default' . $this->screen->id . 'columnshidden', $user_id);
718
-        if (empty($has_default) && ! empty($this->_hidden_columns)) {
719
-            update_user_option($user_id, 'default' . $this->screen->id . 'columnshidden', true);
720
-            update_user_option($user_id, 'manage' . $this->screen->id . 'columnshidden', $this->_hidden_columns, true);
721
-        }
722
-        $ref = 'manage' . $this->screen->id . 'columnshidden';
723
-        return (array) get_user_option($ref, $user_id);
724
-    }
725
-
726
-
727
-    /**
728
-     * Generates the columns for a single row of the table.
729
-     * Overridden from wp_list_table so as to allow us to filter the column content for a given
730
-     * column.
731
-     *
732
-     * @param EE_Base_Class $item The current item
733
-     * @since 3.1.0
734
-     */
735
-    public function single_row_columns($item)
736
-    {
737
-        [$columns, $hidden, $sortable, $primary] = $this->get_column_info();
738
-
739
-        foreach ($columns as $column_name => $column_display_name) {
740
-
741
-            /**
742
-             * With WordPress version 4.3.RC+ WordPress started using the hidden css class to control whether columns
743
-             * are hidden or not instead of using "display:none;".  This bit of code provides backward compat.
744
-             */
745
-            $hidden_class = in_array($column_name, $hidden) ? ' hidden' : '';
746
-
747
-            $classes = $column_name . ' column-' . $column_name . $hidden_class;
748
-            if ($primary === $column_name) {
749
-                $classes .= ' has-row-actions column-primary';
750
-            }
751
-
752
-            $data = ' data-colname="' . wp_strip_all_tags($column_display_name) . '"';
753
-
754
-            $class = 'class="' . esc_attr($classes) . '"';
755
-
756
-            $attributes = "{$class}{$data}";
757
-
758
-            if ($column_name === 'cb') {
759
-                echo '<th scope="row" class="check-column">';
760
-                echo apply_filters(
761
-                    'FHEE__EE_Admin_List_Table__single_row_columns__column_cb_content',
762
-                    $this->column_cb($item), // already escaped
763
-                    $item,
764
-                    $this
765
-                );
766
-                echo '</th>';
767
-            } elseif (method_exists($this, 'column_' . $column_name)) {
768
-                echo "<td $attributes>"; // already escaped
769
-                echo apply_filters(
770
-                    'FHEE__EE_Admin_List_Table__single_row_columns__column_' . $column_name . '__column_content',
771
-                    call_user_func([$this, 'column_' . $column_name], $item),
772
-                    $item,
773
-                    $this
774
-                );
775
-                echo $this->handle_row_actions($item, $column_name, $primary);
776
-                echo "</td>";
777
-            } else {
778
-                echo "<td $attributes>"; // already escaped
779
-                echo apply_filters(
780
-                    'FHEE__EE_Admin_List_Table__single_row_columns__column_default__column_content',
781
-                    $this->column_default($item, $column_name),
782
-                    $item,
783
-                    $column_name,
784
-                    $this
785
-                );
786
-                echo $this->handle_row_actions($item, $column_name, $primary);
787
-                echo "</td>";
788
-            }
789
-        }
790
-    }
791
-
792
-
793
-    /**
794
-     * Extra controls to be displayed between bulk actions and pagination
795
-     *
796
-     * @access public
797
-     * @param string $which
798
-     * @throws EE_Error
799
-     */
800
-    public function extra_tablenav($which)
801
-    {
802
-        if ($which === 'top') {
803
-            $this->_filters();
804
-            echo $this->_get_hidden_fields(); // already escaped
805
-        } else {
806
-            echo '<div class="list-table-bottom-buttons alignleft actions">';
807
-            foreach ($this->_bottom_buttons as $type => $action) {
808
-                $route         = isset($action['route']) ? $action['route'] : '';
809
-                $extra_request = isset($action['extra_request']) ? $action['extra_request'] : '';
810
-                // already escaped
811
-                echo $this->_admin_page->get_action_link_or_button(
812
-                    $route,
813
-                    $type,
814
-                    $extra_request,
815
-                    'button button--secondary'
816
-                );
817
-            }
818
-            do_action('AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', $this, $this->_screen);
819
-            echo '</div>';
820
-        }
821
-    }
822
-
823
-
824
-    /**
825
-     * Get an associative array ( option_name => option_title ) with the list
826
-     * of bulk actions available on this table.
827
-     *
828
-     * @return array
829
-     * @since  3.1.0
830
-     * @access protected
831
-     */
832
-    public function get_bulk_actions()
833
-    {
834
-        return (array) $this->_get_bulk_actions();
835
-    }
836
-
837
-
838
-    /**
839
-     * Processing bulk actions.
840
-     */
841
-    public function process_bulk_action()
842
-    {
843
-        // this is not used it is handled by the child EE_Admin_Page class (routes).  However, including here for
844
-        // reference in case there is a case where it gets used.
845
-    }
846
-
847
-
848
-    /**
849
-     * returns the EE admin page this list table is associated with
850
-     *
851
-     * @return EE_Admin_Page
852
-     */
853
-    public function get_admin_page()
854
-    {
855
-        return $this->_admin_page;
856
-    }
857
-
858
-
859
-    /**
860
-     * A "helper" function for all children to provide an html string of
861
-     * actions to output in their content.  It is preferable for child classes
862
-     * to use this method for generating their actions content so that it's
863
-     * filterable by plugins
864
-     *
865
-     * @param string        $action_container           what are the html container
866
-     *                                                  elements for this actions string?
867
-     * @param string        $action_class               What class is for the container
868
-     *                                                  element.
869
-     * @param string        $action_items               The contents for the action items
870
-     *                                                  container.  This is filtered before
871
-     *                                                  returned.
872
-     * @param string        $action_id                  What id (optional) is used for the
873
-     *                                                  container element.
874
-     * @param EE_Base_Class $item                       The object for the column displaying
875
-     *                                                  the actions.
876
-     * @return string The assembled action elements container.
877
-     */
878
-    protected function _action_string(
879
-        $action_items,
880
-        $item,
881
-        $action_container = 'ul',
882
-        $action_class = '',
883
-        $action_id = ''
884
-    ) {
885
-        $action_class = ! empty($action_class) ? ' class="' . esc_attr($action_class) . '"' : '';
886
-        $action_id    = ! empty($action_id) ? ' id="' . esc_attr($action_id) . '"' : '';
887
-        $open_tag     = ! empty($action_container) ? '<' . $action_container . $action_class . $action_id . '>' : '';
888
-        $close_tag    = ! empty($action_container) ? '</' . $action_container . '>' : '';
889
-        try {
890
-            $content = apply_filters(
891
-                'FHEE__EE_Admin_List_Table___action_string__action_items',
892
-                $action_items,
893
-                $item,
894
-                $this
895
-            );
896
-        } catch (Exception $e) {
897
-            if (WP_DEBUG) {
898
-                EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
899
-            }
900
-            $content = $action_items;
901
-        }
902
-        return "{$open_tag}{$content}{$close_tag}";
903
-    }
904
-
905
-
906
-    /**
907
-     * @return string
908
-     */
909
-    protected function getReturnUrl()
910
-    {
911
-        $host = $this->_admin_page->get_request()->getServerParam('HTTP_HOST');
912
-        $uri  = $this->_admin_page->get_request()->getServerParam('REQUEST_URI');
913
-        return urlencode(esc_url_raw("//{$host}{$uri}"));
914
-    }
915
-
916
-
917
-    /**
918
-     * @param string $id
919
-     * @param string $content
920
-     * @param string $align     start (default), center, end
921
-     * @return string
922
-     * @since   $VID:$
923
-     */
924
-    protected function columnContent($id, $content, $align = 'start')
925
-    {
926
-        if (! isset($this->_columns[ $id ])) {
927
-            throw new DomainException('missing column id');
928
-        }
929
-        $heading = $id !== 'cb' ? $this->_columns[ $id ] : '';
930
-        $align = in_array($align, ['start', 'center', 'end']) ? $align : 'start';
931
-        $align = "ee-responsive-table-cell--{$align}";
932
-
933
-        $html = "<div class='ee-responsive-table-cell ee-responsive-table-cell--column-{$id} {$align} ee-layout-row'>";
934
-        $html .= "<div class='ee-responsive-table-cell__heading'>{$heading}</div>";
935
-        $html .= "<div class='ee-responsive-table-cell__content ee-layout-row'>{$content}</div>";
936
-        $html .= "</div>";
937
-        return $html;
938
-    }
939
-
940
-
941
-    protected function actionsModalMenu($actions): string
942
-    {
943
-        return '
507
+	}
508
+
509
+
510
+	/**
511
+	 * Callback for 'list_table_primary_column' WordPress filter
512
+	 * If child EE_Admin_List_Table classes set the _primary_column property then that will be set as the primary
513
+	 * column when class is instantiated.
514
+	 *
515
+	 * @param string $column_name
516
+	 * @return string
517
+	 * @see WP_List_Table::get_primary_column_name
518
+	 */
519
+	public function set_primary_column($column_name)
520
+	{
521
+		return ! empty($this->_primary_column) ? $this->_primary_column : $column_name;
522
+	}
523
+
524
+
525
+	/**
526
+	 *
527
+	 */
528
+	public function prepare_items()
529
+	{
530
+		$this->_set_column_info();
531
+		// $this->_column_headers = $this->get_column_info();
532
+		$total_items = $this->_all_data_count;
533
+		$this->process_bulk_action();
534
+
535
+		$this->items = $this->_data;
536
+		$this->set_pagination_args(
537
+			[
538
+				'total_items' => $total_items,
539
+				'per_page'    => $this->_per_page,
540
+				'total_pages' => ceil($total_items / $this->_per_page),
541
+			]
542
+		);
543
+	}
544
+
545
+
546
+	/**
547
+	 * @param object|array $item
548
+	 * @return string html content for the column
549
+	 */
550
+	protected function column_cb($item)
551
+	{
552
+		return '';
553
+	}
554
+
555
+
556
+	/**
557
+	 * This column is the default for when there is no defined column method for a registered column.
558
+	 * This can be overridden by child classes, but allows for hooking in for custom columns.
559
+	 *
560
+	 * @param EE_Base_Class $item
561
+	 * @param string        $column_name The column being called.
562
+	 * @return string html content for the column
563
+	 */
564
+	public function column_default($item, $column_name)
565
+	{
566
+		/**
567
+		 * Dynamic hook allowing for adding additional column content in this list table.
568
+		 * Note that $this->screen->id is in the format
569
+		 * {sanitize_title($top_level_menu_label)}_page_{$espresso_admin_page_slug}.  So for the messages list
570
+		 * table it is: event-espresso_page_espresso_messages.
571
+		 * However, take note that if the top level menu label has been translated (i.e. "Event Espresso"). then the
572
+		 * hook prefix ("event-espresso") will be different.
573
+		 */
574
+		ob_start();
575
+		do_action(
576
+			'AHEE__EE_Admin_List_Table__column_' . $column_name . '__' . $this->screen->id,
577
+			$item,
578
+			$this->_screen
579
+		);
580
+		return ob_get_clean();
581
+	}
582
+
583
+
584
+	/**
585
+	 * Get a list of columns. The format is:
586
+	 * 'internal-name' => 'Title'
587
+	 *
588
+	 * @return array
589
+	 * @since  3.1.0
590
+	 * @access public
591
+	 * @abstract
592
+	 */
593
+	public function get_columns()
594
+	{
595
+		/**
596
+		 * Dynamic hook allowing for adding additional columns in this list table.
597
+		 * Note that $this->screen->id is in the format
598
+		 * {sanitize_title($top_level_menu_label)}_page_{$espresso_admin_page_slug}.  So for the messages list
599
+		 * table it is: event-espresso_page_espresso_messages.
600
+		 * However, take note that if the top level menu label has been translated (i.e. "Event Espresso"). then the
601
+		 * hook prefix ("event-espresso") will be different.
602
+		 *
603
+		 * @var array
604
+		 */
605
+		return apply_filters('FHEE_manage_' . $this->screen->id . '_columns', $this->_columns, $this->_screen);
606
+	}
607
+
608
+
609
+	/**
610
+	 * Get an associative array ( id => link ) with the list
611
+	 * of views available on this table.
612
+	 *
613
+	 * @return array
614
+	 * @since  3.1.0
615
+	 * @access protected
616
+	 */
617
+	public function get_views()
618
+	{
619
+		return $this->_views;
620
+	}
621
+
622
+
623
+	/**
624
+	 * Generate the views html.
625
+	 */
626
+	public function display_views()
627
+	{
628
+		$views           = $this->get_views();
629
+		$assembled_views = [];
630
+
631
+		if (empty($views)) {
632
+			return;
633
+		}
634
+		echo "<ul class='subsubsub'>\n";
635
+		foreach ($views as $view) {
636
+			$count = isset($view['count']) && ! empty($view['count']) ? absint($view['count']) : 0;
637
+			if (isset($view['slug'], $view['class'], $view['url'], $view['label'])) {
638
+				$filter = "<li";
639
+				$filter .= $view['class'] ? " class='" . esc_attr($view['class']) . "'" : '';
640
+				$filter .= ">";
641
+				$filter .= '<a href="' . esc_url_raw($view['url']) . '">' . esc_html($view['label']) . '</a>';
642
+				$filter .= '<span class="count">(' . $count . ')</span>';
643
+				$filter .= '</li>';
644
+				$assembled_views[ $view['slug'] ] = $filter;
645
+			}
646
+		}
647
+
648
+		echo ! empty($assembled_views)
649
+			? implode("<li style='margin:0 .5rem;'>|</li>", $assembled_views)
650
+			: '';
651
+		echo "</ul>";
652
+	}
653
+
654
+
655
+	/**
656
+	 * Generates content for a single row of the table
657
+	 *
658
+	 * @param EE_Base_Class $item The current item
659
+	 * @since  4.1
660
+	 * @access public
661
+	 */
662
+	public function single_row($item)
663
+	{
664
+		$row_class = $this->_get_row_class($item);
665
+		echo '<tr class="' . esc_attr($row_class) . '">';
666
+		$this->single_row_columns($item); // already escaped
667
+		echo '</tr>';
668
+	}
669
+
670
+
671
+	/**
672
+	 * This simply sets up the row class for the table rows.
673
+	 * Allows for easier overriding of child methods for setting up sorting.
674
+	 *
675
+	 * @param EE_Base_Class $item the current item
676
+	 * @return string
677
+	 */
678
+	protected function _get_row_class($item)
679
+	{
680
+		static $row_class = '';
681
+		$row_class = ($row_class === '' ? 'alternate' : '');
682
+
683
+		$new_row_class = $row_class;
684
+
685
+		if (! empty($this->_ajax_sorting_callback)) {
686
+			$new_row_class .= ' rowsortable';
687
+		}
688
+
689
+		return $new_row_class;
690
+	}
691
+
692
+
693
+	/**
694
+	 * @return array
695
+	 */
696
+	public function get_sortable_columns()
697
+	{
698
+		return (array) $this->_sortable_columns;
699
+	}
700
+
701
+
702
+	/**
703
+	 * @return string
704
+	 */
705
+	public function get_ajax_sorting_callback()
706
+	{
707
+		return $this->_ajax_sorting_callback;
708
+	}
709
+
710
+
711
+	/**
712
+	 * @return array
713
+	 */
714
+	public function get_hidden_columns()
715
+	{
716
+		$user_id     = get_current_user_id();
717
+		$has_default = get_user_option('default' . $this->screen->id . 'columnshidden', $user_id);
718
+		if (empty($has_default) && ! empty($this->_hidden_columns)) {
719
+			update_user_option($user_id, 'default' . $this->screen->id . 'columnshidden', true);
720
+			update_user_option($user_id, 'manage' . $this->screen->id . 'columnshidden', $this->_hidden_columns, true);
721
+		}
722
+		$ref = 'manage' . $this->screen->id . 'columnshidden';
723
+		return (array) get_user_option($ref, $user_id);
724
+	}
725
+
726
+
727
+	/**
728
+	 * Generates the columns for a single row of the table.
729
+	 * Overridden from wp_list_table so as to allow us to filter the column content for a given
730
+	 * column.
731
+	 *
732
+	 * @param EE_Base_Class $item The current item
733
+	 * @since 3.1.0
734
+	 */
735
+	public function single_row_columns($item)
736
+	{
737
+		[$columns, $hidden, $sortable, $primary] = $this->get_column_info();
738
+
739
+		foreach ($columns as $column_name => $column_display_name) {
740
+
741
+			/**
742
+			 * With WordPress version 4.3.RC+ WordPress started using the hidden css class to control whether columns
743
+			 * are hidden or not instead of using "display:none;".  This bit of code provides backward compat.
744
+			 */
745
+			$hidden_class = in_array($column_name, $hidden) ? ' hidden' : '';
746
+
747
+			$classes = $column_name . ' column-' . $column_name . $hidden_class;
748
+			if ($primary === $column_name) {
749
+				$classes .= ' has-row-actions column-primary';
750
+			}
751
+
752
+			$data = ' data-colname="' . wp_strip_all_tags($column_display_name) . '"';
753
+
754
+			$class = 'class="' . esc_attr($classes) . '"';
755
+
756
+			$attributes = "{$class}{$data}";
757
+
758
+			if ($column_name === 'cb') {
759
+				echo '<th scope="row" class="check-column">';
760
+				echo apply_filters(
761
+					'FHEE__EE_Admin_List_Table__single_row_columns__column_cb_content',
762
+					$this->column_cb($item), // already escaped
763
+					$item,
764
+					$this
765
+				);
766
+				echo '</th>';
767
+			} elseif (method_exists($this, 'column_' . $column_name)) {
768
+				echo "<td $attributes>"; // already escaped
769
+				echo apply_filters(
770
+					'FHEE__EE_Admin_List_Table__single_row_columns__column_' . $column_name . '__column_content',
771
+					call_user_func([$this, 'column_' . $column_name], $item),
772
+					$item,
773
+					$this
774
+				);
775
+				echo $this->handle_row_actions($item, $column_name, $primary);
776
+				echo "</td>";
777
+			} else {
778
+				echo "<td $attributes>"; // already escaped
779
+				echo apply_filters(
780
+					'FHEE__EE_Admin_List_Table__single_row_columns__column_default__column_content',
781
+					$this->column_default($item, $column_name),
782
+					$item,
783
+					$column_name,
784
+					$this
785
+				);
786
+				echo $this->handle_row_actions($item, $column_name, $primary);
787
+				echo "</td>";
788
+			}
789
+		}
790
+	}
791
+
792
+
793
+	/**
794
+	 * Extra controls to be displayed between bulk actions and pagination
795
+	 *
796
+	 * @access public
797
+	 * @param string $which
798
+	 * @throws EE_Error
799
+	 */
800
+	public function extra_tablenav($which)
801
+	{
802
+		if ($which === 'top') {
803
+			$this->_filters();
804
+			echo $this->_get_hidden_fields(); // already escaped
805
+		} else {
806
+			echo '<div class="list-table-bottom-buttons alignleft actions">';
807
+			foreach ($this->_bottom_buttons as $type => $action) {
808
+				$route         = isset($action['route']) ? $action['route'] : '';
809
+				$extra_request = isset($action['extra_request']) ? $action['extra_request'] : '';
810
+				// already escaped
811
+				echo $this->_admin_page->get_action_link_or_button(
812
+					$route,
813
+					$type,
814
+					$extra_request,
815
+					'button button--secondary'
816
+				);
817
+			}
818
+			do_action('AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', $this, $this->_screen);
819
+			echo '</div>';
820
+		}
821
+	}
822
+
823
+
824
+	/**
825
+	 * Get an associative array ( option_name => option_title ) with the list
826
+	 * of bulk actions available on this table.
827
+	 *
828
+	 * @return array
829
+	 * @since  3.1.0
830
+	 * @access protected
831
+	 */
832
+	public function get_bulk_actions()
833
+	{
834
+		return (array) $this->_get_bulk_actions();
835
+	}
836
+
837
+
838
+	/**
839
+	 * Processing bulk actions.
840
+	 */
841
+	public function process_bulk_action()
842
+	{
843
+		// this is not used it is handled by the child EE_Admin_Page class (routes).  However, including here for
844
+		// reference in case there is a case where it gets used.
845
+	}
846
+
847
+
848
+	/**
849
+	 * returns the EE admin page this list table is associated with
850
+	 *
851
+	 * @return EE_Admin_Page
852
+	 */
853
+	public function get_admin_page()
854
+	{
855
+		return $this->_admin_page;
856
+	}
857
+
858
+
859
+	/**
860
+	 * A "helper" function for all children to provide an html string of
861
+	 * actions to output in their content.  It is preferable for child classes
862
+	 * to use this method for generating their actions content so that it's
863
+	 * filterable by plugins
864
+	 *
865
+	 * @param string        $action_container           what are the html container
866
+	 *                                                  elements for this actions string?
867
+	 * @param string        $action_class               What class is for the container
868
+	 *                                                  element.
869
+	 * @param string        $action_items               The contents for the action items
870
+	 *                                                  container.  This is filtered before
871
+	 *                                                  returned.
872
+	 * @param string        $action_id                  What id (optional) is used for the
873
+	 *                                                  container element.
874
+	 * @param EE_Base_Class $item                       The object for the column displaying
875
+	 *                                                  the actions.
876
+	 * @return string The assembled action elements container.
877
+	 */
878
+	protected function _action_string(
879
+		$action_items,
880
+		$item,
881
+		$action_container = 'ul',
882
+		$action_class = '',
883
+		$action_id = ''
884
+	) {
885
+		$action_class = ! empty($action_class) ? ' class="' . esc_attr($action_class) . '"' : '';
886
+		$action_id    = ! empty($action_id) ? ' id="' . esc_attr($action_id) . '"' : '';
887
+		$open_tag     = ! empty($action_container) ? '<' . $action_container . $action_class . $action_id . '>' : '';
888
+		$close_tag    = ! empty($action_container) ? '</' . $action_container . '>' : '';
889
+		try {
890
+			$content = apply_filters(
891
+				'FHEE__EE_Admin_List_Table___action_string__action_items',
892
+				$action_items,
893
+				$item,
894
+				$this
895
+			);
896
+		} catch (Exception $e) {
897
+			if (WP_DEBUG) {
898
+				EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
899
+			}
900
+			$content = $action_items;
901
+		}
902
+		return "{$open_tag}{$content}{$close_tag}";
903
+	}
904
+
905
+
906
+	/**
907
+	 * @return string
908
+	 */
909
+	protected function getReturnUrl()
910
+	{
911
+		$host = $this->_admin_page->get_request()->getServerParam('HTTP_HOST');
912
+		$uri  = $this->_admin_page->get_request()->getServerParam('REQUEST_URI');
913
+		return urlencode(esc_url_raw("//{$host}{$uri}"));
914
+	}
915
+
916
+
917
+	/**
918
+	 * @param string $id
919
+	 * @param string $content
920
+	 * @param string $align     start (default), center, end
921
+	 * @return string
922
+	 * @since   $VID:$
923
+	 */
924
+	protected function columnContent($id, $content, $align = 'start')
925
+	{
926
+		if (! isset($this->_columns[ $id ])) {
927
+			throw new DomainException('missing column id');
928
+		}
929
+		$heading = $id !== 'cb' ? $this->_columns[ $id ] : '';
930
+		$align = in_array($align, ['start', 'center', 'end']) ? $align : 'start';
931
+		$align = "ee-responsive-table-cell--{$align}";
932
+
933
+		$html = "<div class='ee-responsive-table-cell ee-responsive-table-cell--column-{$id} {$align} ee-layout-row'>";
934
+		$html .= "<div class='ee-responsive-table-cell__heading'>{$heading}</div>";
935
+		$html .= "<div class='ee-responsive-table-cell__content ee-layout-row'>{$content}</div>";
936
+		$html .= "</div>";
937
+		return $html;
938
+	}
939
+
940
+
941
+	protected function actionsModalMenu($actions): string
942
+	{
943
+		return '
944 944
         <div class="ee-modal-menu">
945 945
             <button class="ee-modal-menu__button button button--small button--icon-only ee-aria-tooltip"
946 946
                     aria-label="' . esc_attr__('list table actions menu', 'event_espresso') . '"
@@ -952,24 +952,24 @@  discard block
 block discarded – undo
952 952
                 ' . $actions . '
953 953
             </div>
954 954
         </div>';
955
-    }
955
+	}
956 956
 
957 957
 
958
-    protected function actionsColumnHeader(): string
959
-    {
960
-        return '
958
+	protected function actionsColumnHeader(): string
959
+	{
960
+		return '
961 961
             <span class="ee-actions-column-header-wrap">
962 962
                 <span class="dashicons dashicons-screenoptions"></span>
963 963
                 <span class="ee-actions-column-header">' . esc_html__('Actions', 'event_espresso') . '</span>
964 964
             </span>';
965
-    }
965
+	}
966 966
 
967 967
 
968
-    protected function getActionLink(string $url, string $display_text, string $label, $class = ''): string
969
-    {
970
-        $class = ! empty($class) ? "{$class} ee-list-table-action" : 'ee-list-table-action';
971
-        $class = ! empty($label) ? "{$class} ee-aria-tooltip" : $class;
972
-        $label = ! empty($label) ? " aria-label='{$label}'" : '';
973
-        return "<a href='{$url}' class='{$class}'{$label}>{$display_text}</a>";
974
-    }
968
+	protected function getActionLink(string $url, string $display_text, string $label, $class = ''): string
969
+	{
970
+		$class = ! empty($class) ? "{$class} ee-list-table-action" : 'ee-list-table-action';
971
+		$class = ! empty($label) ? "{$class} ee-aria-tooltip" : $class;
972
+		$label = ! empty($label) ? " aria-label='{$label}'" : '';
973
+		return "<a href='{$url}' class='{$class}'{$label}>{$display_text}</a>";
974
+	}
975 975
 }
Please login to merge, or discard this patch.
core/admin/templates/admin_details_legend.template.php 2 patches
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -15,10 +15,10 @@  discard block
 block discarded – undo
15 15
 <div class="ee-list-table-legend-container">
16 16
     <h3><?php esc_html_e('Legend', 'event_espresso'); ?></h3>
17 17
     <?php
18
-    if (isset($status_change_notice)) {
19
-        echo  wp_kses($status_change_notice, AllowedTags::getAllowedTags());
20
-    }
21
-    ?>
18
+	if (isset($status_change_notice)) {
19
+		echo  wp_kses($status_change_notice, AllowedTags::getAllowedTags());
20
+	}
21
+	?>
22 22
     <div class="ee-list-table-legend-wrap">
23 23
         <dl class="ee-list-table-legend">
24 24
             <?php foreach ($items as $item => $details) : ?>
@@ -26,9 +26,9 @@  discard block
 block discarded – undo
26 26
                 <?php $class = ! empty($details['class']) ? $details['class'] : 'ee-legend-img-container'; ?>
27 27
                 <span class="ee-legend-item-wrap">
28 28
                 <?php
29
-                if (strpos($details['class'], '<span') !== false) {
30
-                    echo wp_kses($class, AllowedTags::getWithFormTags());
31
-                } else { ?>
29
+				if (strpos($details['class'], '<span') !== false) {
30
+					echo wp_kses($class, AllowedTags::getWithFormTags());
31
+				} else { ?>
32 32
                 <span class="<?php echo esc_attr($class); ?>">
33 33
                     <?php if (! empty($details['icon'])) : ?>
34 34
                         <img alt="<?php echo esc_attr($details['desc']); ?>"
@@ -38,7 +38,7 @@  discard block
 block discarded – undo
38 38
                     <?php endif; ?>
39 39
                 </span>
40 40
                     <?php
41
-                } ?>
41
+				} ?>
42 42
                 </span>
43 43
                 <span class="ee-legend-description"><?php echo esc_html($details['desc']); ?></span>
44 44
             </dt>
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -30,7 +30,7 @@
 block discarded – undo
30 30
                     echo wp_kses($class, AllowedTags::getWithFormTags());
31 31
                 } else { ?>
32 32
                 <span class="<?php echo esc_attr($class); ?>">
33
-                    <?php if (! empty($details['icon'])) : ?>
33
+                    <?php if ( ! empty($details['icon'])) : ?>
34 34
                         <img alt="<?php echo esc_attr($details['desc']); ?>"
35 35
                              class="ee-legend-icon"
36 36
                              src="<?php echo esc_url_raw($details['icon']); ?>"
Please login to merge, or discard this patch.
core/admin/templates/admin_details_wrapper_no_sidebar.template.php 2 patches
Indentation   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -24,19 +24,19 @@
 block discarded – undo
24 24
         <?php endif; ?>
25 25
 
26 26
         <?php
27
-        if (! empty($post_body_content)) :
28
-            if ($add_page_frame) {
29
-                if (
30
-                    strpos($post_body_content, 'class="padding"') === false
31
-                    || strpos($post_body_content, 'class="padding"') < 120
32
-                ) {
33
-                    $post_body_content = '<div class="padding">' . $post_body_content . '</div>';
34
-                }
35
-                if (strpos($post_body_content, '<div class="ee-admin-container">') === false) {
36
-                    $post_body_content = '<div class="ee-admin-container">' . $post_body_content . '</div>';
37
-                }
38
-            }
39
-            ?>
27
+		if (! empty($post_body_content)) :
28
+			if ($add_page_frame) {
29
+				if (
30
+					strpos($post_body_content, 'class="padding"') === false
31
+					|| strpos($post_body_content, 'class="padding"') < 120
32
+				) {
33
+					$post_body_content = '<div class="padding">' . $post_body_content . '</div>';
34
+				}
35
+				if (strpos($post_body_content, '<div class="ee-admin-container">') === false) {
36
+					$post_body_content = '<div class="ee-admin-container">' . $post_body_content . '</div>';
37
+				}
38
+			}
39
+			?>
40 40
             <div id="post-body-content">
41 41
                 <?php echo wp_kses($post_body_content, AllowedTags::getWithFormTags()); ?>
42 42
             </div>
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -12,11 +12,11 @@  discard block
 block discarded – undo
12 12
 
13 13
 ?>
14 14
 
15
-<div id="<?php echo esc_attr($admin_page_wrapper_div_id);?>" class="<?php echo esc_attr($admin_page_wrapper_div_class);?>"
15
+<div id="<?php echo esc_attr($admin_page_wrapper_div_id); ?>" class="<?php echo esc_attr($admin_page_wrapper_div_class); ?>"
16 16
 >
17 17
     <div id="post-body" class="metabox-holder columns-1">
18 18
 
19
-        <?php if (! empty($admin_page_header)) : ?>
19
+        <?php if ( ! empty($admin_page_header)) : ?>
20 20
             <div id="admin-page-header">
21 21
                 <?php echo wp_kses($admin_page_header, AllowedTags::getWithFormTags()); ?>
22 22
             </div>
@@ -24,16 +24,16 @@  discard block
 block discarded – undo
24 24
         <?php endif; ?>
25 25
 
26 26
         <?php
27
-        if (! empty($post_body_content)) :
27
+        if ( ! empty($post_body_content)) :
28 28
             if ($add_page_frame) {
29 29
                 if (
30 30
                     strpos($post_body_content, 'class="padding"') === false
31 31
                     || strpos($post_body_content, 'class="padding"') < 120
32 32
                 ) {
33
-                    $post_body_content = '<div class="padding">' . $post_body_content . '</div>';
33
+                    $post_body_content = '<div class="padding">'.$post_body_content.'</div>';
34 34
                 }
35 35
                 if (strpos($post_body_content, '<div class="ee-admin-container">') === false) {
36
-                    $post_body_content = '<div class="ee-admin-container">' . $post_body_content . '</div>';
36
+                    $post_body_content = '<div class="ee-admin-container">'.$post_body_content.'</div>';
37 37
                 }
38 38
             }
39 39
             ?>
Please login to merge, or discard this patch.
core/admin/templates/admin_details_wrapper.template.php 2 patches
Indentation   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -26,19 +26,19 @@
 block discarded – undo
26 26
     <div id="post-body" class="metabox-holder columns-2">
27 27
 
28 28
         <?php
29
-        if (! empty($post_body_content)) :
30
-            if ($add_page_frame) {
31
-                if (
32
-                    strpos($post_body_content, 'class="padding"') === false
33
-                    || strpos($post_body_content, 'class="padding"') < 120
34
-                ) {
35
-                    $post_body_content = '<div class="padding">' . $post_body_content . '</div>';
36
-                }
37
-                if (strpos($post_body_content, '<div class="ee-admin-container">') === false) {
38
-                    $post_body_content = '<div class="ee-admin-container">' . $post_body_content . '</div>';
39
-                }
40
-            }
41
-            ?>
29
+		if (! empty($post_body_content)) :
30
+			if ($add_page_frame) {
31
+				if (
32
+					strpos($post_body_content, 'class="padding"') === false
33
+					|| strpos($post_body_content, 'class="padding"') < 120
34
+				) {
35
+					$post_body_content = '<div class="padding">' . $post_body_content . '</div>';
36
+				}
37
+				if (strpos($post_body_content, '<div class="ee-admin-container">') === false) {
38
+					$post_body_content = '<div class="ee-admin-container">' . $post_body_content . '</div>';
39
+				}
40
+			}
41
+			?>
42 42
             <div id="post-body-content">
43 43
                 <?php echo wp_kses($post_body_content, AllowedTags::getWithFormTags()); ?>
44 44
             </div>
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -16,26 +16,26 @@
 block discarded – undo
16 16
 do_action('add_meta_boxes', (string) $post_type, $post);
17 17
 ?>
18 18
 
19
-<?php if (! empty($admin_page_header)) : ?>
19
+<?php if ( ! empty($admin_page_header)) : ?>
20 20
     <div id="admin-page-header">
21 21
         <?php echo wp_kses($admin_page_header, AllowedTags::getWithFormTags()); ?>
22 22
     </div>
23 23
 <?php endif; ?>
24
-<div id="<?php echo esc_attr($admin_page_wrapper_div_id);?>" class="<?php echo esc_attr($admin_page_wrapper_div_class);?>">
24
+<div id="<?php echo esc_attr($admin_page_wrapper_div_id); ?>" class="<?php echo esc_attr($admin_page_wrapper_div_class); ?>">
25 25
     <!-- admin-page-header -->
26 26
     <div id="post-body" class="metabox-holder columns-2">
27 27
 
28 28
         <?php
29
-        if (! empty($post_body_content)) :
29
+        if ( ! empty($post_body_content)) :
30 30
             if ($add_page_frame) {
31 31
                 if (
32 32
                     strpos($post_body_content, 'class="padding"') === false
33 33
                     || strpos($post_body_content, 'class="padding"') < 120
34 34
                 ) {
35
-                    $post_body_content = '<div class="padding">' . $post_body_content . '</div>';
35
+                    $post_body_content = '<div class="padding">'.$post_body_content.'</div>';
36 36
                 }
37 37
                 if (strpos($post_body_content, '<div class="ee-admin-container">') === false) {
38
-                    $post_body_content = '<div class="ee-admin-container">' . $post_body_content . '</div>';
38
+                    $post_body_content = '<div class="ee-admin-container">'.$post_body_content.'</div>';
39 39
                 }
40 40
             }
41 41
             ?>
Please login to merge, or discard this patch.
display/EE_Checkbox_Dropdown_Selector_Display_Strategy.strategy.php 2 patches
Indentation   +163 added lines, -163 removed lines patch added patch discarded remove patch
@@ -11,180 +11,180 @@
 block discarded – undo
11 11
  */
12 12
 class EE_Checkbox_Dropdown_Selector_Display_Strategy extends EE_Compound_Input_Display_Strategy
13 13
 {
14
-    /**
15
-     * enqueues css and js, so that this can be called statically
16
-     */
17
-    public static function enqueue_styles_and_scripts()
18
-    {
19
-        wp_register_style(
20
-            'checkbox_dropdown_selector',
21
-            EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css',
22
-            array('espresso_default'),
23
-            EVENT_ESPRESSO_VERSION
24
-        );
25
-        wp_register_style(
26
-            'espresso_default',
27
-            EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
28
-            array('dashicons'),
29
-            EVENT_ESPRESSO_VERSION
30
-        );
31
-        wp_enqueue_style('checkbox_dropdown_selector');
32
-        wp_register_script(
33
-            'checkbox_dropdown_selector',
34
-            EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js',
35
-            array('jquery'),
36
-            EVENT_ESPRESSO_VERSION,
37
-            true
38
-        );
39
-        wp_localize_script(
40
-            'ticket_selector',
41
-            'eeDTS',
42
-            array(
43
-                'maxChecked' => EE_Registry::instance()
44
-                    ->CFG
45
-                    ->template_settings
46
-                    ->EED_Ticket_Selector
47
-                    ->getDatetimeSelectorMaxChecked()
48
-            )
49
-        );
50
-        wp_enqueue_script('checkbox_dropdown_selector');
51
-    }
14
+	/**
15
+	 * enqueues css and js, so that this can be called statically
16
+	 */
17
+	public static function enqueue_styles_and_scripts()
18
+	{
19
+		wp_register_style(
20
+			'checkbox_dropdown_selector',
21
+			EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css',
22
+			array('espresso_default'),
23
+			EVENT_ESPRESSO_VERSION
24
+		);
25
+		wp_register_style(
26
+			'espresso_default',
27
+			EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
28
+			array('dashicons'),
29
+			EVENT_ESPRESSO_VERSION
30
+		);
31
+		wp_enqueue_style('checkbox_dropdown_selector');
32
+		wp_register_script(
33
+			'checkbox_dropdown_selector',
34
+			EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js',
35
+			array('jquery'),
36
+			EVENT_ESPRESSO_VERSION,
37
+			true
38
+		);
39
+		wp_localize_script(
40
+			'ticket_selector',
41
+			'eeDTS',
42
+			array(
43
+				'maxChecked' => EE_Registry::instance()
44
+					->CFG
45
+					->template_settings
46
+					->EED_Ticket_Selector
47
+					->getDatetimeSelectorMaxChecked()
48
+			)
49
+		);
50
+		wp_enqueue_script('checkbox_dropdown_selector');
51
+	}
52 52
 
53 53
 
54 54
 
55
-    /**
56
-     * Informs the rest of the forms system what CSS and JS is needed to display the input
57
-     */
58
-    public function enqueue_js()
59
-    {
60
-        EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts();
61
-    }
55
+	/**
56
+	 * Informs the rest of the forms system what CSS and JS is needed to display the input
57
+	 */
58
+	public function enqueue_js()
59
+	{
60
+		EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts();
61
+	}
62 62
 
63 63
 
64 64
 
65
-    /**
66
-     * callback for Iframe::addStylesheets() child class methods
67
-     *
68
-     * @param array $iframe_css
69
-     * @return array
70
-     */
71
-    public function iframe_css(array $iframe_css)
72
-    {
73
-        $iframe_css['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css';
74
-        return $iframe_css;
75
-    }
65
+	/**
66
+	 * callback for Iframe::addStylesheets() child class methods
67
+	 *
68
+	 * @param array $iframe_css
69
+	 * @return array
70
+	 */
71
+	public function iframe_css(array $iframe_css)
72
+	{
73
+		$iframe_css['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css';
74
+		return $iframe_css;
75
+	}
76 76
 
77 77
 
78 78
 
79
-    /**
80
-     * callback for Iframe::addScripts() child class methods
81
-     *
82
-     * @param array $iframe_js
83
-     * @return array
84
-     */
85
-    public function iframe_js(array $iframe_js)
86
-    {
87
-        $iframe_js['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js';
88
-        return $iframe_js;
89
-    }
79
+	/**
80
+	 * callback for Iframe::addScripts() child class methods
81
+	 *
82
+	 * @param array $iframe_js
83
+	 * @return array
84
+	 */
85
+	public function iframe_js(array $iframe_js)
86
+	{
87
+		$iframe_js['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js';
88
+		return $iframe_js;
89
+	}
90 90
 
91 91
 
92
-    /**
93
-     * @throws EE_Error
94
-     * @return string of html to display the field
95
-     */
96
-    public function display()
97
-    {
98
-        $input = $this->get_input();
99
-        $select_button_text = $input instanceof EE_Checkbox_Dropdown_Selector_Input ? $input->select_button_text() : '';
100
-        // $multi = count( $input->options() ) > 1 ? TRUE : FALSE;
101
-        $input->set_label_sizes();
102
-        $label_size_class = $input->get_label_size_class();
103
-        if (! is_array($input->raw_value()) && $input->raw_value() !== null) {
104
-            EE_Error::doing_it_wrong(
105
-                'EE_Checkbox_Display_Strategy::display()',
106
-                sprintf(
107
-                    esc_html__(
108
-                        'Input values for checkboxes should be an array of values, but the value for input "%1$s" is "%2$s". Please verify that the input name is exactly "%3$s"',
109
-                        'event_espresso'
110
-                    ),
111
-                    $input->html_id(),
112
-                    var_export($input->raw_value(), true),
113
-                    $input->html_name() . '[]'
114
-                ),
115
-                '4.8.1'
116
-            );
117
-        }
92
+	/**
93
+	 * @throws EE_Error
94
+	 * @return string of html to display the field
95
+	 */
96
+	public function display()
97
+	{
98
+		$input = $this->get_input();
99
+		$select_button_text = $input instanceof EE_Checkbox_Dropdown_Selector_Input ? $input->select_button_text() : '';
100
+		// $multi = count( $input->options() ) > 1 ? TRUE : FALSE;
101
+		$input->set_label_sizes();
102
+		$label_size_class = $input->get_label_size_class();
103
+		if (! is_array($input->raw_value()) && $input->raw_value() !== null) {
104
+			EE_Error::doing_it_wrong(
105
+				'EE_Checkbox_Display_Strategy::display()',
106
+				sprintf(
107
+					esc_html__(
108
+						'Input values for checkboxes should be an array of values, but the value for input "%1$s" is "%2$s". Please verify that the input name is exactly "%3$s"',
109
+						'event_espresso'
110
+					),
111
+					$input->html_id(),
112
+					var_export($input->raw_value(), true),
113
+					$input->html_name() . '[]'
114
+				),
115
+				'4.8.1'
116
+			);
117
+		}
118 118
 
119 119
 
120
-        $html = \EEH_HTML::div('', '', 'checkbox-dropdown-selector-wrap-dv');
121
-        $html .= '<button id="' . $input->html_id() . '-btn"';
122
-        // $html .= ' name="' . $input->html_name() . '"';
123
-        $html .= ' class="' . $input->html_class() . ' checkbox-dropdown-selector-btn button--secondary button"';
124
-        $html .= ' style="' . $input->html_style() . '"';
125
-        $html .= ' data-target="' . $input->html_id() . '-options-dv"';
126
-        $html .= ' ' . $input->other_html_attributes() . '>';
127
-        $html .= '<span class="checkbox-dropdown-selector-selected-spn">';
128
-        $html .= $select_button_text;
129
-        $html .= '</span> <span class="dashicons dashicons-arrow-down"></span>';
130
-        $html .= '</button>';
131
-        $html .= EEH_HTML::div(
132
-            '',
133
-            $input->html_id() . '-options-dv',
134
-            'checkbox-dropdown-selector'
135
-        );
136
-        $html .= EEH_HTML::link(
137
-            '',
138
-            '<span class="dashicons dashicons-no"></span>',
139
-            esc_html__('close datetime selector', 'event_espresso'),
140
-            '',
141
-            'close-espresso-notice'
142
-        );
143
-        $html .= EEH_HTML::ul();
144
-        $input_raw_value = (array) $input->raw_value();
145
-        foreach ($input->options() as $value => $display_text) {
146
-            $html .= EEH_HTML::li();
147
-            $value = $input->get_normalization_strategy()->unnormalize_one($value);
148
-            $html_id = $this->get_sub_input_id($value);
149
-            $html .= EEH_HTML::nl(0, 'checkbox');
150
-            $html .= '<label for="'
151
-                     . $html_id
152
-                     . '" id="'
153
-                     . $html_id
154
-                     . '-lbl" class="ee-checkbox-label-after'
155
-                     . $label_size_class
156
-                     . '">';
157
-            $html .= EEH_HTML::nl(1, 'checkbox');
158
-            $html .= '<input type="checkbox"';
159
-            $html .= ' name="' . $input->html_name() . '[]"';
160
-            $html .= ' id="' . $html_id . '"';
161
-            $html .= ' class="' . $input->html_class() . '-option"';
162
-            $html .= $input->html_style() ? ' style="' . $input->html_style() . '"' : '';
163
-            $html .= ' value="' . esc_attr($value) . '"';
164
-            $html .= ! empty($input_raw_value) && in_array($value, $input_raw_value, true)
165
-                ? ' checked'
166
-                : '';
167
-            $html .= ' ' . $this->_input->other_html_attributes();
168
-            $html .= '>';
169
-            $html .= '<span class="datetime-selector-option-text-spn">' . $display_text . '</span>';
170
-            $html .= EEH_HTML::nl(-1, 'checkbox') . '</label>';
171
-            $html .= EEH_HTML::lix();
172
-        }
173
-        $html .= EEH_HTML::ulx();
174
-        $html .= EEH_HTML::divx();
175
-        $html .= EEH_HTML::divx();
176
-        $html .= EEH_HTML::p(
177
-            apply_filters(
178
-                'FHEE__EE_Checkbox_Dropdown_Selector_Display_Strategy__display__html',
179
-                esc_html__(
180
-                    'To view additional ticket options, click the "Filter by Date" button and select more dates.',
181
-                    'event_espresso'
182
-                )
183
-            ),
184
-            $input->html_id() . '-date-time-filter-notice-pg',
185
-            'date-time-filter-notice-pg small-text lt-grey-text'
186
-        );
187
-        $html .= \EEH_HTML::br();
188
-        return $html;
189
-    }
120
+		$html = \EEH_HTML::div('', '', 'checkbox-dropdown-selector-wrap-dv');
121
+		$html .= '<button id="' . $input->html_id() . '-btn"';
122
+		// $html .= ' name="' . $input->html_name() . '"';
123
+		$html .= ' class="' . $input->html_class() . ' checkbox-dropdown-selector-btn button--secondary button"';
124
+		$html .= ' style="' . $input->html_style() . '"';
125
+		$html .= ' data-target="' . $input->html_id() . '-options-dv"';
126
+		$html .= ' ' . $input->other_html_attributes() . '>';
127
+		$html .= '<span class="checkbox-dropdown-selector-selected-spn">';
128
+		$html .= $select_button_text;
129
+		$html .= '</span> <span class="dashicons dashicons-arrow-down"></span>';
130
+		$html .= '</button>';
131
+		$html .= EEH_HTML::div(
132
+			'',
133
+			$input->html_id() . '-options-dv',
134
+			'checkbox-dropdown-selector'
135
+		);
136
+		$html .= EEH_HTML::link(
137
+			'',
138
+			'<span class="dashicons dashicons-no"></span>',
139
+			esc_html__('close datetime selector', 'event_espresso'),
140
+			'',
141
+			'close-espresso-notice'
142
+		);
143
+		$html .= EEH_HTML::ul();
144
+		$input_raw_value = (array) $input->raw_value();
145
+		foreach ($input->options() as $value => $display_text) {
146
+			$html .= EEH_HTML::li();
147
+			$value = $input->get_normalization_strategy()->unnormalize_one($value);
148
+			$html_id = $this->get_sub_input_id($value);
149
+			$html .= EEH_HTML::nl(0, 'checkbox');
150
+			$html .= '<label for="'
151
+					 . $html_id
152
+					 . '" id="'
153
+					 . $html_id
154
+					 . '-lbl" class="ee-checkbox-label-after'
155
+					 . $label_size_class
156
+					 . '">';
157
+			$html .= EEH_HTML::nl(1, 'checkbox');
158
+			$html .= '<input type="checkbox"';
159
+			$html .= ' name="' . $input->html_name() . '[]"';
160
+			$html .= ' id="' . $html_id . '"';
161
+			$html .= ' class="' . $input->html_class() . '-option"';
162
+			$html .= $input->html_style() ? ' style="' . $input->html_style() . '"' : '';
163
+			$html .= ' value="' . esc_attr($value) . '"';
164
+			$html .= ! empty($input_raw_value) && in_array($value, $input_raw_value, true)
165
+				? ' checked'
166
+				: '';
167
+			$html .= ' ' . $this->_input->other_html_attributes();
168
+			$html .= '>';
169
+			$html .= '<span class="datetime-selector-option-text-spn">' . $display_text . '</span>';
170
+			$html .= EEH_HTML::nl(-1, 'checkbox') . '</label>';
171
+			$html .= EEH_HTML::lix();
172
+		}
173
+		$html .= EEH_HTML::ulx();
174
+		$html .= EEH_HTML::divx();
175
+		$html .= EEH_HTML::divx();
176
+		$html .= EEH_HTML::p(
177
+			apply_filters(
178
+				'FHEE__EE_Checkbox_Dropdown_Selector_Display_Strategy__display__html',
179
+				esc_html__(
180
+					'To view additional ticket options, click the "Filter by Date" button and select more dates.',
181
+					'event_espresso'
182
+				)
183
+			),
184
+			$input->html_id() . '-date-time-filter-notice-pg',
185
+			'date-time-filter-notice-pg small-text lt-grey-text'
186
+		);
187
+		$html .= \EEH_HTML::br();
188
+		return $html;
189
+	}
190 190
 }
Please login to merge, or discard this patch.
Spacing   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -18,20 +18,20 @@  discard block
 block discarded – undo
18 18
     {
19 19
         wp_register_style(
20 20
             'checkbox_dropdown_selector',
21
-            EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css',
21
+            EE_GLOBAL_ASSETS_URL.'css/checkbox_dropdown_selector.css',
22 22
             array('espresso_default'),
23 23
             EVENT_ESPRESSO_VERSION
24 24
         );
25 25
         wp_register_style(
26 26
             'espresso_default',
27
-            EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
27
+            EE_GLOBAL_ASSETS_URL.'css/espresso_default.css',
28 28
             array('dashicons'),
29 29
             EVENT_ESPRESSO_VERSION
30 30
         );
31 31
         wp_enqueue_style('checkbox_dropdown_selector');
32 32
         wp_register_script(
33 33
             'checkbox_dropdown_selector',
34
-            EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js',
34
+            EE_GLOBAL_ASSETS_URL.'scripts/checkbox_dropdown_selector.js',
35 35
             array('jquery'),
36 36
             EVENT_ESPRESSO_VERSION,
37 37
             true
@@ -70,7 +70,7 @@  discard block
 block discarded – undo
70 70
      */
71 71
     public function iframe_css(array $iframe_css)
72 72
     {
73
-        $iframe_css['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css';
73
+        $iframe_css['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL.'css/checkbox_dropdown_selector.css';
74 74
         return $iframe_css;
75 75
     }
76 76
 
@@ -84,7 +84,7 @@  discard block
 block discarded – undo
84 84
      */
85 85
     public function iframe_js(array $iframe_js)
86 86
     {
87
-        $iframe_js['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js';
87
+        $iframe_js['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL.'scripts/checkbox_dropdown_selector.js';
88 88
         return $iframe_js;
89 89
     }
90 90
 
@@ -100,7 +100,7 @@  discard block
 block discarded – undo
100 100
         // $multi = count( $input->options() ) > 1 ? TRUE : FALSE;
101 101
         $input->set_label_sizes();
102 102
         $label_size_class = $input->get_label_size_class();
103
-        if (! is_array($input->raw_value()) && $input->raw_value() !== null) {
103
+        if ( ! is_array($input->raw_value()) && $input->raw_value() !== null) {
104 104
             EE_Error::doing_it_wrong(
105 105
                 'EE_Checkbox_Display_Strategy::display()',
106 106
                 sprintf(
@@ -110,7 +110,7 @@  discard block
 block discarded – undo
110 110
                     ),
111 111
                     $input->html_id(),
112 112
                     var_export($input->raw_value(), true),
113
-                    $input->html_name() . '[]'
113
+                    $input->html_name().'[]'
114 114
                 ),
115 115
                 '4.8.1'
116 116
             );
@@ -118,19 +118,19 @@  discard block
 block discarded – undo
118 118
 
119 119
 
120 120
         $html = \EEH_HTML::div('', '', 'checkbox-dropdown-selector-wrap-dv');
121
-        $html .= '<button id="' . $input->html_id() . '-btn"';
121
+        $html .= '<button id="'.$input->html_id().'-btn"';
122 122
         // $html .= ' name="' . $input->html_name() . '"';
123
-        $html .= ' class="' . $input->html_class() . ' checkbox-dropdown-selector-btn button--secondary button"';
124
-        $html .= ' style="' . $input->html_style() . '"';
125
-        $html .= ' data-target="' . $input->html_id() . '-options-dv"';
126
-        $html .= ' ' . $input->other_html_attributes() . '>';
123
+        $html .= ' class="'.$input->html_class().' checkbox-dropdown-selector-btn button--secondary button"';
124
+        $html .= ' style="'.$input->html_style().'"';
125
+        $html .= ' data-target="'.$input->html_id().'-options-dv"';
126
+        $html .= ' '.$input->other_html_attributes().'>';
127 127
         $html .= '<span class="checkbox-dropdown-selector-selected-spn">';
128 128
         $html .= $select_button_text;
129 129
         $html .= '</span> <span class="dashicons dashicons-arrow-down"></span>';
130 130
         $html .= '</button>';
131 131
         $html .= EEH_HTML::div(
132 132
             '',
133
-            $input->html_id() . '-options-dv',
133
+            $input->html_id().'-options-dv',
134 134
             'checkbox-dropdown-selector'
135 135
         );
136 136
         $html .= EEH_HTML::link(
@@ -156,18 +156,18 @@  discard block
 block discarded – undo
156 156
                      . '">';
157 157
             $html .= EEH_HTML::nl(1, 'checkbox');
158 158
             $html .= '<input type="checkbox"';
159
-            $html .= ' name="' . $input->html_name() . '[]"';
160
-            $html .= ' id="' . $html_id . '"';
161
-            $html .= ' class="' . $input->html_class() . '-option"';
162
-            $html .= $input->html_style() ? ' style="' . $input->html_style() . '"' : '';
163
-            $html .= ' value="' . esc_attr($value) . '"';
159
+            $html .= ' name="'.$input->html_name().'[]"';
160
+            $html .= ' id="'.$html_id.'"';
161
+            $html .= ' class="'.$input->html_class().'-option"';
162
+            $html .= $input->html_style() ? ' style="'.$input->html_style().'"' : '';
163
+            $html .= ' value="'.esc_attr($value).'"';
164 164
             $html .= ! empty($input_raw_value) && in_array($value, $input_raw_value, true)
165 165
                 ? ' checked'
166 166
                 : '';
167
-            $html .= ' ' . $this->_input->other_html_attributes();
167
+            $html .= ' '.$this->_input->other_html_attributes();
168 168
             $html .= '>';
169
-            $html .= '<span class="datetime-selector-option-text-spn">' . $display_text . '</span>';
170
-            $html .= EEH_HTML::nl(-1, 'checkbox') . '</label>';
169
+            $html .= '<span class="datetime-selector-option-text-spn">'.$display_text.'</span>';
170
+            $html .= EEH_HTML::nl(-1, 'checkbox').'</label>';
171 171
             $html .= EEH_HTML::lix();
172 172
         }
173 173
         $html .= EEH_HTML::ulx();
@@ -181,7 +181,7 @@  discard block
 block discarded – undo
181 181
                     'event_espresso'
182 182
                 )
183 183
             ),
184
-            $input->html_id() . '-date-time-filter-notice-pg',
184
+            $input->html_id().'-date-time-filter-notice-pg',
185 185
             'date-time-filter-notice-pg small-text lt-grey-text'
186 186
         );
187 187
         $html .= \EEH_HTML::br();
Please login to merge, or discard this patch.
core/libraries/form_sections/form_handlers/SequentialStepFormManager.php 1 patch
Indentation   +579 added lines, -579 removed lines patch added patch discarded remove patch
@@ -30,583 +30,583 @@
 block discarded – undo
30 30
  */
31 31
 abstract class SequentialStepFormManager
32 32
 {
33
-    /**
34
-     * a simplified URL with no form related parameters
35
-     * that will be used to build the form's redirect URLs
36
-     *
37
-     * @var string $base_url
38
-     */
39
-    private $base_url = '';
40
-
41
-    /**
42
-     * the key used for the URL param that denotes the current form step
43
-     * defaults to 'ee-form-step'
44
-     *
45
-     * @var string $form_step_url_key
46
-     */
47
-    private $form_step_url_key = '';
48
-
49
-    /**
50
-     * @var string $default_form_step
51
-     */
52
-    private $default_form_step = '';
53
-
54
-    /**
55
-     * @var string $form_action
56
-     */
57
-    private $form_action;
58
-
59
-    /**
60
-     * value of one of the string constant above
61
-     *
62
-     * @var string $form_config
63
-     */
64
-    private $form_config;
65
-
66
-    /**
67
-     * @var string $progress_step_style
68
-     */
69
-    private $progress_step_style = '';
70
-
71
-    /**
72
-     * @var RequestInterface $request
73
-     */
74
-    private $request;
75
-
76
-    /**
77
-     * @var Collection $form_steps
78
-     */
79
-    protected $form_steps;
80
-
81
-    /**
82
-     * @var ProgressStepManager $progress_step_manager
83
-     */
84
-    protected $progress_step_manager;
85
-
86
-
87
-    /**
88
-     * @return Collection|null
89
-     */
90
-    abstract protected function getFormStepsCollection();
91
-
92
-    // phpcs:disable PEAR.Functions.ValidDefaultValue.NotAtEnd
93
-    /**
94
-     * StepsManager constructor
95
-     *
96
-     * @param string                           $base_url
97
-     * @param string                           $default_form_step
98
-     * @param string                           $form_action
99
-     * @param string                           $form_config
100
-     * @param EE_Request|RequestInterface|null $request
101
-     * @param string                           $progress_step_style
102
-     * @throws InvalidDataTypeException
103
-     * @throws InvalidArgumentException
104
-     */
105
-    public function __construct(
106
-        $base_url,
107
-        $default_form_step,
108
-        $form_action = '',
109
-        $form_config = FormHandler::ADD_FORM_TAGS_AND_SUBMIT,
110
-        $progress_step_style = 'number_bubbles',
111
-        $request = null
112
-    ) {
113
-        $this->setBaseUrl($base_url);
114
-        $this->setDefaultFormStep($default_form_step);
115
-        $this->setFormAction($form_action);
116
-        $this->setFormConfig($form_config);
117
-        $this->setProgressStepStyle($progress_step_style);
118
-        $this->request = $request instanceof RequestInterface
119
-            ? $request
120
-            : LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
121
-    }
122
-
123
-
124
-    /**
125
-     * @return string
126
-     * @throws InvalidFormHandlerException
127
-     */
128
-    public function baseUrl()
129
-    {
130
-        if (strpos($this->base_url, $this->getCurrentStep()->slug()) === false) {
131
-            add_query_arg(
132
-                array($this->form_step_url_key => $this->getCurrentStep()->slug()),
133
-                $this->base_url
134
-            );
135
-        }
136
-        return $this->base_url;
137
-    }
138
-
139
-
140
-    /**
141
-     * @param string $base_url
142
-     * @throws InvalidDataTypeException
143
-     * @throws InvalidArgumentException
144
-     */
145
-    protected function setBaseUrl($base_url)
146
-    {
147
-        if (! is_string($base_url)) {
148
-            throw new InvalidDataTypeException('$base_url', $base_url, 'string');
149
-        }
150
-        if (empty($base_url)) {
151
-            throw new InvalidArgumentException(
152
-                esc_html__('The base URL can not be an empty string.', 'event_espresso')
153
-            );
154
-        }
155
-        $this->base_url = $base_url;
156
-    }
157
-
158
-
159
-    /**
160
-     * @return string
161
-     * @throws InvalidDataTypeException
162
-     */
163
-    public function formStepUrlKey()
164
-    {
165
-        if (empty($this->form_step_url_key)) {
166
-            $this->setFormStepUrlKey();
167
-        }
168
-        return $this->form_step_url_key;
169
-    }
170
-
171
-
172
-    /**
173
-     * @param string $form_step_url_key
174
-     * @throws InvalidDataTypeException
175
-     */
176
-    public function setFormStepUrlKey($form_step_url_key = 'ee-form-step')
177
-    {
178
-        if (! is_string($form_step_url_key)) {
179
-            throw new InvalidDataTypeException('$form_step_key', $form_step_url_key, 'string');
180
-        }
181
-        $this->form_step_url_key = ! empty($form_step_url_key) ? $form_step_url_key : 'ee-form-step';
182
-    }
183
-
184
-
185
-    /**
186
-     * @return string
187
-     */
188
-    public function defaultFormStep()
189
-    {
190
-        return $this->default_form_step;
191
-    }
192
-
193
-
194
-    /**
195
-     * @param $default_form_step
196
-     * @throws InvalidDataTypeException
197
-     */
198
-    protected function setDefaultFormStep($default_form_step)
199
-    {
200
-        if (! is_string($default_form_step)) {
201
-            throw new InvalidDataTypeException('$default_form_step', $default_form_step, 'string');
202
-        }
203
-        $this->default_form_step = $default_form_step;
204
-    }
205
-
206
-
207
-    /**
208
-     * @return void
209
-     * @throws InvalidIdentifierException
210
-     * @throws InvalidDataTypeException
211
-     */
212
-    protected function setCurrentStepFromRequest()
213
-    {
214
-        $current_step_slug = $this->request()->getRequestParam($this->formStepUrlKey(), $this->defaultFormStep());
215
-        if (! $this->form_steps->setCurrent($current_step_slug)) {
216
-            throw new InvalidIdentifierException(
217
-                $current_step_slug,
218
-                $this->defaultFormStep(),
219
-                sprintf(
220
-                    esc_html__('The "%1$s" form step could not be set.', 'event_espresso'),
221
-                    $current_step_slug
222
-                )
223
-            );
224
-        }
225
-    }
226
-
227
-
228
-    /**
229
-     * @return SequentialStepFormInterface|object
230
-     * @throws InvalidFormHandlerException
231
-     */
232
-    public function getCurrentStep()
233
-    {
234
-        if (! $this->form_steps->current() instanceof SequentialStepForm) {
235
-            throw new InvalidFormHandlerException($this->form_steps->current());
236
-        }
237
-        return $this->form_steps->current();
238
-    }
239
-
240
-
241
-    /**
242
-     * @return string
243
-     * @throws InvalidFormHandlerException
244
-     */
245
-    public function formAction()
246
-    {
247
-        if (! is_string($this->form_action) || empty($this->form_action)) {
248
-            $this->form_action = $this->baseUrl();
249
-        }
250
-        return $this->form_action;
251
-    }
252
-
253
-
254
-    /**
255
-     * @param string $form_action
256
-     * @throws InvalidDataTypeException
257
-     */
258
-    public function setFormAction($form_action)
259
-    {
260
-        if (! is_string($form_action)) {
261
-            throw new InvalidDataTypeException('$form_action', $form_action, 'string');
262
-        }
263
-        $this->form_action = $form_action;
264
-    }
265
-
266
-
267
-    /**
268
-     * @param array $form_action_args
269
-     * @throws InvalidDataTypeException
270
-     * @throws InvalidFormHandlerException
271
-     */
272
-    public function addFormActionArgs($form_action_args = array())
273
-    {
274
-        if (! is_array($form_action_args)) {
275
-            throw new InvalidDataTypeException('$form_action_args', $form_action_args, 'array');
276
-        }
277
-        $form_action_args = ! empty($form_action_args)
278
-            ? $form_action_args
279
-            : array($this->formStepUrlKey() => $this->form_steps->current()->slug());
280
-        $this->getCurrentStep()->setFormAction(
281
-            add_query_arg($form_action_args, $this->formAction())
282
-        );
283
-        $this->form_action = $this->getCurrentStep()->formAction();
284
-    }
285
-
286
-
287
-    /**
288
-     * @return string
289
-     */
290
-    public function formConfig()
291
-    {
292
-        return $this->form_config;
293
-    }
294
-
295
-
296
-    /**
297
-     * @param string $form_config
298
-     */
299
-    public function setFormConfig($form_config)
300
-    {
301
-        $this->form_config = $form_config;
302
-    }
303
-
304
-
305
-    /**
306
-     * @return string
307
-     */
308
-    public function progressStepStyle()
309
-    {
310
-        return $this->progress_step_style;
311
-    }
312
-
313
-
314
-    /**
315
-     * @param string $progress_step_style
316
-     */
317
-    public function setProgressStepStyle($progress_step_style)
318
-    {
319
-        $this->progress_step_style = $progress_step_style;
320
-    }
321
-
322
-
323
-    /**
324
-     * @return RequestInterface
325
-     */
326
-    public function request()
327
-    {
328
-        return $this->request;
329
-    }
330
-
331
-
332
-    /**
333
-     * @return Collection|null
334
-     * @throws InvalidInterfaceException
335
-     */
336
-    protected function getProgressStepsCollection()
337
-    {
338
-        static $collection = null;
339
-        if (! $collection instanceof ProgressStepCollection) {
340
-            $collection = new ProgressStepCollection();
341
-        }
342
-        return $collection;
343
-    }
344
-
345
-
346
-    /**
347
-     * @param Collection $progress_steps_collection
348
-     * @return ProgressStepManager
349
-     * @throws InvalidInterfaceException
350
-     * @throws InvalidClassException
351
-     * @throws InvalidDataTypeException
352
-     * @throws InvalidEntityException
353
-     * @throws InvalidFormHandlerException
354
-     */
355
-    protected function generateProgressSteps(Collection $progress_steps_collection)
356
-    {
357
-        $current_step = $this->getCurrentStep();
358
-        /** @var SequentialStepForm $form_step */
359
-        foreach ($this->form_steps as $form_step) {
360
-            // is this step active ?
361
-            if (! $form_step->initialize()) {
362
-                continue;
363
-            }
364
-            $progress_steps_collection->add(
365
-                new ProgressStep(
366
-                    $form_step->order(),
367
-                    $form_step->slug(),
368
-                    $form_step->slug(),
369
-                    $form_step->formName()
370
-                ),
371
-                $form_step->slug()
372
-            );
373
-        }
374
-        // set collection pointer back to current step
375
-        $this->form_steps->setCurrentUsingObject($current_step);
376
-        return new ProgressStepManager(
377
-            $this->progressStepStyle(),
378
-            $this->defaultFormStep(),
379
-            $this->formStepUrlKey(),
380
-            $progress_steps_collection
381
-        );
382
-    }
383
-
384
-
385
-    /**
386
-     * @throws InvalidClassException
387
-     * @throws InvalidDataTypeException
388
-     * @throws InvalidEntityException
389
-     * @throws InvalidIdentifierException
390
-     * @throws InvalidInterfaceException
391
-     * @throws InvalidArgumentException
392
-     * @throws InvalidFormHandlerException
393
-     */
394
-    public function buildForm()
395
-    {
396
-        $this->buildCurrentStepFormForDisplay();
397
-    }
398
-
399
-
400
-    /**
401
-     * @param array $form_data
402
-     * @throws InvalidArgumentException
403
-     * @throws InvalidClassException
404
-     * @throws InvalidDataTypeException
405
-     * @throws InvalidEntityException
406
-     * @throws InvalidFormHandlerException
407
-     * @throws InvalidIdentifierException
408
-     * @throws InvalidInterfaceException
409
-     */
410
-    public function processForm($form_data = array())
411
-    {
412
-        $this->buildCurrentStepFormForProcessing();
413
-        $this->processCurrentStepForm($form_data);
414
-    }
415
-
416
-
417
-    /**
418
-     * @throws InvalidClassException
419
-     * @throws InvalidDataTypeException
420
-     * @throws InvalidEntityException
421
-     * @throws InvalidInterfaceException
422
-     * @throws InvalidIdentifierException
423
-     * @throws InvalidArgumentException
424
-     * @throws InvalidFormHandlerException
425
-     */
426
-    public function buildCurrentStepFormForDisplay()
427
-    {
428
-        $form_step = $this->buildCurrentStepForm();
429
-        // no displayable content ? then skip straight to processing
430
-        if (! $form_step->displayable()) {
431
-            $this->addFormActionArgs();
432
-            $form_step->setFormAction($this->formAction());
433
-            wp_safe_redirect($form_step->formAction());
434
-        }
435
-    }
436
-
437
-
438
-    /**
439
-     * @throws InvalidClassException
440
-     * @throws InvalidDataTypeException
441
-     * @throws InvalidEntityException
442
-     * @throws InvalidInterfaceException
443
-     * @throws InvalidIdentifierException
444
-     * @throws InvalidArgumentException
445
-     * @throws InvalidFormHandlerException
446
-     */
447
-    public function buildCurrentStepFormForProcessing()
448
-    {
449
-        $this->buildCurrentStepForm(false);
450
-    }
451
-
452
-
453
-    /**
454
-     * @param bool $for_display
455
-     * @return SequentialStepFormInterface
456
-     * @throws InvalidArgumentException
457
-     * @throws InvalidClassException
458
-     * @throws InvalidDataTypeException
459
-     * @throws InvalidEntityException
460
-     * @throws InvalidFormHandlerException
461
-     * @throws InvalidIdentifierException
462
-     * @throws InvalidInterfaceException
463
-     */
464
-    private function buildCurrentStepForm($for_display = true)
465
-    {
466
-        $this->form_steps = $this->getFormStepsCollection();
467
-        $this->setCurrentStepFromRequest();
468
-        $form_step = $this->getCurrentStep();
469
-        if ($form_step->submitBtnText() === esc_html__('Submit', 'event_espresso')) {
470
-            $form_step->setSubmitBtnText(esc_html__('Next Step', 'event_espresso'));
471
-        }
472
-        if ($for_display && $form_step->displayable()) {
473
-            $this->progress_step_manager = $this->generateProgressSteps(
474
-                $this->getProgressStepsCollection()
475
-            );
476
-            $this->progress_step_manager->setCurrentStep(
477
-                $form_step->slug()
478
-            );
479
-            // mark all previous progress steps as completed
480
-            $this->progress_step_manager->setPreviousStepsCompleted();
481
-            $this->progress_step_manager->enqueueStylesAndScripts();
482
-            $this->addFormActionArgs();
483
-            $form_step->setFormAction($this->formAction());
484
-        } else {
485
-            $form_step->setRedirectUrl($this->baseUrl());
486
-            $form_step->addRedirectArgs(
487
-                array($this->formStepUrlKey() => $this->form_steps->current()->slug())
488
-            );
489
-        }
490
-        $form_step->generate();
491
-        if ($for_display) {
492
-            $form_step->enqueueStylesAndScripts();
493
-        }
494
-        return $form_step;
495
-    }
496
-
497
-
498
-    /**
499
-     * @param bool $return_as_string
500
-     * @return string
501
-     * @throws InvalidFormHandlerException
502
-     */
503
-    public function displayProgressSteps($return_as_string = true)
504
-    {
505
-        $form_step = $this->getCurrentStep();
506
-        if (! $form_step->displayable()) {
507
-            return '';
508
-        }
509
-        $progress_steps = apply_filters(
510
-            'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_SequentialStepFormManager__displayProgressSteps__before_steps',
511
-            ''
512
-        );
513
-        $progress_steps .= $this->progress_step_manager->displaySteps();
514
-        $progress_steps .= apply_filters(
515
-            'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_SequentialStepFormManager__displayProgressSteps__after_steps',
516
-            ''
517
-        );
518
-        if ($return_as_string) {
519
-            return $progress_steps;
520
-        }
521
-        echo wp_kses($progress_steps, AllowedTags::getWithFormTags());
522
-        return '';
523
-    }
524
-
525
-
526
-    /**
527
-     * @param bool $return_as_string
528
-     * @return string
529
-     * @throws InvalidFormHandlerException
530
-     */
531
-    public function displayCurrentStepForm($return_as_string = true)
532
-    {
533
-        if ($return_as_string) {
534
-            return $this->getCurrentStep()->display();
535
-        }
536
-        echo wp_kses($this->getCurrentStep()->display(), AllowedTags::getWithFormTags());
537
-        return '';
538
-    }
539
-
540
-
541
-    /**
542
-     * @param array $form_data
543
-     * @return void
544
-     * @throws InvalidArgumentException
545
-     * @throws InvalidDataTypeException
546
-     * @throws InvalidFormHandlerException
547
-     */
548
-    public function processCurrentStepForm($form_data = array())
549
-    {
550
-        // grab instance of current step because after calling next() below,
551
-        // any calls to getCurrentStep() will return the "next" step because we advanced
552
-        $current_step = $this->getCurrentStep();
553
-        try {
554
-            // form processing should either throw exceptions or return true
555
-            $current_step->process($form_data);
556
-        } catch (Exception $e) {
557
-            // something went wrong, convert the Exception to an EE_Error
558
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
559
-            // prevent redirect to next step or other if exception was thrown
560
-            if (
561
-                $current_step->redirectTo() === SequentialStepForm::REDIRECT_TO_NEXT_STEP
562
-                || $current_step->redirectTo() === SequentialStepForm::REDIRECT_TO_OTHER
563
-            ) {
564
-                $current_step->setRedirectTo(SequentialStepForm::REDIRECT_TO_CURRENT_STEP);
565
-            }
566
-        }
567
-        // save notices to a transient so that when we redirect back
568
-        // to the display portion for this step
569
-        // those notices can be displayed
570
-        EE_Error::get_notices(false, true);
571
-        $this->redirectForm($current_step);
572
-    }
573
-
574
-
575
-    /**
576
-     * handles where to go to next
577
-     *
578
-     * @param SequentialStepFormInterface $current_step
579
-     * @throws InvalidArgumentException
580
-     * @throws InvalidDataTypeException
581
-     * @throws InvalidFormHandlerException
582
-     */
583
-    public function redirectForm(SequentialStepFormInterface $current_step)
584
-    {
585
-        $redirect_step = $current_step;
586
-        switch ($current_step->redirectTo()) {
587
-            case SequentialStepForm::REDIRECT_TO_OTHER:
588
-                // going somewhere else, so just check out now
589
-                wp_safe_redirect($redirect_step->redirectUrl());
590
-                exit();
591
-            case SequentialStepForm::REDIRECT_TO_PREV_STEP:
592
-                $redirect_step = $this->form_steps->previous();
593
-                break;
594
-            case SequentialStepForm::REDIRECT_TO_NEXT_STEP:
595
-                $this->form_steps->next();
596
-                if ($this->form_steps->valid()) {
597
-                    $redirect_step = $this->form_steps->current();
598
-                }
599
-                break;
600
-            case SequentialStepForm::REDIRECT_TO_CURRENT_STEP:
601
-            default:
602
-                // $redirect_step is already set
603
-        }
604
-        $current_step->setRedirectUrl($this->baseUrl());
605
-        $current_step->addRedirectArgs(
606
-            // use the slug for whatever step we are redirecting too
607
-            array($this->formStepUrlKey() => $redirect_step->slug())
608
-        );
609
-        wp_safe_redirect($current_step->redirectUrl());
610
-        exit();
611
-    }
33
+	/**
34
+	 * a simplified URL with no form related parameters
35
+	 * that will be used to build the form's redirect URLs
36
+	 *
37
+	 * @var string $base_url
38
+	 */
39
+	private $base_url = '';
40
+
41
+	/**
42
+	 * the key used for the URL param that denotes the current form step
43
+	 * defaults to 'ee-form-step'
44
+	 *
45
+	 * @var string $form_step_url_key
46
+	 */
47
+	private $form_step_url_key = '';
48
+
49
+	/**
50
+	 * @var string $default_form_step
51
+	 */
52
+	private $default_form_step = '';
53
+
54
+	/**
55
+	 * @var string $form_action
56
+	 */
57
+	private $form_action;
58
+
59
+	/**
60
+	 * value of one of the string constant above
61
+	 *
62
+	 * @var string $form_config
63
+	 */
64
+	private $form_config;
65
+
66
+	/**
67
+	 * @var string $progress_step_style
68
+	 */
69
+	private $progress_step_style = '';
70
+
71
+	/**
72
+	 * @var RequestInterface $request
73
+	 */
74
+	private $request;
75
+
76
+	/**
77
+	 * @var Collection $form_steps
78
+	 */
79
+	protected $form_steps;
80
+
81
+	/**
82
+	 * @var ProgressStepManager $progress_step_manager
83
+	 */
84
+	protected $progress_step_manager;
85
+
86
+
87
+	/**
88
+	 * @return Collection|null
89
+	 */
90
+	abstract protected function getFormStepsCollection();
91
+
92
+	// phpcs:disable PEAR.Functions.ValidDefaultValue.NotAtEnd
93
+	/**
94
+	 * StepsManager constructor
95
+	 *
96
+	 * @param string                           $base_url
97
+	 * @param string                           $default_form_step
98
+	 * @param string                           $form_action
99
+	 * @param string                           $form_config
100
+	 * @param EE_Request|RequestInterface|null $request
101
+	 * @param string                           $progress_step_style
102
+	 * @throws InvalidDataTypeException
103
+	 * @throws InvalidArgumentException
104
+	 */
105
+	public function __construct(
106
+		$base_url,
107
+		$default_form_step,
108
+		$form_action = '',
109
+		$form_config = FormHandler::ADD_FORM_TAGS_AND_SUBMIT,
110
+		$progress_step_style = 'number_bubbles',
111
+		$request = null
112
+	) {
113
+		$this->setBaseUrl($base_url);
114
+		$this->setDefaultFormStep($default_form_step);
115
+		$this->setFormAction($form_action);
116
+		$this->setFormConfig($form_config);
117
+		$this->setProgressStepStyle($progress_step_style);
118
+		$this->request = $request instanceof RequestInterface
119
+			? $request
120
+			: LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
121
+	}
122
+
123
+
124
+	/**
125
+	 * @return string
126
+	 * @throws InvalidFormHandlerException
127
+	 */
128
+	public function baseUrl()
129
+	{
130
+		if (strpos($this->base_url, $this->getCurrentStep()->slug()) === false) {
131
+			add_query_arg(
132
+				array($this->form_step_url_key => $this->getCurrentStep()->slug()),
133
+				$this->base_url
134
+			);
135
+		}
136
+		return $this->base_url;
137
+	}
138
+
139
+
140
+	/**
141
+	 * @param string $base_url
142
+	 * @throws InvalidDataTypeException
143
+	 * @throws InvalidArgumentException
144
+	 */
145
+	protected function setBaseUrl($base_url)
146
+	{
147
+		if (! is_string($base_url)) {
148
+			throw new InvalidDataTypeException('$base_url', $base_url, 'string');
149
+		}
150
+		if (empty($base_url)) {
151
+			throw new InvalidArgumentException(
152
+				esc_html__('The base URL can not be an empty string.', 'event_espresso')
153
+			);
154
+		}
155
+		$this->base_url = $base_url;
156
+	}
157
+
158
+
159
+	/**
160
+	 * @return string
161
+	 * @throws InvalidDataTypeException
162
+	 */
163
+	public function formStepUrlKey()
164
+	{
165
+		if (empty($this->form_step_url_key)) {
166
+			$this->setFormStepUrlKey();
167
+		}
168
+		return $this->form_step_url_key;
169
+	}
170
+
171
+
172
+	/**
173
+	 * @param string $form_step_url_key
174
+	 * @throws InvalidDataTypeException
175
+	 */
176
+	public function setFormStepUrlKey($form_step_url_key = 'ee-form-step')
177
+	{
178
+		if (! is_string($form_step_url_key)) {
179
+			throw new InvalidDataTypeException('$form_step_key', $form_step_url_key, 'string');
180
+		}
181
+		$this->form_step_url_key = ! empty($form_step_url_key) ? $form_step_url_key : 'ee-form-step';
182
+	}
183
+
184
+
185
+	/**
186
+	 * @return string
187
+	 */
188
+	public function defaultFormStep()
189
+	{
190
+		return $this->default_form_step;
191
+	}
192
+
193
+
194
+	/**
195
+	 * @param $default_form_step
196
+	 * @throws InvalidDataTypeException
197
+	 */
198
+	protected function setDefaultFormStep($default_form_step)
199
+	{
200
+		if (! is_string($default_form_step)) {
201
+			throw new InvalidDataTypeException('$default_form_step', $default_form_step, 'string');
202
+		}
203
+		$this->default_form_step = $default_form_step;
204
+	}
205
+
206
+
207
+	/**
208
+	 * @return void
209
+	 * @throws InvalidIdentifierException
210
+	 * @throws InvalidDataTypeException
211
+	 */
212
+	protected function setCurrentStepFromRequest()
213
+	{
214
+		$current_step_slug = $this->request()->getRequestParam($this->formStepUrlKey(), $this->defaultFormStep());
215
+		if (! $this->form_steps->setCurrent($current_step_slug)) {
216
+			throw new InvalidIdentifierException(
217
+				$current_step_slug,
218
+				$this->defaultFormStep(),
219
+				sprintf(
220
+					esc_html__('The "%1$s" form step could not be set.', 'event_espresso'),
221
+					$current_step_slug
222
+				)
223
+			);
224
+		}
225
+	}
226
+
227
+
228
+	/**
229
+	 * @return SequentialStepFormInterface|object
230
+	 * @throws InvalidFormHandlerException
231
+	 */
232
+	public function getCurrentStep()
233
+	{
234
+		if (! $this->form_steps->current() instanceof SequentialStepForm) {
235
+			throw new InvalidFormHandlerException($this->form_steps->current());
236
+		}
237
+		return $this->form_steps->current();
238
+	}
239
+
240
+
241
+	/**
242
+	 * @return string
243
+	 * @throws InvalidFormHandlerException
244
+	 */
245
+	public function formAction()
246
+	{
247
+		if (! is_string($this->form_action) || empty($this->form_action)) {
248
+			$this->form_action = $this->baseUrl();
249
+		}
250
+		return $this->form_action;
251
+	}
252
+
253
+
254
+	/**
255
+	 * @param string $form_action
256
+	 * @throws InvalidDataTypeException
257
+	 */
258
+	public function setFormAction($form_action)
259
+	{
260
+		if (! is_string($form_action)) {
261
+			throw new InvalidDataTypeException('$form_action', $form_action, 'string');
262
+		}
263
+		$this->form_action = $form_action;
264
+	}
265
+
266
+
267
+	/**
268
+	 * @param array $form_action_args
269
+	 * @throws InvalidDataTypeException
270
+	 * @throws InvalidFormHandlerException
271
+	 */
272
+	public function addFormActionArgs($form_action_args = array())
273
+	{
274
+		if (! is_array($form_action_args)) {
275
+			throw new InvalidDataTypeException('$form_action_args', $form_action_args, 'array');
276
+		}
277
+		$form_action_args = ! empty($form_action_args)
278
+			? $form_action_args
279
+			: array($this->formStepUrlKey() => $this->form_steps->current()->slug());
280
+		$this->getCurrentStep()->setFormAction(
281
+			add_query_arg($form_action_args, $this->formAction())
282
+		);
283
+		$this->form_action = $this->getCurrentStep()->formAction();
284
+	}
285
+
286
+
287
+	/**
288
+	 * @return string
289
+	 */
290
+	public function formConfig()
291
+	{
292
+		return $this->form_config;
293
+	}
294
+
295
+
296
+	/**
297
+	 * @param string $form_config
298
+	 */
299
+	public function setFormConfig($form_config)
300
+	{
301
+		$this->form_config = $form_config;
302
+	}
303
+
304
+
305
+	/**
306
+	 * @return string
307
+	 */
308
+	public function progressStepStyle()
309
+	{
310
+		return $this->progress_step_style;
311
+	}
312
+
313
+
314
+	/**
315
+	 * @param string $progress_step_style
316
+	 */
317
+	public function setProgressStepStyle($progress_step_style)
318
+	{
319
+		$this->progress_step_style = $progress_step_style;
320
+	}
321
+
322
+
323
+	/**
324
+	 * @return RequestInterface
325
+	 */
326
+	public function request()
327
+	{
328
+		return $this->request;
329
+	}
330
+
331
+
332
+	/**
333
+	 * @return Collection|null
334
+	 * @throws InvalidInterfaceException
335
+	 */
336
+	protected function getProgressStepsCollection()
337
+	{
338
+		static $collection = null;
339
+		if (! $collection instanceof ProgressStepCollection) {
340
+			$collection = new ProgressStepCollection();
341
+		}
342
+		return $collection;
343
+	}
344
+
345
+
346
+	/**
347
+	 * @param Collection $progress_steps_collection
348
+	 * @return ProgressStepManager
349
+	 * @throws InvalidInterfaceException
350
+	 * @throws InvalidClassException
351
+	 * @throws InvalidDataTypeException
352
+	 * @throws InvalidEntityException
353
+	 * @throws InvalidFormHandlerException
354
+	 */
355
+	protected function generateProgressSteps(Collection $progress_steps_collection)
356
+	{
357
+		$current_step = $this->getCurrentStep();
358
+		/** @var SequentialStepForm $form_step */
359
+		foreach ($this->form_steps as $form_step) {
360
+			// is this step active ?
361
+			if (! $form_step->initialize()) {
362
+				continue;
363
+			}
364
+			$progress_steps_collection->add(
365
+				new ProgressStep(
366
+					$form_step->order(),
367
+					$form_step->slug(),
368
+					$form_step->slug(),
369
+					$form_step->formName()
370
+				),
371
+				$form_step->slug()
372
+			);
373
+		}
374
+		// set collection pointer back to current step
375
+		$this->form_steps->setCurrentUsingObject($current_step);
376
+		return new ProgressStepManager(
377
+			$this->progressStepStyle(),
378
+			$this->defaultFormStep(),
379
+			$this->formStepUrlKey(),
380
+			$progress_steps_collection
381
+		);
382
+	}
383
+
384
+
385
+	/**
386
+	 * @throws InvalidClassException
387
+	 * @throws InvalidDataTypeException
388
+	 * @throws InvalidEntityException
389
+	 * @throws InvalidIdentifierException
390
+	 * @throws InvalidInterfaceException
391
+	 * @throws InvalidArgumentException
392
+	 * @throws InvalidFormHandlerException
393
+	 */
394
+	public function buildForm()
395
+	{
396
+		$this->buildCurrentStepFormForDisplay();
397
+	}
398
+
399
+
400
+	/**
401
+	 * @param array $form_data
402
+	 * @throws InvalidArgumentException
403
+	 * @throws InvalidClassException
404
+	 * @throws InvalidDataTypeException
405
+	 * @throws InvalidEntityException
406
+	 * @throws InvalidFormHandlerException
407
+	 * @throws InvalidIdentifierException
408
+	 * @throws InvalidInterfaceException
409
+	 */
410
+	public function processForm($form_data = array())
411
+	{
412
+		$this->buildCurrentStepFormForProcessing();
413
+		$this->processCurrentStepForm($form_data);
414
+	}
415
+
416
+
417
+	/**
418
+	 * @throws InvalidClassException
419
+	 * @throws InvalidDataTypeException
420
+	 * @throws InvalidEntityException
421
+	 * @throws InvalidInterfaceException
422
+	 * @throws InvalidIdentifierException
423
+	 * @throws InvalidArgumentException
424
+	 * @throws InvalidFormHandlerException
425
+	 */
426
+	public function buildCurrentStepFormForDisplay()
427
+	{
428
+		$form_step = $this->buildCurrentStepForm();
429
+		// no displayable content ? then skip straight to processing
430
+		if (! $form_step->displayable()) {
431
+			$this->addFormActionArgs();
432
+			$form_step->setFormAction($this->formAction());
433
+			wp_safe_redirect($form_step->formAction());
434
+		}
435
+	}
436
+
437
+
438
+	/**
439
+	 * @throws InvalidClassException
440
+	 * @throws InvalidDataTypeException
441
+	 * @throws InvalidEntityException
442
+	 * @throws InvalidInterfaceException
443
+	 * @throws InvalidIdentifierException
444
+	 * @throws InvalidArgumentException
445
+	 * @throws InvalidFormHandlerException
446
+	 */
447
+	public function buildCurrentStepFormForProcessing()
448
+	{
449
+		$this->buildCurrentStepForm(false);
450
+	}
451
+
452
+
453
+	/**
454
+	 * @param bool $for_display
455
+	 * @return SequentialStepFormInterface
456
+	 * @throws InvalidArgumentException
457
+	 * @throws InvalidClassException
458
+	 * @throws InvalidDataTypeException
459
+	 * @throws InvalidEntityException
460
+	 * @throws InvalidFormHandlerException
461
+	 * @throws InvalidIdentifierException
462
+	 * @throws InvalidInterfaceException
463
+	 */
464
+	private function buildCurrentStepForm($for_display = true)
465
+	{
466
+		$this->form_steps = $this->getFormStepsCollection();
467
+		$this->setCurrentStepFromRequest();
468
+		$form_step = $this->getCurrentStep();
469
+		if ($form_step->submitBtnText() === esc_html__('Submit', 'event_espresso')) {
470
+			$form_step->setSubmitBtnText(esc_html__('Next Step', 'event_espresso'));
471
+		}
472
+		if ($for_display && $form_step->displayable()) {
473
+			$this->progress_step_manager = $this->generateProgressSteps(
474
+				$this->getProgressStepsCollection()
475
+			);
476
+			$this->progress_step_manager->setCurrentStep(
477
+				$form_step->slug()
478
+			);
479
+			// mark all previous progress steps as completed
480
+			$this->progress_step_manager->setPreviousStepsCompleted();
481
+			$this->progress_step_manager->enqueueStylesAndScripts();
482
+			$this->addFormActionArgs();
483
+			$form_step->setFormAction($this->formAction());
484
+		} else {
485
+			$form_step->setRedirectUrl($this->baseUrl());
486
+			$form_step->addRedirectArgs(
487
+				array($this->formStepUrlKey() => $this->form_steps->current()->slug())
488
+			);
489
+		}
490
+		$form_step->generate();
491
+		if ($for_display) {
492
+			$form_step->enqueueStylesAndScripts();
493
+		}
494
+		return $form_step;
495
+	}
496
+
497
+
498
+	/**
499
+	 * @param bool $return_as_string
500
+	 * @return string
501
+	 * @throws InvalidFormHandlerException
502
+	 */
503
+	public function displayProgressSteps($return_as_string = true)
504
+	{
505
+		$form_step = $this->getCurrentStep();
506
+		if (! $form_step->displayable()) {
507
+			return '';
508
+		}
509
+		$progress_steps = apply_filters(
510
+			'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_SequentialStepFormManager__displayProgressSteps__before_steps',
511
+			''
512
+		);
513
+		$progress_steps .= $this->progress_step_manager->displaySteps();
514
+		$progress_steps .= apply_filters(
515
+			'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_SequentialStepFormManager__displayProgressSteps__after_steps',
516
+			''
517
+		);
518
+		if ($return_as_string) {
519
+			return $progress_steps;
520
+		}
521
+		echo wp_kses($progress_steps, AllowedTags::getWithFormTags());
522
+		return '';
523
+	}
524
+
525
+
526
+	/**
527
+	 * @param bool $return_as_string
528
+	 * @return string
529
+	 * @throws InvalidFormHandlerException
530
+	 */
531
+	public function displayCurrentStepForm($return_as_string = true)
532
+	{
533
+		if ($return_as_string) {
534
+			return $this->getCurrentStep()->display();
535
+		}
536
+		echo wp_kses($this->getCurrentStep()->display(), AllowedTags::getWithFormTags());
537
+		return '';
538
+	}
539
+
540
+
541
+	/**
542
+	 * @param array $form_data
543
+	 * @return void
544
+	 * @throws InvalidArgumentException
545
+	 * @throws InvalidDataTypeException
546
+	 * @throws InvalidFormHandlerException
547
+	 */
548
+	public function processCurrentStepForm($form_data = array())
549
+	{
550
+		// grab instance of current step because after calling next() below,
551
+		// any calls to getCurrentStep() will return the "next" step because we advanced
552
+		$current_step = $this->getCurrentStep();
553
+		try {
554
+			// form processing should either throw exceptions or return true
555
+			$current_step->process($form_data);
556
+		} catch (Exception $e) {
557
+			// something went wrong, convert the Exception to an EE_Error
558
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
559
+			// prevent redirect to next step or other if exception was thrown
560
+			if (
561
+				$current_step->redirectTo() === SequentialStepForm::REDIRECT_TO_NEXT_STEP
562
+				|| $current_step->redirectTo() === SequentialStepForm::REDIRECT_TO_OTHER
563
+			) {
564
+				$current_step->setRedirectTo(SequentialStepForm::REDIRECT_TO_CURRENT_STEP);
565
+			}
566
+		}
567
+		// save notices to a transient so that when we redirect back
568
+		// to the display portion for this step
569
+		// those notices can be displayed
570
+		EE_Error::get_notices(false, true);
571
+		$this->redirectForm($current_step);
572
+	}
573
+
574
+
575
+	/**
576
+	 * handles where to go to next
577
+	 *
578
+	 * @param SequentialStepFormInterface $current_step
579
+	 * @throws InvalidArgumentException
580
+	 * @throws InvalidDataTypeException
581
+	 * @throws InvalidFormHandlerException
582
+	 */
583
+	public function redirectForm(SequentialStepFormInterface $current_step)
584
+	{
585
+		$redirect_step = $current_step;
586
+		switch ($current_step->redirectTo()) {
587
+			case SequentialStepForm::REDIRECT_TO_OTHER:
588
+				// going somewhere else, so just check out now
589
+				wp_safe_redirect($redirect_step->redirectUrl());
590
+				exit();
591
+			case SequentialStepForm::REDIRECT_TO_PREV_STEP:
592
+				$redirect_step = $this->form_steps->previous();
593
+				break;
594
+			case SequentialStepForm::REDIRECT_TO_NEXT_STEP:
595
+				$this->form_steps->next();
596
+				if ($this->form_steps->valid()) {
597
+					$redirect_step = $this->form_steps->current();
598
+				}
599
+				break;
600
+			case SequentialStepForm::REDIRECT_TO_CURRENT_STEP:
601
+			default:
602
+				// $redirect_step is already set
603
+		}
604
+		$current_step->setRedirectUrl($this->baseUrl());
605
+		$current_step->addRedirectArgs(
606
+			// use the slug for whatever step we are redirecting too
607
+			array($this->formStepUrlKey() => $redirect_step->slug())
608
+		);
609
+		wp_safe_redirect($current_step->redirectUrl());
610
+		exit();
611
+	}
612 612
 }
Please login to merge, or discard this patch.