Completed
Pull Request — master (#1147)
by
unknown
86:03 queued 53:30
created
core/db_classes/EE_Ticket_Price.class.php 1 patch
Indentation   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -11,25 +11,25 @@
 block discarded – undo
11 11
 class EE_Ticket_Price extends EE_Base_Class
12 12
 {
13 13
 
14
-    /**
15
-     * @param array  $props_n_values
16
-     * @param string $timezone
17
-     * @return EE_Ticket_Price|mixed
18
-     */
19
-    public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array())
20
-    {
21
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
22
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
23
-    }
14
+	/**
15
+	 * @param array  $props_n_values
16
+	 * @param string $timezone
17
+	 * @return EE_Ticket_Price|mixed
18
+	 */
19
+	public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array())
20
+	{
21
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
22
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
23
+	}
24 24
 
25 25
 
26
-    /**
27
-     * @param array  $props_n_values
28
-     * @param string $timezone
29
-     * @return EE_Ticket_Price
30
-     */
31
-    public static function new_instance_from_db($props_n_values = array(), $timezone = '')
32
-    {
33
-        return new self($props_n_values, true, $timezone);
34
-    }
26
+	/**
27
+	 * @param array  $props_n_values
28
+	 * @param string $timezone
29
+	 * @return EE_Ticket_Price
30
+	 */
31
+	public static function new_instance_from_db($props_n_values = array(), $timezone = '')
32
+	{
33
+		return new self($props_n_values, true, $timezone);
34
+	}
35 35
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Ticket_Template.class.php 1 patch
Indentation   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -12,25 +12,25 @@
 block discarded – undo
12 12
 class EE_Ticket_Template extends EE_Base_Class
13 13
 {
14 14
 
15
-    /**
16
-     * @param array  $props_n_values
17
-     * @param string $timezone
18
-     * @return EE_Ticket_Template|mixed
19
-     */
20
-    public static function new_instance($props_n_values = array(), $timezone = '')
21
-    {
22
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone);
23
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone);
24
-    }
15
+	/**
16
+	 * @param array  $props_n_values
17
+	 * @param string $timezone
18
+	 * @return EE_Ticket_Template|mixed
19
+	 */
20
+	public static function new_instance($props_n_values = array(), $timezone = '')
21
+	{
22
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone);
23
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone);
24
+	}
25 25
 
26 26
 
27
-    /**
28
-     * @param array  $props_n_values
29
-     * @param string $timezone
30
-     * @return EE_Ticket_Template
31
-     */
32
-    public static function new_instance_from_db($props_n_values = array(), $timezone = '')
33
-    {
34
-        return new self($props_n_values, true, $timezone);
35
-    }
27
+	/**
28
+	 * @param array  $props_n_values
29
+	 * @param string $timezone
30
+	 * @return EE_Ticket_Template
31
+	 */
32
+	public static function new_instance_from_db($props_n_values = array(), $timezone = '')
33
+	{
34
+		return new self($props_n_values, true, $timezone);
35
+	}
36 36
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Extra_Meta.class.php 1 patch
Indentation   +111 added lines, -111 removed lines patch added patch discarded remove patch
@@ -10,115 +10,115 @@
 block discarded – undo
10 10
 class EE_Extra_Meta extends EE_Base_Class
11 11
 {
12 12
 
13
-    /**
14
-     * @param array $props_n_values
15
-     * @return EE_Extra_Meta|mixed
16
-     */
17
-    public static function new_instance($props_n_values = array())
18
-    {
19
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
20
-        return $has_object ? $has_object : new self($props_n_values);
21
-    }
22
-
23
-
24
-    /**
25
-     * @param array $props_n_values
26
-     * @return EE_Extra_Meta
27
-     */
28
-    public static function new_instance_from_db($props_n_values = array())
29
-    {
30
-        return new self($props_n_values, true);
31
-    }
32
-
33
-
34
-    /**
35
-     * Gets FK_ID
36
-     *
37
-     * @return int
38
-     */
39
-    public function FK_ID()
40
-    {
41
-        return $this->get('FK_ID');
42
-    }
43
-
44
-
45
-    /**
46
-     * Sets FK_ID
47
-     *
48
-     * @param int $FK_ID
49
-     * @return boolean
50
-     */
51
-    public function set_FK_ID($FK_ID)
52
-    {
53
-        $this->set('FK_ID', $FK_ID);
54
-    }
55
-
56
-
57
-    /**
58
-     * Gets model
59
-     *
60
-     * @return string
61
-     */
62
-    public function model()
63
-    {
64
-        return $this->get('EXM_model');
65
-    }
66
-
67
-
68
-    /**
69
-     * Sets model
70
-     *
71
-     * @param string $model
72
-     * @return boolean
73
-     */
74
-    public function set_model($model)
75
-    {
76
-        $this->set('EXM_model', $model);
77
-    }
78
-
79
-
80
-    /**
81
-     * Gets key
82
-     *
83
-     * @return string
84
-     */
85
-    public function key()
86
-    {
87
-        return $this->get('EXM_key');
88
-    }
89
-
90
-
91
-    /**
92
-     * Sets key
93
-     *
94
-     * @param string $key
95
-     * @return boolean
96
-     */
97
-    public function set_key($key)
98
-    {
99
-        $this->set('EXM_key', $key);
100
-    }
101
-
102
-
103
-    /**
104
-     * Gets value
105
-     *
106
-     * @return string
107
-     */
108
-    public function value()
109
-    {
110
-        return $this->get('EXM_value');
111
-    }
112
-
113
-
114
-    /**
115
-     * Sets value
116
-     *
117
-     * @param string $value
118
-     * @return boolean
119
-     */
120
-    public function set_value($value)
121
-    {
122
-        $this->set('EXM_value', $value);
123
-    }
13
+	/**
14
+	 * @param array $props_n_values
15
+	 * @return EE_Extra_Meta|mixed
16
+	 */
17
+	public static function new_instance($props_n_values = array())
18
+	{
19
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
20
+		return $has_object ? $has_object : new self($props_n_values);
21
+	}
22
+
23
+
24
+	/**
25
+	 * @param array $props_n_values
26
+	 * @return EE_Extra_Meta
27
+	 */
28
+	public static function new_instance_from_db($props_n_values = array())
29
+	{
30
+		return new self($props_n_values, true);
31
+	}
32
+
33
+
34
+	/**
35
+	 * Gets FK_ID
36
+	 *
37
+	 * @return int
38
+	 */
39
+	public function FK_ID()
40
+	{
41
+		return $this->get('FK_ID');
42
+	}
43
+
44
+
45
+	/**
46
+	 * Sets FK_ID
47
+	 *
48
+	 * @param int $FK_ID
49
+	 * @return boolean
50
+	 */
51
+	public function set_FK_ID($FK_ID)
52
+	{
53
+		$this->set('FK_ID', $FK_ID);
54
+	}
55
+
56
+
57
+	/**
58
+	 * Gets model
59
+	 *
60
+	 * @return string
61
+	 */
62
+	public function model()
63
+	{
64
+		return $this->get('EXM_model');
65
+	}
66
+
67
+
68
+	/**
69
+	 * Sets model
70
+	 *
71
+	 * @param string $model
72
+	 * @return boolean
73
+	 */
74
+	public function set_model($model)
75
+	{
76
+		$this->set('EXM_model', $model);
77
+	}
78
+
79
+
80
+	/**
81
+	 * Gets key
82
+	 *
83
+	 * @return string
84
+	 */
85
+	public function key()
86
+	{
87
+		return $this->get('EXM_key');
88
+	}
89
+
90
+
91
+	/**
92
+	 * Sets key
93
+	 *
94
+	 * @param string $key
95
+	 * @return boolean
96
+	 */
97
+	public function set_key($key)
98
+	{
99
+		$this->set('EXM_key', $key);
100
+	}
101
+
102
+
103
+	/**
104
+	 * Gets value
105
+	 *
106
+	 * @return string
107
+	 */
108
+	public function value()
109
+	{
110
+		return $this->get('EXM_value');
111
+	}
112
+
113
+
114
+	/**
115
+	 * Sets value
116
+	 *
117
+	 * @param string $value
118
+	 * @return boolean
119
+	 */
120
+	public function set_value($value)
121
+	{
122
+		$this->set('EXM_value', $value);
123
+	}
124 124
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Import.class.php 2 patches
Indentation   +950 added lines, -950 removed lines patch added patch discarded remove patch
@@ -14,91 +14,91 @@  discard block
 block discarded – undo
14 14
 class EE_Import implements ResettableInterface
15 15
 {
16 16
 
17
-    const do_insert = 'insert';
18
-    const do_update = 'update';
19
-    const do_nothing = 'nothing';
20
-
21
-
22
-    // instance of the EE_Import object
23
-    private static $_instance = null;
24
-
25
-    private static $_csv_array = array();
26
-
27
-    /**
28
-     *
29
-     * @var array of model names
30
-     */
31
-    private static $_model_list = array();
32
-
33
-    private static $_columns_to_save = array();
34
-
35
-    protected $_total_inserts = 0;
36
-    protected $_total_updates = 0;
37
-    protected $_total_insert_errors = 0;
38
-    protected $_total_update_errors = 0;
39
-
40
-
41
-    /**
42
-     *        private constructor to prevent direct creation
43
-     *
44
-     * @Constructor
45
-     * @access private
46
-     * @return void
47
-     */
48
-    private function __construct()
49
-    {
50
-        $this->_total_inserts = 0;
51
-        $this->_total_updates = 0;
52
-        $this->_total_insert_errors = 0;
53
-        $this->_total_update_errors = 0;
54
-    }
55
-
56
-
57
-    /**
58
-     *    @ singleton method used to instantiate class object
59
-     *    @ access public
60
-     *
61
-     * @return EE_Import
62
-     */
63
-    public static function instance()
64
-    {
65
-        // check if class object is instantiated
66
-        if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Import)) {
67
-            self::$_instance = new self();
68
-        }
69
-        return self::$_instance;
70
-    }
71
-
72
-    /**
73
-     * Resets the importer
74
-     *
75
-     * @return EE_Import
76
-     */
77
-    public static function reset()
78
-    {
79
-        self::$_instance = null;
80
-        return self::instance();
81
-    }
82
-
83
-
84
-    /**
85
-     *    @ generates HTML for a file upload input and form
86
-     *    @ access    public
87
-     *
88
-     * @param    string $title  - heading for the form
89
-     * @param    string $intro  - additional text explaing what to do
90
-     * @param    string $page   - EE Admin page to direct form to - in the form "espresso_{pageslug}"
91
-     * @param    string $action - EE Admin page route array "action" that form will direct to
92
-     * @param    string $type   - type of file to import
93
-     *                          @ return    string
94
-     */
95
-    public function upload_form($title, $intro, $form_url, $action, $type)
96
-    {
97
-
98
-        $form_url = EE_Admin_Page::add_query_args_and_nonce(array('action' => $action), $form_url);
99
-
100
-        ob_start();
101
-        ?>
17
+	const do_insert = 'insert';
18
+	const do_update = 'update';
19
+	const do_nothing = 'nothing';
20
+
21
+
22
+	// instance of the EE_Import object
23
+	private static $_instance = null;
24
+
25
+	private static $_csv_array = array();
26
+
27
+	/**
28
+	 *
29
+	 * @var array of model names
30
+	 */
31
+	private static $_model_list = array();
32
+
33
+	private static $_columns_to_save = array();
34
+
35
+	protected $_total_inserts = 0;
36
+	protected $_total_updates = 0;
37
+	protected $_total_insert_errors = 0;
38
+	protected $_total_update_errors = 0;
39
+
40
+
41
+	/**
42
+	 *        private constructor to prevent direct creation
43
+	 *
44
+	 * @Constructor
45
+	 * @access private
46
+	 * @return void
47
+	 */
48
+	private function __construct()
49
+	{
50
+		$this->_total_inserts = 0;
51
+		$this->_total_updates = 0;
52
+		$this->_total_insert_errors = 0;
53
+		$this->_total_update_errors = 0;
54
+	}
55
+
56
+
57
+	/**
58
+	 *    @ singleton method used to instantiate class object
59
+	 *    @ access public
60
+	 *
61
+	 * @return EE_Import
62
+	 */
63
+	public static function instance()
64
+	{
65
+		// check if class object is instantiated
66
+		if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Import)) {
67
+			self::$_instance = new self();
68
+		}
69
+		return self::$_instance;
70
+	}
71
+
72
+	/**
73
+	 * Resets the importer
74
+	 *
75
+	 * @return EE_Import
76
+	 */
77
+	public static function reset()
78
+	{
79
+		self::$_instance = null;
80
+		return self::instance();
81
+	}
82
+
83
+
84
+	/**
85
+	 *    @ generates HTML for a file upload input and form
86
+	 *    @ access    public
87
+	 *
88
+	 * @param    string $title  - heading for the form
89
+	 * @param    string $intro  - additional text explaing what to do
90
+	 * @param    string $page   - EE Admin page to direct form to - in the form "espresso_{pageslug}"
91
+	 * @param    string $action - EE Admin page route array "action" that form will direct to
92
+	 * @param    string $type   - type of file to import
93
+	 *                          @ return    string
94
+	 */
95
+	public function upload_form($title, $intro, $form_url, $action, $type)
96
+	{
97
+
98
+		$form_url = EE_Admin_Page::add_query_args_and_nonce(array('action' => $action), $form_url);
99
+
100
+		ob_start();
101
+		?>
102 102
         <div class="ee-upload-form-dv">
103 103
             <h3><?php echo $title; ?></h3>
104 104
             <p><?php echo $intro; ?></p>
@@ -114,874 +114,874 @@  discard block
 block discarded – undo
114 114
                 <b><?php _e('Attention', 'event_espresso'); ?></b><br/>
115 115
                 <?php echo sprintf(__('Accepts .%s file types only.', 'event_espresso'), $type); ?>
116 116
                 <?php echo __(
117
-                    'Please only import CSV files exported from Event Espresso, or compatible 3rd-party software.',
118
-                    'event_espresso'
119
-                ); ?>
117
+					'Please only import CSV files exported from Event Espresso, or compatible 3rd-party software.',
118
+					'event_espresso'
119
+				); ?>
120 120
             </p>
121 121
 
122 122
         </div>
123 123
 
124 124
         <?php
125
-        $uploader = ob_get_clean();
126
-        return $uploader;
127
-    }
128
-
129
-
130
-    /**
131
-     * @Import Event Espresso data - some code "borrowed" from event espresso csv_import.php
132
-     * @access public
133
-     * @return boolean success
134
-     */
135
-    public function import()
136
-    {
137
-
138
-        require_once(EE_CLASSES . 'EE_CSV.class.php');
139
-        $this->EE_CSV = EE_CSV::instance();
140
-
141
-        if (isset($_REQUEST['import'])) {
142
-            if (isset($_POST['csv_submitted'])) {
143
-                switch ($_FILES['file']['error'][0]) {
144
-                    case UPLOAD_ERR_OK:
145
-                        $error_msg = false;
146
-                        break;
147
-                    case UPLOAD_ERR_INI_SIZE:
148
-                        $error_msg = __(
149
-                            "'The uploaded file exceeds the upload_max_filesize directive in php.ini.'",
150
-                            "event_espresso"
151
-                        );
152
-                        break;
153
-                    case UPLOAD_ERR_FORM_SIZE:
154
-                        $error_msg = __(
155
-                            'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
156
-                            "event_espresso"
157
-                        );
158
-                        break;
159
-                    case UPLOAD_ERR_PARTIAL:
160
-                        $error_msg = __('The uploaded file was only partially uploaded.', "event_espresso");
161
-                        break;
162
-                    case UPLOAD_ERR_NO_FILE:
163
-                        $error_msg = __('No file was uploaded.', "event_espresso");
164
-                        break;
165
-                    case UPLOAD_ERR_NO_TMP_DIR:
166
-                        $error_msg = __('Missing a temporary folder.', "event_espresso");
167
-                        break;
168
-                    case UPLOAD_ERR_CANT_WRITE:
169
-                        $error_msg = __('Failed to write file to disk.', "event_espresso");
170
-                        break;
171
-                    case UPLOAD_ERR_EXTENSION:
172
-                        $error_msg = __('File upload stopped by extension.', "event_espresso");
173
-                        break;
174
-                    default:
175
-                        $error_msg = __(
176
-                            'An unknown error occurred and the file could not be uploaded',
177
-                            "event_espresso"
178
-                        );
179
-                        break;
180
-                }
181
-
182
-                if (! $error_msg) {
183
-                    $filename = $_FILES['file']['name'][0];
184
-                    $file_ext = substr(strrchr($filename, '.'), 1);
185
-                    $file_type = $_FILES['file']['type'][0];
186
-                    $temp_file = $_FILES['file']['tmp_name'][0];
187
-                    $filesize = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB
188
-
189
-                    if ($file_ext == 'csv') {
190
-                        $max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB
191
-                        if ($filesize < $max_upload || true) {
192
-                            $wp_upload_dir = str_replace(array('\\', '/'), DS, wp_upload_dir());
193
-                            $path_to_file = $wp_upload_dir['basedir'] . DS . 'espresso' . DS . $filename;
194
-
195
-                            if (move_uploaded_file($temp_file, $path_to_file)) {
196
-                                // convert csv to array
197
-                                $this->csv_array = $this->EE_CSV->import_csv_to_model_data_array($path_to_file);
198
-
199
-                                // was data successfully stored in an array?
200
-                                if (is_array($this->csv_array)) {
201
-                                    $import_what = str_replace('csv_import_', '', $_REQUEST['action']);
202
-                                    $import_what = str_replace('_', ' ', ucwords($import_what));
203
-                                    $processed_data = $this->csv_array;
204
-                                    $this->columns_to_save = false;
205
-
206
-                                    // if any imports require funcky processing, we'll catch them in the switch
207
-                                    switch ($_REQUEST['action']) {
208
-                                        case "import_events":
209
-                                        case "event_list":
210
-                                            $import_what = 'Event Details';
211
-                                            break;
212
-
213
-                                        case 'groupon_import_csv':
214
-                                            $import_what = 'Groupon Codes';
215
-                                            $processed_data = $this->process_groupon_codes();
216
-                                            break;
217
-                                    }
218
-                                    // save processed codes to db
219
-                                    if ($this->save_csv_data_array_to_db($processed_data, $this->columns_to_save)) {
220
-                                        return true;
221
-                                    }
222
-                                } else {
223
-                                    // no array? must be an error
224
-                                    EE_Error::add_error(
225
-                                        sprintf(__("No file seems to have been uploaded", "event_espresso")),
226
-                                        __FILE__,
227
-                                        __FUNCTION__,
228
-                                        __LINE__
229
-                                    );
230
-                                    return false;
231
-                                }
232
-                            } else {
233
-                                EE_Error::add_error(
234
-                                    sprintf(__("%s was not successfully uploaded", "event_espresso"), $filename),
235
-                                    __FILE__,
236
-                                    __FUNCTION__,
237
-                                    __LINE__
238
-                                );
239
-                                return false;
240
-                            }
241
-                        } else {
242
-                            EE_Error::add_error(
243
-                                sprintf(
244
-                                    __(
245
-                                        "%s was too large of a file and could not be uploaded. The max filesize is %s' KB.",
246
-                                        "event_espresso"
247
-                                    ),
248
-                                    $filename,
249
-                                    $max_upload
250
-                                ),
251
-                                __FILE__,
252
-                                __FUNCTION__,
253
-                                __LINE__
254
-                            );
255
-                            return false;
256
-                        }
257
-                    } else {
258
-                        EE_Error::add_error(
259
-                            sprintf(__("%s  had an invalid file extension, not uploaded", "event_espresso"), $filename),
260
-                            __FILE__,
261
-                            __FUNCTION__,
262
-                            __LINE__
263
-                        );
264
-                        return false;
265
-                    }
266
-                } else {
267
-                    EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
268
-                    return false;
269
-                }
270
-            }
271
-        }
272
-        return;
273
-    }
274
-
275
-
276
-    /**
277
-     *    Given an array of data (usually from a CSV import) attempts to save that data to the db.
278
-     *    If $model_name ISN'T provided, assumes that this is a 3d array, with toplevel keys being model names,
279
-     *    next level being numeric indexes adn each value representing a model object, and the last layer down
280
-     *    being keys of model fields and their proposed values.
281
-     *    If $model_name IS provided, assumes a 2d array of the bottom two layers previously mentioned.
282
-     *    If the CSV data says (in the metadata row) that it's from the SAME database,
283
-     *    we treat the IDs in the CSV as the normal IDs, and try to update those records. However, if those
284
-     *    IDs DON'T exist in the database, they're treated as temporary IDs,
285
-     *    which can used elsewhere to refer to the same object. Once an item
286
-     *    with a temporary ID gets inserted, we record its mapping from temporary
287
-     *    ID to real ID, and use the real ID in place of the temporary ID
288
-     *    when that temporary ID was used as a foreign key.
289
-     *    If the CSV data says (in the metadata again) that it's from a DIFFERENT database,
290
-     *    we treat all the IDs in the CSV as temporary ID- eg, if the CSV specifies an event with
291
-     *    ID 1, and the database already has an event with ID 1, we assume that's just a coincidence,
292
-     *    and insert a new event, and map it's temporary ID of 1 over to its new real ID.
293
-     *    An important exception are non-auto-increment primary keys. If one entry in the
294
-     *    CSV file has the same ID as one in the DB, we assume they are meant to be
295
-     *    the same item, and instead update the item in the DB with that same ID.
296
-     *    Also note, we remember the mappings permanently. So the 2nd, 3rd, and 10000th
297
-     *    time you import a CSV from a different site, we remember their mappings, and
298
-     * will try to update the item in the DB instead of inserting another item (eg
299
-     * if we previously imported an event with temporary ID 1, and then it got a
300
-     * real ID of 123, we remember that. So the next time we import an event with
301
-     * temporary ID, from the same site, we know that it's real ID is 123, and will
302
-     * update that event, instead of adding a new event).
303
-     *
304
-     * @access public
305
-     * @param array $csv_data_array - the array containing the csv data produced from
306
-     *                              EE_CSV::import_csv_to_model_data_array()
307
-     * @param array $fields_to_save - an array containing the csv column names as keys with the corresponding db table
308
-     *                              fields they will be saved to
309
-     * @return TRUE on success, FALSE on fail
310
-     * @throws \EE_Error
311
-     */
312
-    public function save_csv_data_array_to_db($csv_data_array, $model_name = false)
313
-    {
314
-        $success = false;
315
-        $error = false;
316
-        // whther to treat this import as if it's data froma different database or not
317
-        // ie, if it IS from a different database, ignore foreign keys whihf
318
-        $export_from_site_a_to_b = true;
319
-        // first level of array is not table information but a table name was passed to the function
320
-        // array is only two levels deep, so let's fix that by adding a level, else the next steps will fail
321
-        if ($model_name) {
322
-            $csv_data_array = array($csv_data_array);
323
-        }
324
-        // begin looking through the $csv_data_array, expecting the toplevel key to be the model's name...
325
-        $old_site_url = 'none-specified';
326
-        // hanlde metadata
327
-        if (isset($csv_data_array[ EE_CSV::metadata_header ])) {
328
-            $csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]);
329
-            // ok so its metadata, dont try to save it to ehte db obviously...
330
-            if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) {
331
-                EE_Error::add_attention(
332
-                    sprintf(
333
-                        __(
334
-                            "CSV Data appears to be from the same database, so attempting to update data",
335
-                            "event_espresso"
336
-                        )
337
-                    )
338
-                );
339
-                $export_from_site_a_to_b = false;
340
-            } else {
341
-                $old_site_url = isset($csv_metadata['site_url']) ? $csv_metadata['site_url'] : $old_site_url;
342
-                EE_Error::add_attention(
343
-                    sprintf(
344
-                        __(
345
-                            "CSV Data appears to be from a different database (%s instead of %s), so we assume IDs in the CSV data DO NOT correspond to IDs in this database",
346
-                            "event_espresso"
347
-                        ),
348
-                        $old_site_url,
349
-                        site_url()
350
-                    )
351
-                );
352
-            };
353
-            unset($csv_data_array[ EE_CSV::metadata_header ]);
354
-        }
355
-        /**
356
-         * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and
357
-         * the value will be the newly-inserted ID.
358
-         * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option
359
-         */
360
-        $old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), array());
361
-        if ($old_db_to_new_db_mapping) {
362
-            EE_Error::add_attention(
363
-                sprintf(
364
-                    __(
365
-                        "We noticed you have imported data via CSV from %s before. Because of this, IDs in your CSV have been mapped to their new IDs in %s",
366
-                        "event_espresso"
367
-                    ),
368
-                    $old_site_url,
369
-                    site_url()
370
-                )
371
-            );
372
-        }
373
-        $old_db_to_new_db_mapping = $this->save_data_rows_to_db(
374
-            $csv_data_array,
375
-            $export_from_site_a_to_b,
376
-            $old_db_to_new_db_mapping
377
-        );
378
-
379
-        // save the mapping from old db to new db in case they try re-importing the same data from the same website again
380
-        update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping);
381
-
382
-        if ($this->_total_updates > 0) {
383
-            EE_Error::add_success(
384
-                sprintf(
385
-                    __("%s existing records in the database were updated.", "event_espresso"),
386
-                    $this->_total_updates
387
-                )
388
-            );
389
-            $success = true;
390
-        }
391
-        if ($this->_total_inserts > 0) {
392
-            EE_Error::add_success(
393
-                sprintf(__("%s new records were added to the database.", "event_espresso"), $this->_total_inserts)
394
-            );
395
-            $success = true;
396
-        }
397
-
398
-        if ($this->_total_update_errors > 0) {
399
-            EE_Error::add_error(
400
-                sprintf(
401
-                    __(
402
-                        "'One or more errors occurred, and a total of %s existing records in the database were <strong>not</strong> updated.'",
403
-                        "event_espresso"
404
-                    ),
405
-                    $this->_total_update_errors
406
-                ),
407
-                __FILE__,
408
-                __FUNCTION__,
409
-                __LINE__
410
-            );
411
-            $error = true;
412
-        }
413
-        if ($this->_total_insert_errors > 0) {
414
-            EE_Error::add_error(
415
-                sprintf(
416
-                    __(
417
-                        "One or more errors occurred, and a total of %s new records were <strong>not</strong> added to the database.'",
418
-                        "event_espresso"
419
-                    ),
420
-                    $this->_total_insert_errors
421
-                ),
422
-                __FILE__,
423
-                __FUNCTION__,
424
-                __LINE__
425
-            );
426
-            $error = true;
427
-        }
428
-
429
-        // lastly, we need to update the datetime and ticket sold amounts
430
-        // as those may have been affected by this
431
-        EEM_Ticket::instance()->update_tickets_sold(EEM_Ticket::instance()->get_all());
432
-
433
-        // if there was at least one success and absolutely no errors
434
-        if ($success && ! $error) {
435
-            return true;
436
-        } else {
437
-            return false;
438
-        }
439
-    }
440
-
441
-
442
-    /**
443
-     * Processes the array of data, given the knowledge that it's from the same database or a different one,
444
-     * and the mapping from temporary IDs to real IDs.
445
-     * If the data is from a different database, we treat the primary keys and their corresponding
446
-     * foreign keys as "temp Ids", basically identifiers that get mapped to real primary keys
447
-     * in the real target database. As items are inserted, their temporary primary keys
448
-     * are mapped to the real IDs in the target database. Also, before doing any update or
449
-     * insert, we replace all the temp ID which are foreign keys with their mapped real IDs.
450
-     * An exception: string primary keys are treated as real IDs, or else we'd need to
451
-     * dynamically generate new string primary keys which would be very awkard for the country table etc.
452
-     * Also, models with no primary key are strange too. We combine use their primar key INDEX (a
453
-     * combination of fields) to create a unique string identifying the row and store
454
-     * those in the mapping.
455
-     *
456
-     * If the data is from the same database, we usually treat primary keys as real IDs.
457
-     * An exception is if there is nothing in the database for that ID. If that's the case,
458
-     * we need to insert a new row for that ID, and then map from the non-existent ID
459
-     * to the newly-inserted real ID.
460
-     *
461
-     * @param type $csv_data_array
462
-     * @param type $export_from_site_a_to_b
463
-     * @param type $old_db_to_new_db_mapping
464
-     * @return array updated $old_db_to_new_db_mapping
465
-     */
466
-    public function save_data_rows_to_db($csv_data_array, $export_from_site_a_to_b, $old_db_to_new_db_mapping)
467
-    {
468
-        foreach ($csv_data_array as $model_name_in_csv_data => $model_data_from_import) {
469
-            // now check that assumption was correct. If
470
-            if (EE_Registry::instance()->is_model_name($model_name_in_csv_data)) {
471
-                $model_name = $model_name_in_csv_data;
472
-            } else {
473
-                // no table info in the array and no table name passed to the function?? FAIL
474
-                EE_Error::add_error(
475
-                    __(
476
-                        'No table information was specified and/or found, therefore the import could not be completed',
477
-                        'event_espresso'
478
-                    ),
479
-                    __FILE__,
480
-                    __FUNCTION__,
481
-                    __LINE__
482
-                );
483
-                return false;
484
-            }
485
-            /* @var $model EEM_Base */
486
-            $model = EE_Registry::instance()->load_model($model_name);
487
-
488
-            // so without further ado, scanning all the data provided for primary keys and their inital values
489
-            foreach ($model_data_from_import as $model_object_data) {
490
-                // before we do ANYTHING, make sure the csv row wasn't just completely blank
491
-                $row_is_completely_empty = true;
492
-                foreach ($model_object_data as $field) {
493
-                    if ($field) {
494
-                        $row_is_completely_empty = false;
495
-                    }
496
-                }
497
-                if ($row_is_completely_empty) {
498
-                    continue;
499
-                }
500
-                // find the PK in the row of data (or a combined key if
501
-                // there is no primary key)
502
-                if ($model->has_primary_key_field()) {
503
-                    $id_in_csv = $model_object_data[ $model->primary_key_name() ];
504
-                } else {
505
-                    $id_in_csv = $model->get_index_primary_key_string($model_object_data);
506
-                }
507
-
508
-
509
-                $model_object_data = $this->_replace_temp_ids_with_mappings(
510
-                    $model_object_data,
511
-                    $model,
512
-                    $old_db_to_new_db_mapping,
513
-                    $export_from_site_a_to_b
514
-                );
515
-                // now we need to decide if we're going to add a new model object given the $model_object_data,
516
-                // or just update.
517
-                if ($export_from_site_a_to_b) {
518
-                    $what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_other_db(
519
-                        $id_in_csv,
520
-                        $model_object_data,
521
-                        $model,
522
-                        $old_db_to_new_db_mapping
523
-                    );
524
-                } else {// this is just a re-import
525
-                    $what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_same_db(
526
-                        $id_in_csv,
527
-                        $model_object_data,
528
-                        $model,
529
-                        $old_db_to_new_db_mapping
530
-                    );
531
-                }
532
-                if ($what_to_do == self::do_nothing) {
533
-                    continue;
534
-                }
535
-
536
-                // double-check we actually want to insert, if that's what we're planning
537
-                // based on whether this item would be unique in the DB or not
538
-                if ($what_to_do == self::do_insert) {
539
-                    // we're supposed to be inserting. But wait, will this thing
540
-                    // be acceptable if inserted?
541
-                    $conflicting = $model->get_one_conflicting($model_object_data, false);
542
-                    if ($conflicting) {
543
-                        // ok, this item would conflict if inserted. Just update the item that it conflicts with.
544
-                        $what_to_do = self::do_update;
545
-                        // and if this model has a primary key, remember its mapping
546
-                        if ($model->has_primary_key_field()) {
547
-                            $old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID();
548
-                            $model_object_data[ $model->primary_key_name() ] = $conflicting->ID();
549
-                        } else {
550
-                            // we want to update this conflicting item, instead of inserting a conflicting item
551
-                            // so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields
552
-                            // for the WHERE conditions in the update). At the time of this comment, there were no models like this
553
-                            foreach ($model->get_combined_primary_key_fields() as $key_field) {
554
-                                $model_object_data[ $key_field->get_name() ] = $conflicting->get(
555
-                                    $key_field->get_name()
556
-                                );
557
-                            }
558
-                        }
559
-                    }
560
-                }
561
-                if ($what_to_do == self::do_insert) {
562
-                    $old_db_to_new_db_mapping = $this->_insert_from_data_array(
563
-                        $id_in_csv,
564
-                        $model_object_data,
565
-                        $model,
566
-                        $old_db_to_new_db_mapping
567
-                    );
568
-                } elseif ($what_to_do == self::do_update) {
569
-                    $old_db_to_new_db_mapping = $this->_update_from_data_array(
570
-                        $id_in_csv,
571
-                        $model_object_data,
572
-                        $model,
573
-                        $old_db_to_new_db_mapping
574
-                    );
575
-                } else {
576
-                    throw new EE_Error(
577
-                        sprintf(
578
-                            __(
579
-                                'Programming error. We shoudl be inserting or updating, but instead we are being told to "%s", whifh is invalid',
580
-                                'event_espresso'
581
-                            ),
582
-                            $what_to_do
583
-                        )
584
-                    );
585
-                }
586
-            }
587
-        }
588
-        return $old_db_to_new_db_mapping;
589
-    }
590
-
591
-
592
-    /**
593
-     * Decides whether or not to insert, given that this data is from another database.
594
-     * So, if the primary key of this $model_object_data already exists in the database,
595
-     * it's just a coincidence and we should still insert. The only time we should
596
-     * update is when we know what it maps to, or there's something that would
597
-     * conflict (and we should instead just update that conflicting thing)
598
-     *
599
-     * @param string   $id_in_csv
600
-     * @param array    $model_object_data        by reference so it can be modified
601
-     * @param EEM_Base $model
602
-     * @param array    $old_db_to_new_db_mapping by reference so it can be modified
603
-     * @return string one of the consts on this class that starts with do_*
604
-     */
605
-    protected function _decide_whether_to_insert_or_update_given_data_from_other_db(
606
-        $id_in_csv,
607
-        $model_object_data,
608
-        $model,
609
-        $old_db_to_new_db_mapping
610
-    ) {
611
-        $model_name = $model->get_this_model_name();
612
-        // if it's a site-to-site export-and-import, see if this modelobject's id
613
-        // in the old data that we know of
614
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) {
615
-            return self::do_update;
616
-        } else {
617
-            return self::do_insert;
618
-        }
619
-    }
620
-
621
-    /**
622
-     * If this thing basically already exists in the database, we want to update it;
623
-     * otherwise insert it (ie, someone tweaked the CSV file, or the item was
624
-     * deleted in the database so it should be re-inserted)
625
-     *
626
-     * @param type     $id_in_csv
627
-     * @param type     $model_object_data
628
-     * @param EEM_Base $model
629
-     * @param type     $old_db_to_new_db_mapping
630
-     * @return
631
-     */
632
-    protected function _decide_whether_to_insert_or_update_given_data_from_same_db(
633
-        $id_in_csv,
634
-        $model_object_data,
635
-        $model
636
-    ) {
637
-        // in this case, check if this thing ACTUALLY exists in the database
638
-        if ($model->get_one_conflicting($model_object_data)) {
639
-            return self::do_update;
640
-        } else {
641
-            return self::do_insert;
642
-        }
643
-    }
644
-
645
-    /**
646
-     * Using the $old_db_to_new_db_mapping array, replaces all the temporary IDs
647
-     * with their mapped real IDs. Eg, if importing from site A to B, the mapping
648
-     * file may indicate that the ID "my_event_id" maps to an actual event ID of 123.
649
-     * So this function searches for any event temp Ids called "my_event_id" and
650
-     * replaces them with 123.
651
-     * Also, if there is no temp ID for the INT foreign keys from another database,
652
-     * replaces them with 0 or the field's default.
653
-     *
654
-     * @param type     $model_object_data
655
-     * @param EEM_Base $model
656
-     * @param type     $old_db_to_new_db_mapping
657
-     * @param boolean  $export_from_site_a_to_b
658
-     * @return array updated model object data with temp IDs removed
659
-     */
660
-    protected function _replace_temp_ids_with_mappings(
661
-        $model_object_data,
662
-        $model,
663
-        $old_db_to_new_db_mapping,
664
-        $export_from_site_a_to_b
665
-    ) {
666
-        // if this model object's primary key is in the mapping, replace it
667
-        if ($model->has_primary_key_field() &&
668
-            $model->get_primary_key_field()->is_auto_increment() &&
669
-            isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ]) &&
670
-            isset(
671
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $model_object_data[ $model->primary_key_name() ] ]
672
-            )) {
673
-            $model_object_data[ $model->primary_key_name() ] = $old_db_to_new_db_mapping[ $model->get_this_model_name(
674
-            ) ][ $model_object_data[ $model->primary_key_name() ] ];
675
-        }
676
-
677
-        try {
678
-            $model_name_field = $model->get_field_containing_related_model_name();
679
-            $models_pointed_to_by_model_name_field = $model_name_field->get_model_names_pointed_to();
680
-        } catch (EE_Error $e) {
681
-            $model_name_field = null;
682
-            $models_pointed_to_by_model_name_field = array();
683
-        }
684
-        foreach ($model->field_settings(true) as $field_obj) {
685
-            if ($field_obj instanceof EE_Foreign_Key_Int_Field) {
686
-                $models_pointed_to = $field_obj->get_model_names_pointed_to();
687
-                $found_a_mapping = false;
688
-                foreach ($models_pointed_to as $model_pointed_to_by_fk) {
689
-                    if ($model_name_field) {
690
-                        $value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ];
691
-                        if ($value_of_model_name_field == $model_pointed_to_by_fk) {
692
-                            $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
693
-                                $model_object_data[ $field_obj->get_name() ],
694
-                                $model_pointed_to_by_fk,
695
-                                $old_db_to_new_db_mapping,
696
-                                $export_from_site_a_to_b
697
-                            );
698
-                            $found_a_mapping = true;
699
-                            break;
700
-                        }
701
-                    } else {
702
-                        $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
703
-                            $model_object_data[ $field_obj->get_name() ],
704
-                            $model_pointed_to_by_fk,
705
-                            $old_db_to_new_db_mapping,
706
-                            $export_from_site_a_to_b
707
-                        );
708
-                        $found_a_mapping = true;
709
-                    }
710
-                    // once we've found a mapping for this field no need to continue
711
-                    if ($found_a_mapping) {
712
-                        break;
713
-                    }
714
-                }
715
-            } else {
716
-                // it's a string foreign key (which we leave alone, because those are things
717
-                // like country names, which we'd really rather not make 2 USAs etc (we'd actually
718
-                // prefer to just update one)
719
-                // or it's just a regular value that ought to be replaced
720
-            }
721
-        }
722
-        //
723
-        if ($model instanceof EEM_Term_Taxonomy) {
724
-            $model_object_data = $this->_handle_split_term_ids($model_object_data);
725
-        }
726
-        return $model_object_data;
727
-    }
728
-
729
-    /**
730
-     * If the data was exported PRE-4.2, but then imported POST-4.2, then the term_id
731
-     * this term-taxonomy refers to may be out-of-date so we need to update it.
732
-     * see https://make.wordpress.org/core/2015/02/16/taxonomy-term-splitting-in-4-2-a-developer-guide/
733
-     *
734
-     * @param type $model_object_data
735
-     * @return array new model object data
736
-     */
737
-    protected function _handle_split_term_ids($model_object_data)
738
-    {
739
-        if (isset($model_object_data['term_id'])
740
-            && isset($model_object_data['taxonomy'])
741
-            && apply_filters(
742
-                'FHEE__EE_Import__handle_split_term_ids__function_exists',
743
-                function_exists('wp_get_split_term'),
744
-                $model_object_data
745
-            )) {
746
-            $new_term_id = wp_get_split_term($model_object_data['term_id'], $model_object_data['taxonomy']);
747
-            if ($new_term_id) {
748
-                $model_object_data['term_id'] = $new_term_id;
749
-            }
750
-        }
751
-        return $model_object_data;
752
-    }
753
-
754
-    /**
755
-     * Given the object's ID and its model's name, find it int he mapping data,
756
-     * bearing in mind where it came from
757
-     *
758
-     * @param type   $object_id
759
-     * @param string $model_name
760
-     * @param array  $old_db_to_new_db_mapping
761
-     * @param type   $export_from_site_a_to_b
762
-     * @return int
763
-     */
764
-    protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b)
765
-    {
766
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) {
767
-            return $old_db_to_new_db_mapping[ $model_name ][ $object_id ];
768
-        } elseif ($object_id == '0' || $object_id == '') {
769
-            // leave as-is
770
-            return $object_id;
771
-        } elseif ($export_from_site_a_to_b) {
772
-            // we couldn't find a mapping for this, and it's from a different site,
773
-            // so blank it out
774
-            return null;
775
-        } elseif (! $export_from_site_a_to_b) {
776
-            // we coudln't find a mapping for this, but it's from thsi DB anyway
777
-            // so let's just leave it as-is
778
-            return $object_id;
779
-        }
780
-    }
781
-
782
-    /**
783
-     *
784
-     * @param type     $id_in_csv
785
-     * @param type     $model_object_data
786
-     * @param EEM_Base $model
787
-     * @param type     $old_db_to_new_db_mapping
788
-     * @return array updated $old_db_to_new_db_mapping
789
-     */
790
-    protected function _insert_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
791
-    {
792
-        // remove the primary key, if there is one (we don't want it for inserts OR updates)
793
-        // we'll put it back in if we need it
794
-        if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) {
795
-            $effective_id = $model_object_data[ $model->primary_key_name() ];
796
-            unset($model_object_data[ $model->primary_key_name() ]);
797
-        } else {
798
-            $effective_id = $model->get_index_primary_key_string($model_object_data);
799
-        }
800
-        // the model takes care of validating the CSV's input
801
-        try {
802
-            $new_id = $model->insert($model_object_data);
803
-            if ($new_id) {
804
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id;
805
-                $this->_total_inserts++;
806
-                EE_Error::add_success(
807
-                    sprintf(
808
-                        __("Successfully added new %s (with id %s) with csv data %s", "event_espresso"),
809
-                        $model->get_this_model_name(),
810
-                        $new_id,
811
-                        implode(",", $model_object_data)
812
-                    )
813
-                );
814
-            } else {
815
-                $this->_total_insert_errors++;
816
-                // put the ID used back in there for the error message
817
-                if ($model->has_primary_key_field()) {
818
-                    $model_object_data[ $model->primary_key_name() ] = $effective_id;
819
-                }
820
-                EE_Error::add_error(
821
-                    sprintf(
822
-                        __("Could not insert new %s with the csv data: %s", "event_espresso"),
823
-                        $model->get_this_model_name(),
824
-                        http_build_query($model_object_data)
825
-                    ),
826
-                    __FILE__,
827
-                    __FUNCTION__,
828
-                    __LINE__
829
-                );
830
-            }
831
-        } catch (EE_Error $e) {
832
-            $this->_total_insert_errors++;
833
-            if ($model->has_primary_key_field()) {
834
-                $model_object_data[ $model->primary_key_name() ] = $effective_id;
835
-            }
836
-            EE_Error::add_error(
837
-                sprintf(
838
-                    __("Could not insert new %s with the csv data: %s because %s", "event_espresso"),
839
-                    $model->get_this_model_name(),
840
-                    implode(",", $model_object_data),
841
-                    $e->getMessage()
842
-                ),
843
-                __FILE__,
844
-                __FUNCTION__,
845
-                __LINE__
846
-            );
847
-        }
848
-        return $old_db_to_new_db_mapping;
849
-    }
850
-
851
-    /**
852
-     * Given the model object data, finds the row to update and updates it
853
-     *
854
-     * @param string|int $id_in_csv
855
-     * @param array      $model_object_data
856
-     * @param EEM_Base   $model
857
-     * @param array      $old_db_to_new_db_mapping
858
-     * @return array updated $old_db_to_new_db_mapping
859
-     */
860
-    protected function _update_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
861
-    {
862
-        try {
863
-            // let's keep two copies of the model object data:
864
-            // one for performing an update, one for everthing else
865
-            $model_object_data_for_update = $model_object_data;
866
-            if ($model->has_primary_key_field()) {
867
-                $conditions = array($model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]);
868
-                // remove the primary key because we shouldn't use it for updating
869
-                unset($model_object_data_for_update[ $model->primary_key_name() ]);
870
-            } elseif ($model->get_combined_primary_key_fields() > 1) {
871
-                $conditions = array();
872
-                foreach ($model->get_combined_primary_key_fields() as $key_field) {
873
-                    $conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ];
874
-                }
875
-            } else {
876
-                $model->primary_key_name(
877
-                );// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
878
-            }
879
-
880
-            $success = $model->update($model_object_data_for_update, array($conditions));
881
-            if ($success) {
882
-                $this->_total_updates++;
883
-                EE_Error::add_success(
884
-                    sprintf(
885
-                        __("Successfully updated %s with csv data %s", "event_espresso"),
886
-                        $model->get_this_model_name(),
887
-                        implode(",", $model_object_data_for_update)
888
-                    )
889
-                );
890
-                // we should still record the mapping even though it was an update
891
-                // because if we were going to insert somethign but it was going to conflict
892
-                // we would have last-minute decided to update. So we'd like to know what we updated
893
-                // and so we record what record ended up being updated using the mapping
894
-                if ($model->has_primary_key_field()) {
895
-                    $new_key_for_mapping = $model_object_data[ $model->primary_key_name() ];
896
-                } else {
897
-                    // no primary key just a combined key
898
-                    $new_key_for_mapping = $model->get_index_primary_key_string($model_object_data);
899
-                }
900
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping;
901
-            } else {
902
-                $matched_items = $model->get_all(array($conditions));
903
-                if (! $matched_items) {
904
-                    // no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck?
905
-                    $this->_total_update_errors++;
906
-                    EE_Error::add_error(
907
-                        sprintf(
908
-                            __(
909
-                                "Could not update %s with the csv data: '%s' for an unknown reason (using WHERE conditions %s)",
910
-                                "event_espresso"
911
-                            ),
912
-                            $model->get_this_model_name(),
913
-                            http_build_query($model_object_data),
914
-                            http_build_query($conditions)
915
-                        ),
916
-                        __FILE__,
917
-                        __FUNCTION__,
918
-                        __LINE__
919
-                    );
920
-                } else {
921
-                    $this->_total_updates++;
922
-                    EE_Error::add_success(
923
-                        sprintf(
924
-                            __(
925
-                                "%s with csv data '%s' was found in the database and didn't need updating because all the data is identical.",
926
-                                "event_espresso"
927
-                            ),
928
-                            $model->get_this_model_name(),
929
-                            implode(",", $model_object_data)
930
-                        )
931
-                    );
932
-                }
933
-            }
934
-        } catch (EE_Error $e) {
935
-            $this->_total_update_errors++;
936
-            $basic_message = sprintf(
937
-                __("Could not update %s with the csv data: %s because %s", "event_espresso"),
938
-                $model->get_this_model_name(),
939
-                implode(",", $model_object_data),
940
-                $e->getMessage()
941
-            );
942
-            $debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString();
943
-            EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__);
944
-        }
945
-        return $old_db_to_new_db_mapping;
946
-    }
947
-
948
-    /**
949
-     * Gets the number of inserts performed since importer was instantiated or reset
950
-     *
951
-     * @return int
952
-     */
953
-    public function get_total_inserts()
954
-    {
955
-        return $this->_total_inserts;
956
-    }
957
-
958
-    /**
959
-     *  Gets the number of insert errors since importer was instantiated or reset
960
-     *
961
-     * @return int
962
-     */
963
-    public function get_total_insert_errors()
964
-    {
965
-        return $this->_total_insert_errors;
966
-    }
967
-
968
-    /**
969
-     *  Gets the number of updates performed since importer was instantiated or reset
970
-     *
971
-     * @return int
972
-     */
973
-    public function get_total_updates()
974
-    {
975
-        return $this->_total_updates;
976
-    }
977
-
978
-    /**
979
-     *  Gets the number of update errors since importer was instantiated or reset
980
-     *
981
-     * @return int
982
-     */
983
-    public function get_total_update_errors()
984
-    {
985
-        return $this->_total_update_errors;
986
-    }
125
+		$uploader = ob_get_clean();
126
+		return $uploader;
127
+	}
128
+
129
+
130
+	/**
131
+	 * @Import Event Espresso data - some code "borrowed" from event espresso csv_import.php
132
+	 * @access public
133
+	 * @return boolean success
134
+	 */
135
+	public function import()
136
+	{
137
+
138
+		require_once(EE_CLASSES . 'EE_CSV.class.php');
139
+		$this->EE_CSV = EE_CSV::instance();
140
+
141
+		if (isset($_REQUEST['import'])) {
142
+			if (isset($_POST['csv_submitted'])) {
143
+				switch ($_FILES['file']['error'][0]) {
144
+					case UPLOAD_ERR_OK:
145
+						$error_msg = false;
146
+						break;
147
+					case UPLOAD_ERR_INI_SIZE:
148
+						$error_msg = __(
149
+							"'The uploaded file exceeds the upload_max_filesize directive in php.ini.'",
150
+							"event_espresso"
151
+						);
152
+						break;
153
+					case UPLOAD_ERR_FORM_SIZE:
154
+						$error_msg = __(
155
+							'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
156
+							"event_espresso"
157
+						);
158
+						break;
159
+					case UPLOAD_ERR_PARTIAL:
160
+						$error_msg = __('The uploaded file was only partially uploaded.', "event_espresso");
161
+						break;
162
+					case UPLOAD_ERR_NO_FILE:
163
+						$error_msg = __('No file was uploaded.', "event_espresso");
164
+						break;
165
+					case UPLOAD_ERR_NO_TMP_DIR:
166
+						$error_msg = __('Missing a temporary folder.', "event_espresso");
167
+						break;
168
+					case UPLOAD_ERR_CANT_WRITE:
169
+						$error_msg = __('Failed to write file to disk.', "event_espresso");
170
+						break;
171
+					case UPLOAD_ERR_EXTENSION:
172
+						$error_msg = __('File upload stopped by extension.', "event_espresso");
173
+						break;
174
+					default:
175
+						$error_msg = __(
176
+							'An unknown error occurred and the file could not be uploaded',
177
+							"event_espresso"
178
+						);
179
+						break;
180
+				}
181
+
182
+				if (! $error_msg) {
183
+					$filename = $_FILES['file']['name'][0];
184
+					$file_ext = substr(strrchr($filename, '.'), 1);
185
+					$file_type = $_FILES['file']['type'][0];
186
+					$temp_file = $_FILES['file']['tmp_name'][0];
187
+					$filesize = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB
188
+
189
+					if ($file_ext == 'csv') {
190
+						$max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB
191
+						if ($filesize < $max_upload || true) {
192
+							$wp_upload_dir = str_replace(array('\\', '/'), DS, wp_upload_dir());
193
+							$path_to_file = $wp_upload_dir['basedir'] . DS . 'espresso' . DS . $filename;
194
+
195
+							if (move_uploaded_file($temp_file, $path_to_file)) {
196
+								// convert csv to array
197
+								$this->csv_array = $this->EE_CSV->import_csv_to_model_data_array($path_to_file);
198
+
199
+								// was data successfully stored in an array?
200
+								if (is_array($this->csv_array)) {
201
+									$import_what = str_replace('csv_import_', '', $_REQUEST['action']);
202
+									$import_what = str_replace('_', ' ', ucwords($import_what));
203
+									$processed_data = $this->csv_array;
204
+									$this->columns_to_save = false;
205
+
206
+									// if any imports require funcky processing, we'll catch them in the switch
207
+									switch ($_REQUEST['action']) {
208
+										case "import_events":
209
+										case "event_list":
210
+											$import_what = 'Event Details';
211
+											break;
212
+
213
+										case 'groupon_import_csv':
214
+											$import_what = 'Groupon Codes';
215
+											$processed_data = $this->process_groupon_codes();
216
+											break;
217
+									}
218
+									// save processed codes to db
219
+									if ($this->save_csv_data_array_to_db($processed_data, $this->columns_to_save)) {
220
+										return true;
221
+									}
222
+								} else {
223
+									// no array? must be an error
224
+									EE_Error::add_error(
225
+										sprintf(__("No file seems to have been uploaded", "event_espresso")),
226
+										__FILE__,
227
+										__FUNCTION__,
228
+										__LINE__
229
+									);
230
+									return false;
231
+								}
232
+							} else {
233
+								EE_Error::add_error(
234
+									sprintf(__("%s was not successfully uploaded", "event_espresso"), $filename),
235
+									__FILE__,
236
+									__FUNCTION__,
237
+									__LINE__
238
+								);
239
+								return false;
240
+							}
241
+						} else {
242
+							EE_Error::add_error(
243
+								sprintf(
244
+									__(
245
+										"%s was too large of a file and could not be uploaded. The max filesize is %s' KB.",
246
+										"event_espresso"
247
+									),
248
+									$filename,
249
+									$max_upload
250
+								),
251
+								__FILE__,
252
+								__FUNCTION__,
253
+								__LINE__
254
+							);
255
+							return false;
256
+						}
257
+					} else {
258
+						EE_Error::add_error(
259
+							sprintf(__("%s  had an invalid file extension, not uploaded", "event_espresso"), $filename),
260
+							__FILE__,
261
+							__FUNCTION__,
262
+							__LINE__
263
+						);
264
+						return false;
265
+					}
266
+				} else {
267
+					EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
268
+					return false;
269
+				}
270
+			}
271
+		}
272
+		return;
273
+	}
274
+
275
+
276
+	/**
277
+	 *    Given an array of data (usually from a CSV import) attempts to save that data to the db.
278
+	 *    If $model_name ISN'T provided, assumes that this is a 3d array, with toplevel keys being model names,
279
+	 *    next level being numeric indexes adn each value representing a model object, and the last layer down
280
+	 *    being keys of model fields and their proposed values.
281
+	 *    If $model_name IS provided, assumes a 2d array of the bottom two layers previously mentioned.
282
+	 *    If the CSV data says (in the metadata row) that it's from the SAME database,
283
+	 *    we treat the IDs in the CSV as the normal IDs, and try to update those records. However, if those
284
+	 *    IDs DON'T exist in the database, they're treated as temporary IDs,
285
+	 *    which can used elsewhere to refer to the same object. Once an item
286
+	 *    with a temporary ID gets inserted, we record its mapping from temporary
287
+	 *    ID to real ID, and use the real ID in place of the temporary ID
288
+	 *    when that temporary ID was used as a foreign key.
289
+	 *    If the CSV data says (in the metadata again) that it's from a DIFFERENT database,
290
+	 *    we treat all the IDs in the CSV as temporary ID- eg, if the CSV specifies an event with
291
+	 *    ID 1, and the database already has an event with ID 1, we assume that's just a coincidence,
292
+	 *    and insert a new event, and map it's temporary ID of 1 over to its new real ID.
293
+	 *    An important exception are non-auto-increment primary keys. If one entry in the
294
+	 *    CSV file has the same ID as one in the DB, we assume they are meant to be
295
+	 *    the same item, and instead update the item in the DB with that same ID.
296
+	 *    Also note, we remember the mappings permanently. So the 2nd, 3rd, and 10000th
297
+	 *    time you import a CSV from a different site, we remember their mappings, and
298
+	 * will try to update the item in the DB instead of inserting another item (eg
299
+	 * if we previously imported an event with temporary ID 1, and then it got a
300
+	 * real ID of 123, we remember that. So the next time we import an event with
301
+	 * temporary ID, from the same site, we know that it's real ID is 123, and will
302
+	 * update that event, instead of adding a new event).
303
+	 *
304
+	 * @access public
305
+	 * @param array $csv_data_array - the array containing the csv data produced from
306
+	 *                              EE_CSV::import_csv_to_model_data_array()
307
+	 * @param array $fields_to_save - an array containing the csv column names as keys with the corresponding db table
308
+	 *                              fields they will be saved to
309
+	 * @return TRUE on success, FALSE on fail
310
+	 * @throws \EE_Error
311
+	 */
312
+	public function save_csv_data_array_to_db($csv_data_array, $model_name = false)
313
+	{
314
+		$success = false;
315
+		$error = false;
316
+		// whther to treat this import as if it's data froma different database or not
317
+		// ie, if it IS from a different database, ignore foreign keys whihf
318
+		$export_from_site_a_to_b = true;
319
+		// first level of array is not table information but a table name was passed to the function
320
+		// array is only two levels deep, so let's fix that by adding a level, else the next steps will fail
321
+		if ($model_name) {
322
+			$csv_data_array = array($csv_data_array);
323
+		}
324
+		// begin looking through the $csv_data_array, expecting the toplevel key to be the model's name...
325
+		$old_site_url = 'none-specified';
326
+		// hanlde metadata
327
+		if (isset($csv_data_array[ EE_CSV::metadata_header ])) {
328
+			$csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]);
329
+			// ok so its metadata, dont try to save it to ehte db obviously...
330
+			if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) {
331
+				EE_Error::add_attention(
332
+					sprintf(
333
+						__(
334
+							"CSV Data appears to be from the same database, so attempting to update data",
335
+							"event_espresso"
336
+						)
337
+					)
338
+				);
339
+				$export_from_site_a_to_b = false;
340
+			} else {
341
+				$old_site_url = isset($csv_metadata['site_url']) ? $csv_metadata['site_url'] : $old_site_url;
342
+				EE_Error::add_attention(
343
+					sprintf(
344
+						__(
345
+							"CSV Data appears to be from a different database (%s instead of %s), so we assume IDs in the CSV data DO NOT correspond to IDs in this database",
346
+							"event_espresso"
347
+						),
348
+						$old_site_url,
349
+						site_url()
350
+					)
351
+				);
352
+			};
353
+			unset($csv_data_array[ EE_CSV::metadata_header ]);
354
+		}
355
+		/**
356
+		 * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and
357
+		 * the value will be the newly-inserted ID.
358
+		 * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option
359
+		 */
360
+		$old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), array());
361
+		if ($old_db_to_new_db_mapping) {
362
+			EE_Error::add_attention(
363
+				sprintf(
364
+					__(
365
+						"We noticed you have imported data via CSV from %s before. Because of this, IDs in your CSV have been mapped to their new IDs in %s",
366
+						"event_espresso"
367
+					),
368
+					$old_site_url,
369
+					site_url()
370
+				)
371
+			);
372
+		}
373
+		$old_db_to_new_db_mapping = $this->save_data_rows_to_db(
374
+			$csv_data_array,
375
+			$export_from_site_a_to_b,
376
+			$old_db_to_new_db_mapping
377
+		);
378
+
379
+		// save the mapping from old db to new db in case they try re-importing the same data from the same website again
380
+		update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping);
381
+
382
+		if ($this->_total_updates > 0) {
383
+			EE_Error::add_success(
384
+				sprintf(
385
+					__("%s existing records in the database were updated.", "event_espresso"),
386
+					$this->_total_updates
387
+				)
388
+			);
389
+			$success = true;
390
+		}
391
+		if ($this->_total_inserts > 0) {
392
+			EE_Error::add_success(
393
+				sprintf(__("%s new records were added to the database.", "event_espresso"), $this->_total_inserts)
394
+			);
395
+			$success = true;
396
+		}
397
+
398
+		if ($this->_total_update_errors > 0) {
399
+			EE_Error::add_error(
400
+				sprintf(
401
+					__(
402
+						"'One or more errors occurred, and a total of %s existing records in the database were <strong>not</strong> updated.'",
403
+						"event_espresso"
404
+					),
405
+					$this->_total_update_errors
406
+				),
407
+				__FILE__,
408
+				__FUNCTION__,
409
+				__LINE__
410
+			);
411
+			$error = true;
412
+		}
413
+		if ($this->_total_insert_errors > 0) {
414
+			EE_Error::add_error(
415
+				sprintf(
416
+					__(
417
+						"One or more errors occurred, and a total of %s new records were <strong>not</strong> added to the database.'",
418
+						"event_espresso"
419
+					),
420
+					$this->_total_insert_errors
421
+				),
422
+				__FILE__,
423
+				__FUNCTION__,
424
+				__LINE__
425
+			);
426
+			$error = true;
427
+		}
428
+
429
+		// lastly, we need to update the datetime and ticket sold amounts
430
+		// as those may have been affected by this
431
+		EEM_Ticket::instance()->update_tickets_sold(EEM_Ticket::instance()->get_all());
432
+
433
+		// if there was at least one success and absolutely no errors
434
+		if ($success && ! $error) {
435
+			return true;
436
+		} else {
437
+			return false;
438
+		}
439
+	}
440
+
441
+
442
+	/**
443
+	 * Processes the array of data, given the knowledge that it's from the same database or a different one,
444
+	 * and the mapping from temporary IDs to real IDs.
445
+	 * If the data is from a different database, we treat the primary keys and their corresponding
446
+	 * foreign keys as "temp Ids", basically identifiers that get mapped to real primary keys
447
+	 * in the real target database. As items are inserted, their temporary primary keys
448
+	 * are mapped to the real IDs in the target database. Also, before doing any update or
449
+	 * insert, we replace all the temp ID which are foreign keys with their mapped real IDs.
450
+	 * An exception: string primary keys are treated as real IDs, or else we'd need to
451
+	 * dynamically generate new string primary keys which would be very awkard for the country table etc.
452
+	 * Also, models with no primary key are strange too. We combine use their primar key INDEX (a
453
+	 * combination of fields) to create a unique string identifying the row and store
454
+	 * those in the mapping.
455
+	 *
456
+	 * If the data is from the same database, we usually treat primary keys as real IDs.
457
+	 * An exception is if there is nothing in the database for that ID. If that's the case,
458
+	 * we need to insert a new row for that ID, and then map from the non-existent ID
459
+	 * to the newly-inserted real ID.
460
+	 *
461
+	 * @param type $csv_data_array
462
+	 * @param type $export_from_site_a_to_b
463
+	 * @param type $old_db_to_new_db_mapping
464
+	 * @return array updated $old_db_to_new_db_mapping
465
+	 */
466
+	public function save_data_rows_to_db($csv_data_array, $export_from_site_a_to_b, $old_db_to_new_db_mapping)
467
+	{
468
+		foreach ($csv_data_array as $model_name_in_csv_data => $model_data_from_import) {
469
+			// now check that assumption was correct. If
470
+			if (EE_Registry::instance()->is_model_name($model_name_in_csv_data)) {
471
+				$model_name = $model_name_in_csv_data;
472
+			} else {
473
+				// no table info in the array and no table name passed to the function?? FAIL
474
+				EE_Error::add_error(
475
+					__(
476
+						'No table information was specified and/or found, therefore the import could not be completed',
477
+						'event_espresso'
478
+					),
479
+					__FILE__,
480
+					__FUNCTION__,
481
+					__LINE__
482
+				);
483
+				return false;
484
+			}
485
+			/* @var $model EEM_Base */
486
+			$model = EE_Registry::instance()->load_model($model_name);
487
+
488
+			// so without further ado, scanning all the data provided for primary keys and their inital values
489
+			foreach ($model_data_from_import as $model_object_data) {
490
+				// before we do ANYTHING, make sure the csv row wasn't just completely blank
491
+				$row_is_completely_empty = true;
492
+				foreach ($model_object_data as $field) {
493
+					if ($field) {
494
+						$row_is_completely_empty = false;
495
+					}
496
+				}
497
+				if ($row_is_completely_empty) {
498
+					continue;
499
+				}
500
+				// find the PK in the row of data (or a combined key if
501
+				// there is no primary key)
502
+				if ($model->has_primary_key_field()) {
503
+					$id_in_csv = $model_object_data[ $model->primary_key_name() ];
504
+				} else {
505
+					$id_in_csv = $model->get_index_primary_key_string($model_object_data);
506
+				}
507
+
508
+
509
+				$model_object_data = $this->_replace_temp_ids_with_mappings(
510
+					$model_object_data,
511
+					$model,
512
+					$old_db_to_new_db_mapping,
513
+					$export_from_site_a_to_b
514
+				);
515
+				// now we need to decide if we're going to add a new model object given the $model_object_data,
516
+				// or just update.
517
+				if ($export_from_site_a_to_b) {
518
+					$what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_other_db(
519
+						$id_in_csv,
520
+						$model_object_data,
521
+						$model,
522
+						$old_db_to_new_db_mapping
523
+					);
524
+				} else {// this is just a re-import
525
+					$what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_same_db(
526
+						$id_in_csv,
527
+						$model_object_data,
528
+						$model,
529
+						$old_db_to_new_db_mapping
530
+					);
531
+				}
532
+				if ($what_to_do == self::do_nothing) {
533
+					continue;
534
+				}
535
+
536
+				// double-check we actually want to insert, if that's what we're planning
537
+				// based on whether this item would be unique in the DB or not
538
+				if ($what_to_do == self::do_insert) {
539
+					// we're supposed to be inserting. But wait, will this thing
540
+					// be acceptable if inserted?
541
+					$conflicting = $model->get_one_conflicting($model_object_data, false);
542
+					if ($conflicting) {
543
+						// ok, this item would conflict if inserted. Just update the item that it conflicts with.
544
+						$what_to_do = self::do_update;
545
+						// and if this model has a primary key, remember its mapping
546
+						if ($model->has_primary_key_field()) {
547
+							$old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID();
548
+							$model_object_data[ $model->primary_key_name() ] = $conflicting->ID();
549
+						} else {
550
+							// we want to update this conflicting item, instead of inserting a conflicting item
551
+							// so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields
552
+							// for the WHERE conditions in the update). At the time of this comment, there were no models like this
553
+							foreach ($model->get_combined_primary_key_fields() as $key_field) {
554
+								$model_object_data[ $key_field->get_name() ] = $conflicting->get(
555
+									$key_field->get_name()
556
+								);
557
+							}
558
+						}
559
+					}
560
+				}
561
+				if ($what_to_do == self::do_insert) {
562
+					$old_db_to_new_db_mapping = $this->_insert_from_data_array(
563
+						$id_in_csv,
564
+						$model_object_data,
565
+						$model,
566
+						$old_db_to_new_db_mapping
567
+					);
568
+				} elseif ($what_to_do == self::do_update) {
569
+					$old_db_to_new_db_mapping = $this->_update_from_data_array(
570
+						$id_in_csv,
571
+						$model_object_data,
572
+						$model,
573
+						$old_db_to_new_db_mapping
574
+					);
575
+				} else {
576
+					throw new EE_Error(
577
+						sprintf(
578
+							__(
579
+								'Programming error. We shoudl be inserting or updating, but instead we are being told to "%s", whifh is invalid',
580
+								'event_espresso'
581
+							),
582
+							$what_to_do
583
+						)
584
+					);
585
+				}
586
+			}
587
+		}
588
+		return $old_db_to_new_db_mapping;
589
+	}
590
+
591
+
592
+	/**
593
+	 * Decides whether or not to insert, given that this data is from another database.
594
+	 * So, if the primary key of this $model_object_data already exists in the database,
595
+	 * it's just a coincidence and we should still insert. The only time we should
596
+	 * update is when we know what it maps to, or there's something that would
597
+	 * conflict (and we should instead just update that conflicting thing)
598
+	 *
599
+	 * @param string   $id_in_csv
600
+	 * @param array    $model_object_data        by reference so it can be modified
601
+	 * @param EEM_Base $model
602
+	 * @param array    $old_db_to_new_db_mapping by reference so it can be modified
603
+	 * @return string one of the consts on this class that starts with do_*
604
+	 */
605
+	protected function _decide_whether_to_insert_or_update_given_data_from_other_db(
606
+		$id_in_csv,
607
+		$model_object_data,
608
+		$model,
609
+		$old_db_to_new_db_mapping
610
+	) {
611
+		$model_name = $model->get_this_model_name();
612
+		// if it's a site-to-site export-and-import, see if this modelobject's id
613
+		// in the old data that we know of
614
+		if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) {
615
+			return self::do_update;
616
+		} else {
617
+			return self::do_insert;
618
+		}
619
+	}
620
+
621
+	/**
622
+	 * If this thing basically already exists in the database, we want to update it;
623
+	 * otherwise insert it (ie, someone tweaked the CSV file, or the item was
624
+	 * deleted in the database so it should be re-inserted)
625
+	 *
626
+	 * @param type     $id_in_csv
627
+	 * @param type     $model_object_data
628
+	 * @param EEM_Base $model
629
+	 * @param type     $old_db_to_new_db_mapping
630
+	 * @return
631
+	 */
632
+	protected function _decide_whether_to_insert_or_update_given_data_from_same_db(
633
+		$id_in_csv,
634
+		$model_object_data,
635
+		$model
636
+	) {
637
+		// in this case, check if this thing ACTUALLY exists in the database
638
+		if ($model->get_one_conflicting($model_object_data)) {
639
+			return self::do_update;
640
+		} else {
641
+			return self::do_insert;
642
+		}
643
+	}
644
+
645
+	/**
646
+	 * Using the $old_db_to_new_db_mapping array, replaces all the temporary IDs
647
+	 * with their mapped real IDs. Eg, if importing from site A to B, the mapping
648
+	 * file may indicate that the ID "my_event_id" maps to an actual event ID of 123.
649
+	 * So this function searches for any event temp Ids called "my_event_id" and
650
+	 * replaces them with 123.
651
+	 * Also, if there is no temp ID for the INT foreign keys from another database,
652
+	 * replaces them with 0 or the field's default.
653
+	 *
654
+	 * @param type     $model_object_data
655
+	 * @param EEM_Base $model
656
+	 * @param type     $old_db_to_new_db_mapping
657
+	 * @param boolean  $export_from_site_a_to_b
658
+	 * @return array updated model object data with temp IDs removed
659
+	 */
660
+	protected function _replace_temp_ids_with_mappings(
661
+		$model_object_data,
662
+		$model,
663
+		$old_db_to_new_db_mapping,
664
+		$export_from_site_a_to_b
665
+	) {
666
+		// if this model object's primary key is in the mapping, replace it
667
+		if ($model->has_primary_key_field() &&
668
+			$model->get_primary_key_field()->is_auto_increment() &&
669
+			isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ]) &&
670
+			isset(
671
+				$old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $model_object_data[ $model->primary_key_name() ] ]
672
+			)) {
673
+			$model_object_data[ $model->primary_key_name() ] = $old_db_to_new_db_mapping[ $model->get_this_model_name(
674
+			) ][ $model_object_data[ $model->primary_key_name() ] ];
675
+		}
676
+
677
+		try {
678
+			$model_name_field = $model->get_field_containing_related_model_name();
679
+			$models_pointed_to_by_model_name_field = $model_name_field->get_model_names_pointed_to();
680
+		} catch (EE_Error $e) {
681
+			$model_name_field = null;
682
+			$models_pointed_to_by_model_name_field = array();
683
+		}
684
+		foreach ($model->field_settings(true) as $field_obj) {
685
+			if ($field_obj instanceof EE_Foreign_Key_Int_Field) {
686
+				$models_pointed_to = $field_obj->get_model_names_pointed_to();
687
+				$found_a_mapping = false;
688
+				foreach ($models_pointed_to as $model_pointed_to_by_fk) {
689
+					if ($model_name_field) {
690
+						$value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ];
691
+						if ($value_of_model_name_field == $model_pointed_to_by_fk) {
692
+							$model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
693
+								$model_object_data[ $field_obj->get_name() ],
694
+								$model_pointed_to_by_fk,
695
+								$old_db_to_new_db_mapping,
696
+								$export_from_site_a_to_b
697
+							);
698
+							$found_a_mapping = true;
699
+							break;
700
+						}
701
+					} else {
702
+						$model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
703
+							$model_object_data[ $field_obj->get_name() ],
704
+							$model_pointed_to_by_fk,
705
+							$old_db_to_new_db_mapping,
706
+							$export_from_site_a_to_b
707
+						);
708
+						$found_a_mapping = true;
709
+					}
710
+					// once we've found a mapping for this field no need to continue
711
+					if ($found_a_mapping) {
712
+						break;
713
+					}
714
+				}
715
+			} else {
716
+				// it's a string foreign key (which we leave alone, because those are things
717
+				// like country names, which we'd really rather not make 2 USAs etc (we'd actually
718
+				// prefer to just update one)
719
+				// or it's just a regular value that ought to be replaced
720
+			}
721
+		}
722
+		//
723
+		if ($model instanceof EEM_Term_Taxonomy) {
724
+			$model_object_data = $this->_handle_split_term_ids($model_object_data);
725
+		}
726
+		return $model_object_data;
727
+	}
728
+
729
+	/**
730
+	 * If the data was exported PRE-4.2, but then imported POST-4.2, then the term_id
731
+	 * this term-taxonomy refers to may be out-of-date so we need to update it.
732
+	 * see https://make.wordpress.org/core/2015/02/16/taxonomy-term-splitting-in-4-2-a-developer-guide/
733
+	 *
734
+	 * @param type $model_object_data
735
+	 * @return array new model object data
736
+	 */
737
+	protected function _handle_split_term_ids($model_object_data)
738
+	{
739
+		if (isset($model_object_data['term_id'])
740
+			&& isset($model_object_data['taxonomy'])
741
+			&& apply_filters(
742
+				'FHEE__EE_Import__handle_split_term_ids__function_exists',
743
+				function_exists('wp_get_split_term'),
744
+				$model_object_data
745
+			)) {
746
+			$new_term_id = wp_get_split_term($model_object_data['term_id'], $model_object_data['taxonomy']);
747
+			if ($new_term_id) {
748
+				$model_object_data['term_id'] = $new_term_id;
749
+			}
750
+		}
751
+		return $model_object_data;
752
+	}
753
+
754
+	/**
755
+	 * Given the object's ID and its model's name, find it int he mapping data,
756
+	 * bearing in mind where it came from
757
+	 *
758
+	 * @param type   $object_id
759
+	 * @param string $model_name
760
+	 * @param array  $old_db_to_new_db_mapping
761
+	 * @param type   $export_from_site_a_to_b
762
+	 * @return int
763
+	 */
764
+	protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b)
765
+	{
766
+		if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) {
767
+			return $old_db_to_new_db_mapping[ $model_name ][ $object_id ];
768
+		} elseif ($object_id == '0' || $object_id == '') {
769
+			// leave as-is
770
+			return $object_id;
771
+		} elseif ($export_from_site_a_to_b) {
772
+			// we couldn't find a mapping for this, and it's from a different site,
773
+			// so blank it out
774
+			return null;
775
+		} elseif (! $export_from_site_a_to_b) {
776
+			// we coudln't find a mapping for this, but it's from thsi DB anyway
777
+			// so let's just leave it as-is
778
+			return $object_id;
779
+		}
780
+	}
781
+
782
+	/**
783
+	 *
784
+	 * @param type     $id_in_csv
785
+	 * @param type     $model_object_data
786
+	 * @param EEM_Base $model
787
+	 * @param type     $old_db_to_new_db_mapping
788
+	 * @return array updated $old_db_to_new_db_mapping
789
+	 */
790
+	protected function _insert_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
791
+	{
792
+		// remove the primary key, if there is one (we don't want it for inserts OR updates)
793
+		// we'll put it back in if we need it
794
+		if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) {
795
+			$effective_id = $model_object_data[ $model->primary_key_name() ];
796
+			unset($model_object_data[ $model->primary_key_name() ]);
797
+		} else {
798
+			$effective_id = $model->get_index_primary_key_string($model_object_data);
799
+		}
800
+		// the model takes care of validating the CSV's input
801
+		try {
802
+			$new_id = $model->insert($model_object_data);
803
+			if ($new_id) {
804
+				$old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id;
805
+				$this->_total_inserts++;
806
+				EE_Error::add_success(
807
+					sprintf(
808
+						__("Successfully added new %s (with id %s) with csv data %s", "event_espresso"),
809
+						$model->get_this_model_name(),
810
+						$new_id,
811
+						implode(",", $model_object_data)
812
+					)
813
+				);
814
+			} else {
815
+				$this->_total_insert_errors++;
816
+				// put the ID used back in there for the error message
817
+				if ($model->has_primary_key_field()) {
818
+					$model_object_data[ $model->primary_key_name() ] = $effective_id;
819
+				}
820
+				EE_Error::add_error(
821
+					sprintf(
822
+						__("Could not insert new %s with the csv data: %s", "event_espresso"),
823
+						$model->get_this_model_name(),
824
+						http_build_query($model_object_data)
825
+					),
826
+					__FILE__,
827
+					__FUNCTION__,
828
+					__LINE__
829
+				);
830
+			}
831
+		} catch (EE_Error $e) {
832
+			$this->_total_insert_errors++;
833
+			if ($model->has_primary_key_field()) {
834
+				$model_object_data[ $model->primary_key_name() ] = $effective_id;
835
+			}
836
+			EE_Error::add_error(
837
+				sprintf(
838
+					__("Could not insert new %s with the csv data: %s because %s", "event_espresso"),
839
+					$model->get_this_model_name(),
840
+					implode(",", $model_object_data),
841
+					$e->getMessage()
842
+				),
843
+				__FILE__,
844
+				__FUNCTION__,
845
+				__LINE__
846
+			);
847
+		}
848
+		return $old_db_to_new_db_mapping;
849
+	}
850
+
851
+	/**
852
+	 * Given the model object data, finds the row to update and updates it
853
+	 *
854
+	 * @param string|int $id_in_csv
855
+	 * @param array      $model_object_data
856
+	 * @param EEM_Base   $model
857
+	 * @param array      $old_db_to_new_db_mapping
858
+	 * @return array updated $old_db_to_new_db_mapping
859
+	 */
860
+	protected function _update_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
861
+	{
862
+		try {
863
+			// let's keep two copies of the model object data:
864
+			// one for performing an update, one for everthing else
865
+			$model_object_data_for_update = $model_object_data;
866
+			if ($model->has_primary_key_field()) {
867
+				$conditions = array($model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]);
868
+				// remove the primary key because we shouldn't use it for updating
869
+				unset($model_object_data_for_update[ $model->primary_key_name() ]);
870
+			} elseif ($model->get_combined_primary_key_fields() > 1) {
871
+				$conditions = array();
872
+				foreach ($model->get_combined_primary_key_fields() as $key_field) {
873
+					$conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ];
874
+				}
875
+			} else {
876
+				$model->primary_key_name(
877
+				);// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
878
+			}
879
+
880
+			$success = $model->update($model_object_data_for_update, array($conditions));
881
+			if ($success) {
882
+				$this->_total_updates++;
883
+				EE_Error::add_success(
884
+					sprintf(
885
+						__("Successfully updated %s with csv data %s", "event_espresso"),
886
+						$model->get_this_model_name(),
887
+						implode(",", $model_object_data_for_update)
888
+					)
889
+				);
890
+				// we should still record the mapping even though it was an update
891
+				// because if we were going to insert somethign but it was going to conflict
892
+				// we would have last-minute decided to update. So we'd like to know what we updated
893
+				// and so we record what record ended up being updated using the mapping
894
+				if ($model->has_primary_key_field()) {
895
+					$new_key_for_mapping = $model_object_data[ $model->primary_key_name() ];
896
+				} else {
897
+					// no primary key just a combined key
898
+					$new_key_for_mapping = $model->get_index_primary_key_string($model_object_data);
899
+				}
900
+				$old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping;
901
+			} else {
902
+				$matched_items = $model->get_all(array($conditions));
903
+				if (! $matched_items) {
904
+					// no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck?
905
+					$this->_total_update_errors++;
906
+					EE_Error::add_error(
907
+						sprintf(
908
+							__(
909
+								"Could not update %s with the csv data: '%s' for an unknown reason (using WHERE conditions %s)",
910
+								"event_espresso"
911
+							),
912
+							$model->get_this_model_name(),
913
+							http_build_query($model_object_data),
914
+							http_build_query($conditions)
915
+						),
916
+						__FILE__,
917
+						__FUNCTION__,
918
+						__LINE__
919
+					);
920
+				} else {
921
+					$this->_total_updates++;
922
+					EE_Error::add_success(
923
+						sprintf(
924
+							__(
925
+								"%s with csv data '%s' was found in the database and didn't need updating because all the data is identical.",
926
+								"event_espresso"
927
+							),
928
+							$model->get_this_model_name(),
929
+							implode(",", $model_object_data)
930
+						)
931
+					);
932
+				}
933
+			}
934
+		} catch (EE_Error $e) {
935
+			$this->_total_update_errors++;
936
+			$basic_message = sprintf(
937
+				__("Could not update %s with the csv data: %s because %s", "event_espresso"),
938
+				$model->get_this_model_name(),
939
+				implode(",", $model_object_data),
940
+				$e->getMessage()
941
+			);
942
+			$debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString();
943
+			EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__);
944
+		}
945
+		return $old_db_to_new_db_mapping;
946
+	}
947
+
948
+	/**
949
+	 * Gets the number of inserts performed since importer was instantiated or reset
950
+	 *
951
+	 * @return int
952
+	 */
953
+	public function get_total_inserts()
954
+	{
955
+		return $this->_total_inserts;
956
+	}
957
+
958
+	/**
959
+	 *  Gets the number of insert errors since importer was instantiated or reset
960
+	 *
961
+	 * @return int
962
+	 */
963
+	public function get_total_insert_errors()
964
+	{
965
+		return $this->_total_insert_errors;
966
+	}
967
+
968
+	/**
969
+	 *  Gets the number of updates performed since importer was instantiated or reset
970
+	 *
971
+	 * @return int
972
+	 */
973
+	public function get_total_updates()
974
+	{
975
+		return $this->_total_updates;
976
+	}
977
+
978
+	/**
979
+	 *  Gets the number of update errors since importer was instantiated or reset
980
+	 *
981
+	 * @return int
982
+	 */
983
+	public function get_total_update_errors()
984
+	{
985
+		return $this->_total_update_errors;
986
+	}
987 987
 }
Please login to merge, or discard this patch.
Spacing   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -135,7 +135,7 @@  discard block
 block discarded – undo
135 135
     public function import()
136 136
     {
137 137
 
138
-        require_once(EE_CLASSES . 'EE_CSV.class.php');
138
+        require_once(EE_CLASSES.'EE_CSV.class.php');
139 139
         $this->EE_CSV = EE_CSV::instance();
140 140
 
141 141
         if (isset($_REQUEST['import'])) {
@@ -179,18 +179,18 @@  discard block
 block discarded – undo
179 179
                         break;
180 180
                 }
181 181
 
182
-                if (! $error_msg) {
182
+                if ( ! $error_msg) {
183 183
                     $filename = $_FILES['file']['name'][0];
184 184
                     $file_ext = substr(strrchr($filename, '.'), 1);
185 185
                     $file_type = $_FILES['file']['type'][0];
186 186
                     $temp_file = $_FILES['file']['tmp_name'][0];
187
-                    $filesize = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB
187
+                    $filesize = $_FILES['file']['size'][0] / 1024; // convert from bytes to KB
188 188
 
189 189
                     if ($file_ext == 'csv') {
190
-                        $max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB
190
+                        $max_upload = $this->EE_CSV->get_max_upload_size(); // max upload size in KB
191 191
                         if ($filesize < $max_upload || true) {
192 192
                             $wp_upload_dir = str_replace(array('\\', '/'), DS, wp_upload_dir());
193
-                            $path_to_file = $wp_upload_dir['basedir'] . DS . 'espresso' . DS . $filename;
193
+                            $path_to_file = $wp_upload_dir['basedir'].DS.'espresso'.DS.$filename;
194 194
 
195 195
                             if (move_uploaded_file($temp_file, $path_to_file)) {
196 196
                                 // convert csv to array
@@ -324,8 +324,8 @@  discard block
 block discarded – undo
324 324
         // begin looking through the $csv_data_array, expecting the toplevel key to be the model's name...
325 325
         $old_site_url = 'none-specified';
326 326
         // hanlde metadata
327
-        if (isset($csv_data_array[ EE_CSV::metadata_header ])) {
328
-            $csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]);
327
+        if (isset($csv_data_array[EE_CSV::metadata_header])) {
328
+            $csv_metadata = array_shift($csv_data_array[EE_CSV::metadata_header]);
329 329
             // ok so its metadata, dont try to save it to ehte db obviously...
330 330
             if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) {
331 331
                 EE_Error::add_attention(
@@ -350,14 +350,14 @@  discard block
 block discarded – undo
350 350
                     )
351 351
                 );
352 352
             };
353
-            unset($csv_data_array[ EE_CSV::metadata_header ]);
353
+            unset($csv_data_array[EE_CSV::metadata_header]);
354 354
         }
355 355
         /**
356 356
          * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and
357 357
          * the value will be the newly-inserted ID.
358 358
          * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option
359 359
          */
360
-        $old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), array());
360
+        $old_db_to_new_db_mapping = get_option('ee_id_mapping_from'.sanitize_title($old_site_url), array());
361 361
         if ($old_db_to_new_db_mapping) {
362 362
             EE_Error::add_attention(
363 363
                 sprintf(
@@ -377,7 +377,7 @@  discard block
 block discarded – undo
377 377
         );
378 378
 
379 379
         // save the mapping from old db to new db in case they try re-importing the same data from the same website again
380
-        update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping);
380
+        update_option('ee_id_mapping_from'.sanitize_title($old_site_url), $old_db_to_new_db_mapping);
381 381
 
382 382
         if ($this->_total_updates > 0) {
383 383
             EE_Error::add_success(
@@ -500,7 +500,7 @@  discard block
 block discarded – undo
500 500
                 // find the PK in the row of data (or a combined key if
501 501
                 // there is no primary key)
502 502
                 if ($model->has_primary_key_field()) {
503
-                    $id_in_csv = $model_object_data[ $model->primary_key_name() ];
503
+                    $id_in_csv = $model_object_data[$model->primary_key_name()];
504 504
                 } else {
505 505
                     $id_in_csv = $model->get_index_primary_key_string($model_object_data);
506 506
                 }
@@ -544,14 +544,14 @@  discard block
 block discarded – undo
544 544
                         $what_to_do = self::do_update;
545 545
                         // and if this model has a primary key, remember its mapping
546 546
                         if ($model->has_primary_key_field()) {
547
-                            $old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID();
548
-                            $model_object_data[ $model->primary_key_name() ] = $conflicting->ID();
547
+                            $old_db_to_new_db_mapping[$model_name][$id_in_csv] = $conflicting->ID();
548
+                            $model_object_data[$model->primary_key_name()] = $conflicting->ID();
549 549
                         } else {
550 550
                             // we want to update this conflicting item, instead of inserting a conflicting item
551 551
                             // so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields
552 552
                             // for the WHERE conditions in the update). At the time of this comment, there were no models like this
553 553
                             foreach ($model->get_combined_primary_key_fields() as $key_field) {
554
-                                $model_object_data[ $key_field->get_name() ] = $conflicting->get(
554
+                                $model_object_data[$key_field->get_name()] = $conflicting->get(
555 555
                                     $key_field->get_name()
556 556
                                 );
557 557
                             }
@@ -611,7 +611,7 @@  discard block
 block discarded – undo
611 611
         $model_name = $model->get_this_model_name();
612 612
         // if it's a site-to-site export-and-import, see if this modelobject's id
613 613
         // in the old data that we know of
614
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) {
614
+        if (isset($old_db_to_new_db_mapping[$model_name][$id_in_csv])) {
615 615
             return self::do_update;
616 616
         } else {
617 617
             return self::do_insert;
@@ -666,12 +666,12 @@  discard block
 block discarded – undo
666 666
         // if this model object's primary key is in the mapping, replace it
667 667
         if ($model->has_primary_key_field() &&
668 668
             $model->get_primary_key_field()->is_auto_increment() &&
669
-            isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ]) &&
669
+            isset($old_db_to_new_db_mapping[$model->get_this_model_name()]) &&
670 670
             isset(
671
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $model_object_data[ $model->primary_key_name() ] ]
671
+                $old_db_to_new_db_mapping[$model->get_this_model_name()][$model_object_data[$model->primary_key_name()]]
672 672
             )) {
673
-            $model_object_data[ $model->primary_key_name() ] = $old_db_to_new_db_mapping[ $model->get_this_model_name(
674
-            ) ][ $model_object_data[ $model->primary_key_name() ] ];
673
+            $model_object_data[$model->primary_key_name()] = $old_db_to_new_db_mapping[$model->get_this_model_name(
674
+            )][$model_object_data[$model->primary_key_name()]];
675 675
         }
676 676
 
677 677
         try {
@@ -687,10 +687,10 @@  discard block
 block discarded – undo
687 687
                 $found_a_mapping = false;
688 688
                 foreach ($models_pointed_to as $model_pointed_to_by_fk) {
689 689
                     if ($model_name_field) {
690
-                        $value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ];
690
+                        $value_of_model_name_field = $model_object_data[$model_name_field->get_name()];
691 691
                         if ($value_of_model_name_field == $model_pointed_to_by_fk) {
692
-                            $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
693
-                                $model_object_data[ $field_obj->get_name() ],
692
+                            $model_object_data[$field_obj->get_name()] = $this->_find_mapping_in(
693
+                                $model_object_data[$field_obj->get_name()],
694 694
                                 $model_pointed_to_by_fk,
695 695
                                 $old_db_to_new_db_mapping,
696 696
                                 $export_from_site_a_to_b
@@ -699,8 +699,8 @@  discard block
 block discarded – undo
699 699
                             break;
700 700
                         }
701 701
                     } else {
702
-                        $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
703
-                            $model_object_data[ $field_obj->get_name() ],
702
+                        $model_object_data[$field_obj->get_name()] = $this->_find_mapping_in(
703
+                            $model_object_data[$field_obj->get_name()],
704 704
                             $model_pointed_to_by_fk,
705 705
                             $old_db_to_new_db_mapping,
706 706
                             $export_from_site_a_to_b
@@ -763,8 +763,8 @@  discard block
 block discarded – undo
763 763
      */
764 764
     protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b)
765 765
     {
766
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) {
767
-            return $old_db_to_new_db_mapping[ $model_name ][ $object_id ];
766
+        if (isset($old_db_to_new_db_mapping[$model_name][$object_id])) {
767
+            return $old_db_to_new_db_mapping[$model_name][$object_id];
768 768
         } elseif ($object_id == '0' || $object_id == '') {
769 769
             // leave as-is
770 770
             return $object_id;
@@ -772,7 +772,7 @@  discard block
 block discarded – undo
772 772
             // we couldn't find a mapping for this, and it's from a different site,
773 773
             // so blank it out
774 774
             return null;
775
-        } elseif (! $export_from_site_a_to_b) {
775
+        } elseif ( ! $export_from_site_a_to_b) {
776 776
             // we coudln't find a mapping for this, but it's from thsi DB anyway
777 777
             // so let's just leave it as-is
778 778
             return $object_id;
@@ -792,8 +792,8 @@  discard block
 block discarded – undo
792 792
         // remove the primary key, if there is one (we don't want it for inserts OR updates)
793 793
         // we'll put it back in if we need it
794 794
         if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) {
795
-            $effective_id = $model_object_data[ $model->primary_key_name() ];
796
-            unset($model_object_data[ $model->primary_key_name() ]);
795
+            $effective_id = $model_object_data[$model->primary_key_name()];
796
+            unset($model_object_data[$model->primary_key_name()]);
797 797
         } else {
798 798
             $effective_id = $model->get_index_primary_key_string($model_object_data);
799 799
         }
@@ -801,7 +801,7 @@  discard block
 block discarded – undo
801 801
         try {
802 802
             $new_id = $model->insert($model_object_data);
803 803
             if ($new_id) {
804
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id;
804
+                $old_db_to_new_db_mapping[$model->get_this_model_name()][$id_in_csv] = $new_id;
805 805
                 $this->_total_inserts++;
806 806
                 EE_Error::add_success(
807 807
                     sprintf(
@@ -815,7 +815,7 @@  discard block
 block discarded – undo
815 815
                 $this->_total_insert_errors++;
816 816
                 // put the ID used back in there for the error message
817 817
                 if ($model->has_primary_key_field()) {
818
-                    $model_object_data[ $model->primary_key_name() ] = $effective_id;
818
+                    $model_object_data[$model->primary_key_name()] = $effective_id;
819 819
                 }
820 820
                 EE_Error::add_error(
821 821
                     sprintf(
@@ -831,7 +831,7 @@  discard block
 block discarded – undo
831 831
         } catch (EE_Error $e) {
832 832
             $this->_total_insert_errors++;
833 833
             if ($model->has_primary_key_field()) {
834
-                $model_object_data[ $model->primary_key_name() ] = $effective_id;
834
+                $model_object_data[$model->primary_key_name()] = $effective_id;
835 835
             }
836 836
             EE_Error::add_error(
837 837
                 sprintf(
@@ -864,17 +864,17 @@  discard block
 block discarded – undo
864 864
             // one for performing an update, one for everthing else
865 865
             $model_object_data_for_update = $model_object_data;
866 866
             if ($model->has_primary_key_field()) {
867
-                $conditions = array($model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]);
867
+                $conditions = array($model->primary_key_name() => $model_object_data[$model->primary_key_name()]);
868 868
                 // remove the primary key because we shouldn't use it for updating
869
-                unset($model_object_data_for_update[ $model->primary_key_name() ]);
869
+                unset($model_object_data_for_update[$model->primary_key_name()]);
870 870
             } elseif ($model->get_combined_primary_key_fields() > 1) {
871 871
                 $conditions = array();
872 872
                 foreach ($model->get_combined_primary_key_fields() as $key_field) {
873
-                    $conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ];
873
+                    $conditions[$key_field->get_name()] = $model_object_data[$key_field->get_name()];
874 874
                 }
875 875
             } else {
876 876
                 $model->primary_key_name(
877
-                );// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
877
+                ); // this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
878 878
             }
879 879
 
880 880
             $success = $model->update($model_object_data_for_update, array($conditions));
@@ -892,15 +892,15 @@  discard block
 block discarded – undo
892 892
                 // we would have last-minute decided to update. So we'd like to know what we updated
893 893
                 // and so we record what record ended up being updated using the mapping
894 894
                 if ($model->has_primary_key_field()) {
895
-                    $new_key_for_mapping = $model_object_data[ $model->primary_key_name() ];
895
+                    $new_key_for_mapping = $model_object_data[$model->primary_key_name()];
896 896
                 } else {
897 897
                     // no primary key just a combined key
898 898
                     $new_key_for_mapping = $model->get_index_primary_key_string($model_object_data);
899 899
                 }
900
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping;
900
+                $old_db_to_new_db_mapping[$model->get_this_model_name()][$id_in_csv] = $new_key_for_mapping;
901 901
             } else {
902 902
                 $matched_items = $model->get_all(array($conditions));
903
-                if (! $matched_items) {
903
+                if ( ! $matched_items) {
904 904
                     // no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck?
905 905
                     $this->_total_update_errors++;
906 906
                     EE_Error::add_error(
@@ -939,7 +939,7 @@  discard block
 block discarded – undo
939 939
                 implode(",", $model_object_data),
940 940
                 $e->getMessage()
941 941
             );
942
-            $debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString();
942
+            $debug_message = $basic_message.' Stack trace: '.$e->getTraceAsString();
943 943
             EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__);
944 944
         }
945 945
         return $old_db_to_new_db_mapping;
Please login to merge, or discard this patch.
core/db_classes/EE_Term_Relationship.class.php 1 patch
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -10,23 +10,23 @@
 block discarded – undo
10 10
 class EE_Term_Relationship extends EE_Base_Class
11 11
 {
12 12
 
13
-    /**
14
-     * @param array $props_n_values
15
-     * @return EE_Term_Relationship
16
-     */
17
-    public static function new_instance($props_n_values = array())
18
-    {
19
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
20
-        return $has_object ? $has_object : new self($props_n_values);
21
-    }
13
+	/**
14
+	 * @param array $props_n_values
15
+	 * @return EE_Term_Relationship
16
+	 */
17
+	public static function new_instance($props_n_values = array())
18
+	{
19
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
20
+		return $has_object ? $has_object : new self($props_n_values);
21
+	}
22 22
 
23 23
 
24
-    /**
25
-     * @param array $props_n_values
26
-     * @return EE_Term_Relationship
27
-     */
28
-    public static function new_instance_from_db($props_n_values = array())
29
-    {
30
-        return new self($props_n_values, true);
31
-    }
24
+	/**
25
+	 * @param array $props_n_values
26
+	 * @return EE_Term_Relationship
27
+	 */
28
+	public static function new_instance_from_db($props_n_values = array())
29
+	{
30
+		return new self($props_n_values, true);
31
+	}
32 32
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Export.class.php 2 patches
Spacing   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -44,7 +44,7 @@  discard block
 block discarded – undo
44 44
     {
45 45
         $this->_req_data = $request_data;
46 46
         $this->today = date("Y-m-d", time());
47
-        require_once(EE_CLASSES . 'EE_CSV.class.php');
47
+        require_once(EE_CLASSES.'EE_CSV.class.php');
48 48
         $this->EE_CSV = EE_CSV::instance();
49 49
     }
50 50
 
@@ -167,7 +167,7 @@  discard block
 block discarded – undo
167 167
                 $value_to_equal = $EVT_ID;
168 168
                 $event = EE_Registry::instance()->load_model('Event')->get_one_by_ID($EVT_ID);
169 169
 
170
-                $filename = 'event-' . ($event instanceof EE_Event ? $event->slug() : __('unknown', 'event_espresso'));
170
+                $filename = 'event-'.($event instanceof EE_Event ? $event->slug() : __('unknown', 'event_espresso'));
171 171
             }
172 172
             $event_query_params[0]['EVT_ID'] = $value_to_equal;
173 173
             $related_models_query_params[0]['Event.EVT_ID'] = $value_to_equal;
@@ -216,7 +216,7 @@  discard block
 block discarded – undo
216 216
 
217 217
         $filename = $this->generate_filename($filename);
218 218
 
219
-        if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $model_data)) {
219
+        if ( ! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $model_data)) {
220 220
             EE_Error::add_error(
221 221
                 __(
222 222
                     "'An error occurred and the Event details could not be exported from the database.'",
@@ -243,16 +243,16 @@  discard block
 block discarded – undo
243 243
             foreach (EEM_Attendee::instance()->field_settings() as $field_name => $field_obj) {
244 244
                 if ($field_name == 'STA_ID') {
245 245
                     $state_name_field = EEM_State::instance()->field_settings_for('STA_name');
246
-                    $csv_row[ __('State', 'event_espresso') ] = $attendee_row[ $state_name_field->get_qualified_column(
247
-                    ) ];
246
+                    $csv_row[__('State', 'event_espresso')] = $attendee_row[$state_name_field->get_qualified_column(
247
+                    )];
248 248
                 } elseif ($field_name == 'CNT_ISO') {
249 249
                     $country_name_field = EEM_Country::instance()->field_settings_for('CNT_name');
250
-                    $csv_row[ __(
250
+                    $csv_row[__(
251 251
                         'Country',
252 252
                         'event_espresso'
253
-                    ) ] = $attendee_row[ $country_name_field->get_qualified_column() ];
253
+                    )] = $attendee_row[$country_name_field->get_qualified_column()];
254 254
                 } else {
255
-                    $csv_row[ $field_obj->get_nicename() ] = $attendee_row[ $field_obj->get_qualified_column() ];
255
+                    $csv_row[$field_obj->get_nicename()] = $attendee_row[$field_obj->get_qualified_column()];
256 256
                 }
257 257
             }
258 258
             $csv_data[] = $csv_row;
@@ -291,7 +291,7 @@  discard block
 block discarded – undo
291 291
         $model_data = $this->_get_export_data_for_models($models_to_export);
292 292
         $filename = $this->generate_filename('all-attendees');
293 293
 
294
-        if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $model_data)) {
294
+        if ( ! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $model_data)) {
295 295
             EE_Error::add_error(
296 296
                 __(
297 297
                     'An error occurred and the Attendee data could not be exported from the database.',
@@ -409,9 +409,9 @@  discard block
 block discarded – undo
409 409
         foreach ($registration_rows as $reg_row) {
410 410
             if (is_array($reg_row)) {
411 411
                 $reg_csv_array = array();
412
-                if (! $event_id) {
412
+                if ( ! $event_id) {
413 413
                     // get the event's name and Id
414
-                    $reg_csv_array[ __('Event', 'event_espresso') ] = sprintf(
414
+                    $reg_csv_array[__('Event', 'event_espresso')] = sprintf(
415 415
                         __('%1$s (%2$s)', 'event_espresso'),
416 416
                         $this->_prepare_value_from_db_for_display(
417 417
                             EEM_Event::instance(),
@@ -457,13 +457,13 @@  discard block
 block discarded – undo
457 457
                         $value = $this->_prepare_value_from_db_for_display(
458 458
                             $reg_model,
459 459
                             $field_name,
460
-                            $reg_row[ $field->get_qualified_column() ]
460
+                            $reg_row[$field->get_qualified_column()]
461 461
                         );
462 462
                     }
463
-                    $reg_csv_array[ $this->_get_column_name_for_field($field) ] = $value;
463
+                    $reg_csv_array[$this->_get_column_name_for_field($field)] = $value;
464 464
                     if ($field_name == 'REG_final_price') {
465 465
                         // add a column named Currency after the final price
466
-                        $reg_csv_array[ __("Currency", "event_espresso") ] = EE_Config::instance()->currency->code;
466
+                        $reg_csv_array[__("Currency", "event_espresso")] = EE_Config::instance()->currency->code;
467 467
                     }
468 468
                 }
469 469
                 // get pretty status
@@ -475,23 +475,23 @@  discard block
 block discarded – undo
475 475
                     false,
476 476
                     'sentence'
477 477
                 );
478
-                $reg_csv_array[ __(
478
+                $reg_csv_array[__(
479 479
                     "Registration Status",
480 480
                     'event_espresso'
481
-                ) ] = $stati[ $reg_row['Registration.STS_ID'] ];
481
+                )] = $stati[$reg_row['Registration.STS_ID']];
482 482
                 // get pretty trnasaction status
483
-                $reg_csv_array[ __(
483
+                $reg_csv_array[__(
484 484
                     "Transaction Status",
485 485
                     'event_espresso'
486
-                ) ] = $stati[ $reg_row['TransactionTable.STS_ID'] ];
487
-                $reg_csv_array[ __('Transaction Amount Due', 'event_espresso') ] = $is_primary_reg
486
+                )] = $stati[$reg_row['TransactionTable.STS_ID']];
487
+                $reg_csv_array[__('Transaction Amount Due', 'event_espresso')] = $is_primary_reg
488 488
                     ? $this->_prepare_value_from_db_for_display(
489 489
                         EEM_Transaction::instance(),
490 490
                         'TXN_total',
491 491
                         $reg_row['TransactionTable.TXN_total'],
492 492
                         'localized_float'
493 493
                     ) : '0.00';
494
-                $reg_csv_array[ __('Amount Paid', 'event_espresso') ] = $is_primary_reg
494
+                $reg_csv_array[__('Amount Paid', 'event_espresso')] = $is_primary_reg
495 495
                     ? $this->_prepare_value_from_db_for_display(
496 496
                         EEM_Transaction::instance(),
497 497
                         'TXN_paid',
@@ -523,15 +523,15 @@  discard block
 block discarded – undo
523 523
                             ? $payment_method_and_gateway_txn_id['payment_time'] : '';
524 524
                     }
525 525
                 }
526
-                $reg_csv_array[ __('Payment Date(s)', 'event_espresso') ] = implode(',', $payment_times);
527
-                $reg_csv_array[ __('Payment Method(s)', 'event_espresso') ] = implode(",", $payment_methods);
528
-                $reg_csv_array[ __('Gateway Transaction ID(s)', 'event_espresso') ] = implode(
526
+                $reg_csv_array[__('Payment Date(s)', 'event_espresso')] = implode(',', $payment_times);
527
+                $reg_csv_array[__('Payment Method(s)', 'event_espresso')] = implode(",", $payment_methods);
528
+                $reg_csv_array[__('Gateway Transaction ID(s)', 'event_espresso')] = implode(
529 529
                     ',',
530 530
                     $gateway_txn_ids_etc
531 531
                 );
532 532
 
533 533
                 // get whether or not the user has checked in
534
-                $reg_csv_array[ __("Check-Ins", "event_espresso") ] = $reg_model->count_related(
534
+                $reg_csv_array[__("Check-Ins", "event_espresso")] = $reg_model->count_related(
535 535
                     $reg_row['Registration.REG_ID'],
536 536
                     'Checkin'
537 537
                 );
@@ -561,8 +561,8 @@  discard block
 block discarded – undo
561 561
                     $ticket_name = __('Unknown', 'event_espresso');
562 562
                     $datetimes_strings = array(__('Unknown', 'event_espresso'));
563 563
                 }
564
-                $reg_csv_array[ $ticket_model->field_settings_for('TKT_name')->get_nicename() ] = $ticket_name;
565
-                $reg_csv_array[ __("Datetimes of Ticket", "event_espresso") ] = implode(", ", $datetimes_strings);
564
+                $reg_csv_array[$ticket_model->field_settings_for('TKT_name')->get_nicename()] = $ticket_name;
565
+                $reg_csv_array[__("Datetimes of Ticket", "event_espresso")] = implode(", ", $datetimes_strings);
566 566
                 // get datetime(s) of registration
567 567
 
568 568
                 // add attendee columns
@@ -583,20 +583,20 @@  discard block
 block discarded – undo
583 583
                             $value = $this->_prepare_value_from_db_for_display(
584 584
                                 EEM_Attendee::instance(),
585 585
                                 $att_field_name,
586
-                                $reg_row[ $field_obj->get_qualified_column() ]
586
+                                $reg_row[$field_obj->get_qualified_column()]
587 587
                             );
588 588
                         }
589 589
                     } else {
590 590
                         $value = '';
591 591
                     }
592 592
 
593
-                    $reg_csv_array[ $this->_get_column_name_for_field($field_obj) ] = $value;
593
+                    $reg_csv_array[$this->_get_column_name_for_field($field_obj)] = $value;
594 594
                 }
595 595
 
596 596
                 // make sure each registration has the same questions in the same order
597 597
                 foreach ($questions_for_these_regs_rows as $question_row) {
598
-                    if (! isset($reg_csv_array[ $question_row['Question.QST_admin_label'] ])) {
599
-                        $reg_csv_array[ $question_row['Question.QST_admin_label'] ] = null;
598
+                    if ( ! isset($reg_csv_array[$question_row['Question.QST_admin_label']])) {
599
+                        $reg_csv_array[$question_row['Question.QST_admin_label']] = null;
600 600
                     }
601 601
                 }
602 602
                 // now fill out the questions THEY answered
@@ -614,11 +614,11 @@  discard block
 block discarded – undo
614 614
                         $question_label = sprintf(__('Question $s', 'event_espresso'), $answer_row['Answer.QST_ID']);
615 615
                     }
616 616
                     if (isset($answer_row['Question.QST_type']) && $answer_row['Question.QST_type'] == EEM_Question::QST_type_state) {
617
-                        $reg_csv_array[ $question_label ] = EEM_State::instance()->get_state_name_by_ID(
617
+                        $reg_csv_array[$question_label] = EEM_State::instance()->get_state_name_by_ID(
618 618
                             $answer_row['Answer.ANS_value']
619 619
                         );
620 620
                     } else {
621
-                        $reg_csv_array[ $question_label ] = $this->_prepare_value_from_db_for_display(
621
+                        $reg_csv_array[$question_label] = $this->_prepare_value_from_db_for_display(
622 622
                             EEM_Answer::instance(),
623 623
                             'ANS_value',
624 624
                             $answer_row['Answer.ANS_value']
@@ -644,16 +644,16 @@  discard block
 block discarded – undo
644 644
                 $model = EE_Registry::instance()->load_model($model_name);
645 645
                 foreach ($field_list as $field_name) {
646 646
                     $field = $model->field_settings_for($field_name);
647
-                    $reg_csv_array[ $this->_get_column_name_for_field(
647
+                    $reg_csv_array[$this->_get_column_name_for_field(
648 648
                         $field
649
-                    ) ] = null;// $registration->get($field->get_name());
649
+                    )] = null; // $registration->get($field->get_name());
650 650
                 }
651 651
             }
652 652
             $registrations_csv_ready_array [] = $reg_csv_array;
653 653
         }
654 654
         if ($event_id) {
655 655
             $event_slug = EEM_Event::instance()->get_var(array(array('EVT_ID' => $event_id)), 'EVT_slug');
656
-            if (! $event_slug) {
656
+            if ( ! $event_slug) {
657 657
                 $event_slug = __('unknown', 'event_espresso');
658 658
             }
659 659
         } else {
@@ -674,7 +674,7 @@  discard block
 block discarded – undo
674 674
      */
675 675
     protected function _get_column_name_for_field(EE_Model_Field_Base $field)
676 676
     {
677
-        return $field->get_nicename() . "[" . $field->get_name() . "]";
677
+        return $field->get_nicename()."[".$field->get_name()."]";
678 678
     }
679 679
 
680 680
 
@@ -697,7 +697,7 @@  discard block
 block discarded – undo
697 697
             } else {
698 698
                 // generate regular where = clause
699 699
                 $EVT_CAT_ID = absint($this->_req_data['EVT_CAT_ID']);
700
-                $filename = 'event-category#' . $EVT_CAT_ID;
700
+                $filename = 'event-category#'.$EVT_CAT_ID;
701 701
                 $query_params[0]['term_taxonomy_id'] = $EVT_CAT_ID;
702 702
             }
703 703
         } else {
@@ -712,7 +712,7 @@  discard block
 block discarded – undo
712 712
         $table_data = $this->_get_export_data_for_models($tables_to_export);
713 713
         $filename = $this->generate_filename($filename);
714 714
 
715
-        if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $table_data)) {
715
+        if ( ! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $table_data)) {
716 716
             EE_Error::add_error(
717 717
                 __(
718 718
                     'An error occurred and the Category details could not be exported from the database.',
@@ -735,8 +735,8 @@  discard block
 block discarded – undo
735 735
     private function generate_filename($export_name = '')
736 736
     {
737 737
         if ($export_name != '') {
738
-            $filename = get_bloginfo('name') . '-' . $export_name;
739
-            $filename = sanitize_key($filename) . '-' . $this->today;
738
+            $filename = get_bloginfo('name').'-'.$export_name;
739
+            $filename = sanitize_key($filename).'-'.$this->today;
740 740
             return $filename;
741 741
         } else {
742 742
             EE_Error::add_error(__("No filename was provided", "event_espresso"), __FILE__, __FUNCTION__, __LINE__);
@@ -765,25 +765,25 @@  discard block
 block discarded – undo
765 765
                 $model = EE_Registry::instance()->load_model($model_name);
766 766
                 $model_objects = $model->get_all($query_params);
767 767
 
768
-                $table_data[ $model_name ] = array();
768
+                $table_data[$model_name] = array();
769 769
                 foreach ($model_objects as $model_object) {
770 770
                     $model_data_array = array();
771 771
                     $fields = $model->field_settings();
772 772
                     foreach ($fields as $field) {
773
-                        $column_name = $field->get_nicename() . "[" . $field->get_name() . "]";
773
+                        $column_name = $field->get_nicename()."[".$field->get_name()."]";
774 774
                         if ($field instanceof EE_Datetime_Field) {
775 775
                             // $field->set_date_format('Y-m-d');
776 776
                             // $field->set_time_format('H:i:s');
777
-                            $model_data_array[ $column_name ] = $model_object->get_datetime(
777
+                            $model_data_array[$column_name] = $model_object->get_datetime(
778 778
                                 $field->get_name(),
779 779
                                 'Y-m-d',
780 780
                                 'H:i:s'
781 781
                             );
782 782
                         } else {
783
-                            $model_data_array[ $column_name ] = $model_object->get($field->get_name());
783
+                            $model_data_array[$column_name] = $model_object->get($field->get_name());
784 784
                         }
785 785
                     }
786
-                    $table_data[ $model_name ][] = $model_data_array;
786
+                    $table_data[$model_name][] = $model_data_array;
787 787
                 }
788 788
             }
789 789
         }
Please login to merge, or discard this patch.
Indentation   +773 added lines, -773 removed lines patch added patch discarded remove patch
@@ -16,777 +16,777 @@
 block discarded – undo
16 16
 class EE_Export
17 17
 {
18 18
 
19
-    const option_prefix = 'ee_report_job_';
20
-
21
-
22
-    // instance of the EE_Export object
23
-    private static $_instance = null;
24
-
25
-    // instance of the EE_CSV object
26
-    /**
27
-     *
28
-     * @var EE_CSV
29
-     */
30
-    public $EE_CSV = null;
31
-
32
-
33
-    private $_req_data = array();
34
-
35
-
36
-    /**
37
-     *        private constructor to prevent direct creation
38
-     *
39
-     * @Constructor
40
-     * @access private
41
-     * @param array $request_data
42
-     */
43
-    private function __construct($request_data = array())
44
-    {
45
-        $this->_req_data = $request_data;
46
-        $this->today = date("Y-m-d", time());
47
-        require_once(EE_CLASSES . 'EE_CSV.class.php');
48
-        $this->EE_CSV = EE_CSV::instance();
49
-    }
50
-
51
-
52
-    /**
53
-     *        @ singleton method used to instantiate class object
54
-     *        @ access public
55
-     *
56
-     * @param array $request_data
57
-     * @return \EE_Export
58
-     */
59
-    public static function instance($request_data = array())
60
-    {
61
-        // check if class object is instantiated
62
-        if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Export)) {
63
-            self::$_instance = new self($request_data);
64
-        }
65
-        return self::$_instance;
66
-    }
67
-
68
-
69
-    /**
70
-     * @Export Event Espresso data - routes export requests
71
-     * @access public
72
-     * @return void | bool
73
-     */
74
-    public function export()
75
-    {
76
-        // in case of bulk exports, the "actual" action will be in action2, but first check regular action for "export" keyword
77
-        if (isset($this->_req_data['action']) && strpos($this->_req_data['action'], 'export') === false) {
78
-            // check if action2 has export action
79
-            if (isset($this->_req_data['action2']) && strpos($this->_req_data['action2'], 'export') !== false) {
80
-                // whoop! there it is!
81
-                $this->_req_data['action'] = $this->_req_data['action2'];
82
-            }
83
-        }
84
-
85
-        $this->_req_data['export'] = isset($this->_req_data['export']) ? $this->_req_data['export'] : '';
86
-
87
-        switch ($this->_req_data['export']) {
88
-            case 'report':
89
-                switch ($this->_req_data['action']) {
90
-                    case "event":
91
-                    case "export_events":
92
-                    case 'all_event_data':
93
-                        $this->export_all_event_data();
94
-                        break;
95
-
96
-                    case 'registrations_report_for_event':
97
-                        $this->report_registrations_for_event($this->_req_data['EVT_ID']);
98
-                        break;
99
-
100
-                    case 'attendees':
101
-                        $this->export_attendees();
102
-                        break;
103
-
104
-                    case 'categories':
105
-                        $this->export_categories();
106
-                        break;
107
-
108
-                    default:
109
-                        EE_Error::add_error(
110
-                            __('An error occurred! The requested export report could not be found.', 'event_espresso'),
111
-                            __FILE__,
112
-                            __FUNCTION__,
113
-                            __LINE__
114
-                        );
115
-                        return false;
116
-                        break;
117
-                }
118
-                break; // end of switch export : report
119
-            default:
120
-                break;
121
-        } // end of switch export
122
-
123
-        exit;
124
-    }
125
-
126
-    /**
127
-     * Downloads a CSV file with all the columns, but no data. This should be used for importing
128
-     *
129
-     * @return null kills execution
130
-     */
131
-    public function export_sample()
132
-    {
133
-        $event = EEM_Event::instance()->get_one();
134
-        $this->_req_data['EVT_ID'] = $event->ID();
135
-        $this->export_all_event_data();
136
-    }
137
-
138
-
139
-    /**
140
-     * @Export data for ALL events
141
-     * @access public
142
-     * @return void
143
-     */
144
-    public function export_all_event_data()
145
-    {
146
-        // are any Event IDs set?
147
-        $event_query_params = array();
148
-        $related_models_query_params = array();
149
-        $related_through_reg_query_params = array();
150
-        $datetime_ticket_query_params = array();
151
-        $price_query_params = array();
152
-        $price_type_query_params = array();
153
-        $term_query_params = array();
154
-        $state_country_query_params = array();
155
-        $question_group_query_params = array();
156
-        $question_query_params = array();
157
-        if (isset($this->_req_data['EVT_ID'])) {
158
-            // do we have an array of IDs ?
159
-
160
-            if (is_array($this->_req_data['EVT_ID'])) {
161
-                $EVT_IDs = array_map('sanitize_text_field', $this->_req_data['EVT_ID']);
162
-                $value_to_equal = array('IN', $EVT_IDs);
163
-                $filename = 'events';
164
-            } else {
165
-                // generate regular where = clause
166
-                $EVT_ID = absint($this->_req_data['EVT_ID']);
167
-                $value_to_equal = $EVT_ID;
168
-                $event = EE_Registry::instance()->load_model('Event')->get_one_by_ID($EVT_ID);
169
-
170
-                $filename = 'event-' . ($event instanceof EE_Event ? $event->slug() : __('unknown', 'event_espresso'));
171
-            }
172
-            $event_query_params[0]['EVT_ID'] = $value_to_equal;
173
-            $related_models_query_params[0]['Event.EVT_ID'] = $value_to_equal;
174
-            $related_through_reg_query_params[0]['Registration.EVT_ID'] = $value_to_equal;
175
-            $datetime_ticket_query_params[0]['Datetime.EVT_ID'] = $value_to_equal;
176
-            $price_query_params[0]['Ticket.Datetime.EVT_ID'] = $value_to_equal;
177
-            $price_type_query_params[0]['Price.Ticket.Datetime.EVT_ID'] = $value_to_equal;
178
-            $term_query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $value_to_equal;
179
-            $state_country_query_params[0]['Venue.Event.EVT_ID'] = $value_to_equal;
180
-            $question_group_query_params[0]['Event.EVT_ID'] = $value_to_equal;
181
-            $question_query_params[0]['Question_Group.Event.EVT_ID'] = $value_to_equal;
182
-        } else {
183
-            $filename = 'all-events';
184
-        }
185
-
186
-
187
-        // array in the format:  table name =>  query where clause
188
-        $models_to_export = array(
189
-            'Event'                   => $event_query_params,
190
-            'Datetime'                => $related_models_query_params,
191
-            'Ticket_Template'         => $price_query_params,
192
-            'Ticket'                  => $datetime_ticket_query_params,
193
-            'Datetime_Ticket'         => $datetime_ticket_query_params,
194
-            'Price_Type'              => $price_type_query_params,
195
-            'Price'                   => $price_query_params,
196
-            'Ticket_Price'            => $price_query_params,
197
-            'Term'                    => $term_query_params,
198
-            'Term_Taxonomy'           => $related_models_query_params,
199
-            'Term_Relationship'       => $related_models_query_params, // model has NO primary key...
200
-            'Country'                 => $state_country_query_params,
201
-            'State'                   => $state_country_query_params,
202
-            'Venue'                   => $related_models_query_params,
203
-            'Event_Venue'             => $related_models_query_params,
204
-            'Question_Group'          => $question_group_query_params,
205
-            'Event_Question_Group'    => $question_group_query_params,
206
-            'Question'                => $question_query_params,
207
-            'Question_Group_Question' => $question_query_params,
208
-            // 'Transaction'=>$related_through_reg_query_params,
209
-            // 'Registration'=>$related_models_query_params,
210
-            // 'Attendee'=>$related_through_reg_query_params,
211
-            // 'Line_Item'=>
212
-
213
-        );
214
-
215
-        $model_data = $this->_get_export_data_for_models($models_to_export);
216
-
217
-        $filename = $this->generate_filename($filename);
218
-
219
-        if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $model_data)) {
220
-            EE_Error::add_error(
221
-                __(
222
-                    "'An error occurred and the Event details could not be exported from the database.'",
223
-                    "event_espresso"
224
-                ),
225
-                __FILE__,
226
-                __FUNCTION__,
227
-                __LINE__
228
-            );
229
-        }
230
-    }
231
-
232
-    public function report_attendees()
233
-    {
234
-        $attendee_rows = EEM_Attendee::instance()->get_all_wpdb_results(
235
-            array(
236
-                'force_join' => array('State', 'Country'),
237
-                'caps'       => EEM_Base::caps_read_admin,
238
-            )
239
-        );
240
-        $csv_data = array();
241
-        foreach ($attendee_rows as $attendee_row) {
242
-            $csv_row = array();
243
-            foreach (EEM_Attendee::instance()->field_settings() as $field_name => $field_obj) {
244
-                if ($field_name == 'STA_ID') {
245
-                    $state_name_field = EEM_State::instance()->field_settings_for('STA_name');
246
-                    $csv_row[ __('State', 'event_espresso') ] = $attendee_row[ $state_name_field->get_qualified_column(
247
-                    ) ];
248
-                } elseif ($field_name == 'CNT_ISO') {
249
-                    $country_name_field = EEM_Country::instance()->field_settings_for('CNT_name');
250
-                    $csv_row[ __(
251
-                        'Country',
252
-                        'event_espresso'
253
-                    ) ] = $attendee_row[ $country_name_field->get_qualified_column() ];
254
-                } else {
255
-                    $csv_row[ $field_obj->get_nicename() ] = $attendee_row[ $field_obj->get_qualified_column() ];
256
-                }
257
-            }
258
-            $csv_data[] = $csv_row;
259
-        }
260
-
261
-        $filename = $this->generate_filename('contact-list-report');
262
-
263
-        $handle = $this->EE_CSV->begin_sending_csv($filename);
264
-        $this->EE_CSV->write_data_array_to_csv($handle, $csv_data);
265
-        $this->EE_CSV->end_sending_csv($handle);
266
-    }
267
-
268
-
269
-    /**
270
-     * @Export data for ALL attendees
271
-     * @access public
272
-     * @return void
273
-     */
274
-    public function export_attendees()
275
-    {
276
-
277
-        $states_that_have_an_attendee = EEM_State::instance()->get_all(
278
-            array(0 => array('Attendee.ATT_ID' => array('IS NOT NULL')))
279
-        );
280
-        $countries_that_have_an_attendee = EEM_Country::instance()->get_all(
281
-            array(0 => array('Attendee.ATT_ID' => array('IS NOT NULL')))
282
-        );
283
-        // $states_to_export_query_params
284
-        $models_to_export = array(
285
-            'Country'  => array(array('CNT_ISO' => array('IN', array_keys($countries_that_have_an_attendee)))),
286
-            'State'    => array(array('STA_ID' => array('IN', array_keys($states_that_have_an_attendee)))),
287
-            'Attendee' => array(),
288
-        );
289
-
290
-
291
-        $model_data = $this->_get_export_data_for_models($models_to_export);
292
-        $filename = $this->generate_filename('all-attendees');
293
-
294
-        if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $model_data)) {
295
-            EE_Error::add_error(
296
-                __(
297
-                    'An error occurred and the Attendee data could not be exported from the database.',
298
-                    'event_espresso'
299
-                ),
300
-                __FILE__,
301
-                __FUNCTION__,
302
-                __LINE__
303
-            );
304
-        }
305
-    }
306
-
307
-    /**
308
-     * Shortcut for preparing a database result for display
309
-     *
310
-     * @param EEM_Base       $model
311
-     * @param string         $field_name
312
-     * @param string         $raw_db_value
313
-     * @param boolean|string $pretty_schema true to display pretty, a string to use a specific "Schema", or false to
314
-     *                                      NOT display pretty
315
-     * @return string
316
-     */
317
-    protected function _prepare_value_from_db_for_display($model, $field_name, $raw_db_value, $pretty_schema = true)
318
-    {
319
-        $field_obj = $model->field_settings_for($field_name);
320
-        $value_on_model_obj = $field_obj->prepare_for_set_from_db($raw_db_value);
321
-        if ($field_obj instanceof EE_Datetime_Field) {
322
-            $field_obj->set_date_format(
323
-                EE_CSV::instance()->get_date_format_for_csv($field_obj->get_date_format($pretty_schema)),
324
-                $pretty_schema
325
-            );
326
-            $field_obj->set_time_format(
327
-                EE_CSV::instance()->get_time_format_for_csv($field_obj->get_time_format($pretty_schema)),
328
-                $pretty_schema
329
-            );
330
-        }
331
-        if ($pretty_schema === true) {
332
-            return $field_obj->prepare_for_pretty_echoing($value_on_model_obj);
333
-        } elseif (is_string($pretty_schema)) {
334
-            return $field_obj->prepare_for_pretty_echoing($value_on_model_obj, $pretty_schema);
335
-        } else {
336
-            return $field_obj->prepare_for_get($value_on_model_obj);
337
-        }
338
-    }
339
-
340
-    /**
341
-     * Export a custom CSV of registration info including: A bunch of the reg fields, the time of the event, the price
342
-     * name, and the questions associated with the registrations
343
-     *
344
-     * @param int $event_id
345
-     */
346
-    public function report_registrations_for_event($event_id = null)
347
-    {
348
-        $reg_fields_to_include = array(
349
-            'TXN_ID',
350
-            'ATT_ID',
351
-            'REG_ID',
352
-            'REG_date',
353
-            'REG_code',
354
-            'REG_count',
355
-            'REG_final_price',
356
-
357
-        );
358
-        $att_fields_to_include = array(
359
-            'ATT_fname',
360
-            'ATT_lname',
361
-            'ATT_email',
362
-            'ATT_address',
363
-            'ATT_address2',
364
-            'ATT_city',
365
-            'STA_ID',
366
-            'CNT_ISO',
367
-            'ATT_zip',
368
-            'ATT_phone',
369
-        );
370
-
371
-        $registrations_csv_ready_array = array();
372
-        $reg_model = EE_Registry::instance()->load_model('Registration');
373
-        $query_params = apply_filters(
374
-            'FHEE__EE_Export__report_registration_for_event',
375
-            array(
376
-                array(
377
-                    'OR'                 => array(
378
-                        // don't include registrations from failed or abandoned transactions...
379
-                        'Transaction.STS_ID' => array(
380
-                            'NOT IN',
381
-                            array(EEM_Transaction::failed_status_code, EEM_Transaction::abandoned_status_code),
382
-                        ),
383
-                        // unless the registration is approved, in which case include it regardless of transaction status
384
-                        'STS_ID'             => EEM_Registration::status_id_approved,
385
-                    ),
386
-                    'Ticket.TKT_deleted' => array('IN', array(true, false)),
387
-                ),
388
-                'order_by'   => array('Transaction.TXN_ID' => 'asc', 'REG_count' => 'asc'),
389
-                'force_join' => array('Transaction', 'Ticket', 'Attendee'),
390
-                'caps'       => EEM_Base::caps_read_admin,
391
-            ),
392
-            $event_id
393
-        );
394
-        if ($event_id) {
395
-            $query_params[0]['EVT_ID'] = $event_id;
396
-        } else {
397
-            $query_params['force_join'][] = 'Event';
398
-        }
399
-        $registration_rows = $reg_model->get_all_wpdb_results($query_params);
400
-        // get all questions which relate to someone in this group
401
-        $registration_ids = array();
402
-        foreach ($registration_rows as $reg_row) {
403
-            $registration_ids[] = intval($reg_row['Registration.REG_ID']);
404
-        }
405
-        // EEM_Question::instance()->show_next_x_db_queries();
406
-        $questions_for_these_regs_rows = EEM_Question::instance()->get_all_wpdb_results(
407
-            array(array('Answer.REG_ID' => array('IN', $registration_ids)))
408
-        );
409
-        foreach ($registration_rows as $reg_row) {
410
-            if (is_array($reg_row)) {
411
-                $reg_csv_array = array();
412
-                if (! $event_id) {
413
-                    // get the event's name and Id
414
-                    $reg_csv_array[ __('Event', 'event_espresso') ] = sprintf(
415
-                        __('%1$s (%2$s)', 'event_espresso'),
416
-                        $this->_prepare_value_from_db_for_display(
417
-                            EEM_Event::instance(),
418
-                            'EVT_name',
419
-                            $reg_row['Event_CPT.post_title']
420
-                        ),
421
-                        $reg_row['Event_CPT.ID']
422
-                    );
423
-                }
424
-                $is_primary_reg = $reg_row['Registration.REG_count'] == '1' ? true : false;
425
-                /*@var $reg_row EE_Registration */
426
-                foreach ($reg_fields_to_include as $field_name) {
427
-                    $field = $reg_model->field_settings_for($field_name);
428
-                    if ($field_name == 'REG_final_price') {
429
-                        $value = $this->_prepare_value_from_db_for_display(
430
-                            $reg_model,
431
-                            $field_name,
432
-                            $reg_row['Registration.REG_final_price'],
433
-                            'localized_float'
434
-                        );
435
-                    } elseif ($field_name == 'REG_count') {
436
-                        $value = sprintf(
437
-                            __('%s of %s', 'event_espresso'),
438
-                            $this->_prepare_value_from_db_for_display(
439
-                                $reg_model,
440
-                                'REG_count',
441
-                                $reg_row['Registration.REG_count']
442
-                            ),
443
-                            $this->_prepare_value_from_db_for_display(
444
-                                $reg_model,
445
-                                'REG_group_size',
446
-                                $reg_row['Registration.REG_group_size']
447
-                            )
448
-                        );
449
-                    } elseif ($field_name == 'REG_date') {
450
-                        $value = $this->_prepare_value_from_db_for_display(
451
-                            $reg_model,
452
-                            $field_name,
453
-                            $reg_row['Registration.REG_date'],
454
-                            'no_html'
455
-                        );
456
-                    } else {
457
-                        $value = $this->_prepare_value_from_db_for_display(
458
-                            $reg_model,
459
-                            $field_name,
460
-                            $reg_row[ $field->get_qualified_column() ]
461
-                        );
462
-                    }
463
-                    $reg_csv_array[ $this->_get_column_name_for_field($field) ] = $value;
464
-                    if ($field_name == 'REG_final_price') {
465
-                        // add a column named Currency after the final price
466
-                        $reg_csv_array[ __("Currency", "event_espresso") ] = EE_Config::instance()->currency->code;
467
-                    }
468
-                }
469
-                // get pretty status
470
-                $stati = EEM_Status::instance()->localized_status(
471
-                    array(
472
-                        $reg_row['Registration.STS_ID']     => __('unknown', 'event_espresso'),
473
-                        $reg_row['TransactionTable.STS_ID'] => __('unknown', 'event_espresso'),
474
-                    ),
475
-                    false,
476
-                    'sentence'
477
-                );
478
-                $reg_csv_array[ __(
479
-                    "Registration Status",
480
-                    'event_espresso'
481
-                ) ] = $stati[ $reg_row['Registration.STS_ID'] ];
482
-                // get pretty trnasaction status
483
-                $reg_csv_array[ __(
484
-                    "Transaction Status",
485
-                    'event_espresso'
486
-                ) ] = $stati[ $reg_row['TransactionTable.STS_ID'] ];
487
-                $reg_csv_array[ __('Transaction Amount Due', 'event_espresso') ] = $is_primary_reg
488
-                    ? $this->_prepare_value_from_db_for_display(
489
-                        EEM_Transaction::instance(),
490
-                        'TXN_total',
491
-                        $reg_row['TransactionTable.TXN_total'],
492
-                        'localized_float'
493
-                    ) : '0.00';
494
-                $reg_csv_array[ __('Amount Paid', 'event_espresso') ] = $is_primary_reg
495
-                    ? $this->_prepare_value_from_db_for_display(
496
-                        EEM_Transaction::instance(),
497
-                        'TXN_paid',
498
-                        $reg_row['TransactionTable.TXN_paid'],
499
-                        'localized_float'
500
-                    ) : '0.00';
501
-                $payment_methods = array();
502
-                $gateway_txn_ids_etc = array();
503
-                $payment_times = array();
504
-                if ($is_primary_reg && $reg_row['TransactionTable.TXN_ID']) {
505
-                    $payments_info = EEM_Payment::instance()->get_all_wpdb_results(
506
-                        array(
507
-                            array(
508
-                                'TXN_ID' => $reg_row['TransactionTable.TXN_ID'],
509
-                                'STS_ID' => EEM_Payment::status_id_approved,
510
-                            ),
511
-                            'force_join' => array('Payment_Method'),
512
-                        ),
513
-                        ARRAY_A,
514
-                        'Payment_Method.PMD_admin_name as name, Payment.PAY_txn_id_chq_nmbr as gateway_txn_id, Payment.PAY_timestamp as payment_time'
515
-                    );
516
-
517
-                    foreach ($payments_info as $payment_method_and_gateway_txn_id) {
518
-                        $payment_methods[] = isset($payment_method_and_gateway_txn_id['name'])
519
-                            ? $payment_method_and_gateway_txn_id['name'] : __('Unknown', 'event_espresso');
520
-                        $gateway_txn_ids_etc[] = isset($payment_method_and_gateway_txn_id['gateway_txn_id'])
521
-                            ? $payment_method_and_gateway_txn_id['gateway_txn_id'] : '';
522
-                        $payment_times[] = isset($payment_method_and_gateway_txn_id['payment_time'])
523
-                            ? $payment_method_and_gateway_txn_id['payment_time'] : '';
524
-                    }
525
-                }
526
-                $reg_csv_array[ __('Payment Date(s)', 'event_espresso') ] = implode(',', $payment_times);
527
-                $reg_csv_array[ __('Payment Method(s)', 'event_espresso') ] = implode(",", $payment_methods);
528
-                $reg_csv_array[ __('Gateway Transaction ID(s)', 'event_espresso') ] = implode(
529
-                    ',',
530
-                    $gateway_txn_ids_etc
531
-                );
532
-
533
-                // get whether or not the user has checked in
534
-                $reg_csv_array[ __("Check-Ins", "event_espresso") ] = $reg_model->count_related(
535
-                    $reg_row['Registration.REG_ID'],
536
-                    'Checkin'
537
-                );
538
-                // get ticket of registration and its price
539
-                $ticket_model = EE_Registry::instance()->load_model('Ticket');
540
-                if ($reg_row['Ticket.TKT_ID']) {
541
-                    $ticket_name = $this->_prepare_value_from_db_for_display(
542
-                        $ticket_model,
543
-                        'TKT_name',
544
-                        $reg_row['Ticket.TKT_name']
545
-                    );
546
-                    $datetimes_strings = array();
547
-                    foreach (EEM_Datetime::instance()->get_all_wpdb_results(
548
-                        array(
549
-                            array('Ticket.TKT_ID' => $reg_row['Ticket.TKT_ID']),
550
-                            'order_by'                 => array('DTT_EVT_start' => 'ASC'),
551
-                            'default_where_conditions' => 'none',
552
-                        )
553
-                    ) as $datetime) {
554
-                        $datetimes_strings[] = $this->_prepare_value_from_db_for_display(
555
-                            EEM_Datetime::instance(),
556
-                            'DTT_EVT_start',
557
-                            $datetime['Datetime.DTT_EVT_start']
558
-                        );
559
-                    }
560
-                } else {
561
-                    $ticket_name = __('Unknown', 'event_espresso');
562
-                    $datetimes_strings = array(__('Unknown', 'event_espresso'));
563
-                }
564
-                $reg_csv_array[ $ticket_model->field_settings_for('TKT_name')->get_nicename() ] = $ticket_name;
565
-                $reg_csv_array[ __("Datetimes of Ticket", "event_espresso") ] = implode(", ", $datetimes_strings);
566
-                // get datetime(s) of registration
567
-
568
-                // add attendee columns
569
-                foreach ($att_fields_to_include as $att_field_name) {
570
-                    $field_obj = EEM_Attendee::instance()->field_settings_for($att_field_name);
571
-                    if ($reg_row['Attendee_CPT.ID']) {
572
-                        if ($att_field_name == 'STA_ID') {
573
-                            $value = EEM_State::instance()->get_var(
574
-                                array(array('STA_ID' => $reg_row['Attendee_Meta.STA_ID'])),
575
-                                'STA_name'
576
-                            );
577
-                        } elseif ($att_field_name == 'CNT_ISO') {
578
-                            $value = EEM_Country::instance()->get_var(
579
-                                array(array('CNT_ISO' => $reg_row['Attendee_Meta.CNT_ISO'])),
580
-                                'CNT_name'
581
-                            );
582
-                        } else {
583
-                            $value = $this->_prepare_value_from_db_for_display(
584
-                                EEM_Attendee::instance(),
585
-                                $att_field_name,
586
-                                $reg_row[ $field_obj->get_qualified_column() ]
587
-                            );
588
-                        }
589
-                    } else {
590
-                        $value = '';
591
-                    }
592
-
593
-                    $reg_csv_array[ $this->_get_column_name_for_field($field_obj) ] = $value;
594
-                }
595
-
596
-                // make sure each registration has the same questions in the same order
597
-                foreach ($questions_for_these_regs_rows as $question_row) {
598
-                    if (! isset($reg_csv_array[ $question_row['Question.QST_admin_label'] ])) {
599
-                        $reg_csv_array[ $question_row['Question.QST_admin_label'] ] = null;
600
-                    }
601
-                }
602
-                // now fill out the questions THEY answered
603
-                foreach (EEM_Answer::instance()->get_all_wpdb_results(
604
-                    array(array('REG_ID' => $reg_row['Registration.REG_ID']), 'force_join' => array('Question'))
605
-                ) as $answer_row) {
606
-                    /* @var $answer EE_Answer */
607
-                    if ($answer_row['Question.QST_ID']) {
608
-                        $question_label = $this->_prepare_value_from_db_for_display(
609
-                            EEM_Question::instance(),
610
-                            'QST_admin_label',
611
-                            $answer_row['Question.QST_admin_label']
612
-                        );
613
-                    } else {
614
-                        $question_label = sprintf(__('Question $s', 'event_espresso'), $answer_row['Answer.QST_ID']);
615
-                    }
616
-                    if (isset($answer_row['Question.QST_type']) && $answer_row['Question.QST_type'] == EEM_Question::QST_type_state) {
617
-                        $reg_csv_array[ $question_label ] = EEM_State::instance()->get_state_name_by_ID(
618
-                            $answer_row['Answer.ANS_value']
619
-                        );
620
-                    } else {
621
-                        $reg_csv_array[ $question_label ] = $this->_prepare_value_from_db_for_display(
622
-                            EEM_Answer::instance(),
623
-                            'ANS_value',
624
-                            $answer_row['Answer.ANS_value']
625
-                        );
626
-                    }
627
-                }
628
-                $registrations_csv_ready_array[] = apply_filters(
629
-                    'FHEE__EE_Export__report_registrations__reg_csv_array',
630
-                    $reg_csv_array,
631
-                    $reg_row
632
-                );
633
-            }
634
-        }
635
-
636
-        // if we couldn't export anything, we want to at least show the column headers
637
-        if (empty($registrations_csv_ready_array)) {
638
-            $reg_csv_array = array();
639
-            $model_and_fields_to_include = array(
640
-                'Registration' => $reg_fields_to_include,
641
-                'Attendee'     => $att_fields_to_include,
642
-            );
643
-            foreach ($model_and_fields_to_include as $model_name => $field_list) {
644
-                $model = EE_Registry::instance()->load_model($model_name);
645
-                foreach ($field_list as $field_name) {
646
-                    $field = $model->field_settings_for($field_name);
647
-                    $reg_csv_array[ $this->_get_column_name_for_field(
648
-                        $field
649
-                    ) ] = null;// $registration->get($field->get_name());
650
-                }
651
-            }
652
-            $registrations_csv_ready_array [] = $reg_csv_array;
653
-        }
654
-        if ($event_id) {
655
-            $event_slug = EEM_Event::instance()->get_var(array(array('EVT_ID' => $event_id)), 'EVT_slug');
656
-            if (! $event_slug) {
657
-                $event_slug = __('unknown', 'event_espresso');
658
-            }
659
-        } else {
660
-            $event_slug = __('all', 'event_espresso');
661
-        }
662
-        $filename = sprintf("registrations-for-%s", $event_slug);
663
-
664
-        $handle = $this->EE_CSV->begin_sending_csv($filename);
665
-        $this->EE_CSV->write_data_array_to_csv($handle, $registrations_csv_ready_array);
666
-        $this->EE_CSV->end_sending_csv($handle);
667
-    }
668
-
669
-    /**
670
-     * Gets the 'normal' column named for fields
671
-     *
672
-     * @param EE_Model_Field_Base $field
673
-     * @return string
674
-     */
675
-    protected function _get_column_name_for_field(EE_Model_Field_Base $field)
676
-    {
677
-        return $field->get_nicename() . "[" . $field->get_name() . "]";
678
-    }
679
-
680
-
681
-    /**
682
-     * @Export data for ALL events
683
-     * @access public
684
-     * @return void
685
-     */
686
-    public function export_categories()
687
-    {
688
-        // are any Event IDs set?
689
-        $query_params = array();
690
-        if (isset($this->_req_data['EVT_CAT_ID'])) {
691
-            // do we have an array of IDs ?
692
-            if (is_array($this->_req_data['EVT_CAT_ID'])) {
693
-                // generate an "IN (CSV)" where clause
694
-                $EVT_CAT_IDs = array_map('sanitize_text_field', $this->_req_data['EVT_CAT_ID']);
695
-                $filename = 'event-categories';
696
-                $query_params[0]['term_taxonomy_id'] = array('IN', $EVT_CAT_IDs);
697
-            } else {
698
-                // generate regular where = clause
699
-                $EVT_CAT_ID = absint($this->_req_data['EVT_CAT_ID']);
700
-                $filename = 'event-category#' . $EVT_CAT_ID;
701
-                $query_params[0]['term_taxonomy_id'] = $EVT_CAT_ID;
702
-            }
703
-        } else {
704
-            // no IDs means we will d/l the entire table
705
-            $filename = 'all-categories';
706
-        }
707
-
708
-        $tables_to_export = array(
709
-            'Term_Taxonomy' => $query_params,
710
-        );
711
-
712
-        $table_data = $this->_get_export_data_for_models($tables_to_export);
713
-        $filename = $this->generate_filename($filename);
714
-
715
-        if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $table_data)) {
716
-            EE_Error::add_error(
717
-                __(
718
-                    'An error occurred and the Category details could not be exported from the database.',
719
-                    'event_espresso'
720
-                ),
721
-                __FILE__,
722
-                __FUNCTION__,
723
-                __LINE__
724
-            );
725
-        }
726
-    }
727
-
728
-
729
-    /**
730
-     * @process export name to create a suitable filename
731
-     * @access  private
732
-     * @param string - export_name
733
-     * @return string on success, FALSE on fail
734
-     */
735
-    private function generate_filename($export_name = '')
736
-    {
737
-        if ($export_name != '') {
738
-            $filename = get_bloginfo('name') . '-' . $export_name;
739
-            $filename = sanitize_key($filename) . '-' . $this->today;
740
-            return $filename;
741
-        } else {
742
-            EE_Error::add_error(__("No filename was provided", "event_espresso"), __FILE__, __FUNCTION__, __LINE__);
743
-        }
744
-        return false;
745
-    }
746
-
747
-
748
-    /**
749
-     * @recursive function for exporting table data and merging the results with the next results
750
-     * @access    private
751
-     * @param array $models_to_export keys are model names (eg 'Event', 'Attendee', etc.) and values are arrays of
752
-     *                                query params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
753
-     * @return array on success, FALSE on fail
754
-     */
755
-    private function _get_export_data_for_models($models_to_export = array())
756
-    {
757
-        $table_data = false;
758
-        if (is_array($models_to_export)) {
759
-            foreach ($models_to_export as $model_name => $query_params) {
760
-                // check for a numerically-indexed array. in that case, $model_name is the value!!
761
-                if (is_int($model_name)) {
762
-                    $model_name = $query_params;
763
-                    $query_params = array();
764
-                }
765
-                $model = EE_Registry::instance()->load_model($model_name);
766
-                $model_objects = $model->get_all($query_params);
767
-
768
-                $table_data[ $model_name ] = array();
769
-                foreach ($model_objects as $model_object) {
770
-                    $model_data_array = array();
771
-                    $fields = $model->field_settings();
772
-                    foreach ($fields as $field) {
773
-                        $column_name = $field->get_nicename() . "[" . $field->get_name() . "]";
774
-                        if ($field instanceof EE_Datetime_Field) {
775
-                            // $field->set_date_format('Y-m-d');
776
-                            // $field->set_time_format('H:i:s');
777
-                            $model_data_array[ $column_name ] = $model_object->get_datetime(
778
-                                $field->get_name(),
779
-                                'Y-m-d',
780
-                                'H:i:s'
781
-                            );
782
-                        } else {
783
-                            $model_data_array[ $column_name ] = $model_object->get($field->get_name());
784
-                        }
785
-                    }
786
-                    $table_data[ $model_name ][] = $model_data_array;
787
-                }
788
-            }
789
-        }
790
-        return $table_data;
791
-    }
19
+	const option_prefix = 'ee_report_job_';
20
+
21
+
22
+	// instance of the EE_Export object
23
+	private static $_instance = null;
24
+
25
+	// instance of the EE_CSV object
26
+	/**
27
+	 *
28
+	 * @var EE_CSV
29
+	 */
30
+	public $EE_CSV = null;
31
+
32
+
33
+	private $_req_data = array();
34
+
35
+
36
+	/**
37
+	 *        private constructor to prevent direct creation
38
+	 *
39
+	 * @Constructor
40
+	 * @access private
41
+	 * @param array $request_data
42
+	 */
43
+	private function __construct($request_data = array())
44
+	{
45
+		$this->_req_data = $request_data;
46
+		$this->today = date("Y-m-d", time());
47
+		require_once(EE_CLASSES . 'EE_CSV.class.php');
48
+		$this->EE_CSV = EE_CSV::instance();
49
+	}
50
+
51
+
52
+	/**
53
+	 *        @ singleton method used to instantiate class object
54
+	 *        @ access public
55
+	 *
56
+	 * @param array $request_data
57
+	 * @return \EE_Export
58
+	 */
59
+	public static function instance($request_data = array())
60
+	{
61
+		// check if class object is instantiated
62
+		if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Export)) {
63
+			self::$_instance = new self($request_data);
64
+		}
65
+		return self::$_instance;
66
+	}
67
+
68
+
69
+	/**
70
+	 * @Export Event Espresso data - routes export requests
71
+	 * @access public
72
+	 * @return void | bool
73
+	 */
74
+	public function export()
75
+	{
76
+		// in case of bulk exports, the "actual" action will be in action2, but first check regular action for "export" keyword
77
+		if (isset($this->_req_data['action']) && strpos($this->_req_data['action'], 'export') === false) {
78
+			// check if action2 has export action
79
+			if (isset($this->_req_data['action2']) && strpos($this->_req_data['action2'], 'export') !== false) {
80
+				// whoop! there it is!
81
+				$this->_req_data['action'] = $this->_req_data['action2'];
82
+			}
83
+		}
84
+
85
+		$this->_req_data['export'] = isset($this->_req_data['export']) ? $this->_req_data['export'] : '';
86
+
87
+		switch ($this->_req_data['export']) {
88
+			case 'report':
89
+				switch ($this->_req_data['action']) {
90
+					case "event":
91
+					case "export_events":
92
+					case 'all_event_data':
93
+						$this->export_all_event_data();
94
+						break;
95
+
96
+					case 'registrations_report_for_event':
97
+						$this->report_registrations_for_event($this->_req_data['EVT_ID']);
98
+						break;
99
+
100
+					case 'attendees':
101
+						$this->export_attendees();
102
+						break;
103
+
104
+					case 'categories':
105
+						$this->export_categories();
106
+						break;
107
+
108
+					default:
109
+						EE_Error::add_error(
110
+							__('An error occurred! The requested export report could not be found.', 'event_espresso'),
111
+							__FILE__,
112
+							__FUNCTION__,
113
+							__LINE__
114
+						);
115
+						return false;
116
+						break;
117
+				}
118
+				break; // end of switch export : report
119
+			default:
120
+				break;
121
+		} // end of switch export
122
+
123
+		exit;
124
+	}
125
+
126
+	/**
127
+	 * Downloads a CSV file with all the columns, but no data. This should be used for importing
128
+	 *
129
+	 * @return null kills execution
130
+	 */
131
+	public function export_sample()
132
+	{
133
+		$event = EEM_Event::instance()->get_one();
134
+		$this->_req_data['EVT_ID'] = $event->ID();
135
+		$this->export_all_event_data();
136
+	}
137
+
138
+
139
+	/**
140
+	 * @Export data for ALL events
141
+	 * @access public
142
+	 * @return void
143
+	 */
144
+	public function export_all_event_data()
145
+	{
146
+		// are any Event IDs set?
147
+		$event_query_params = array();
148
+		$related_models_query_params = array();
149
+		$related_through_reg_query_params = array();
150
+		$datetime_ticket_query_params = array();
151
+		$price_query_params = array();
152
+		$price_type_query_params = array();
153
+		$term_query_params = array();
154
+		$state_country_query_params = array();
155
+		$question_group_query_params = array();
156
+		$question_query_params = array();
157
+		if (isset($this->_req_data['EVT_ID'])) {
158
+			// do we have an array of IDs ?
159
+
160
+			if (is_array($this->_req_data['EVT_ID'])) {
161
+				$EVT_IDs = array_map('sanitize_text_field', $this->_req_data['EVT_ID']);
162
+				$value_to_equal = array('IN', $EVT_IDs);
163
+				$filename = 'events';
164
+			} else {
165
+				// generate regular where = clause
166
+				$EVT_ID = absint($this->_req_data['EVT_ID']);
167
+				$value_to_equal = $EVT_ID;
168
+				$event = EE_Registry::instance()->load_model('Event')->get_one_by_ID($EVT_ID);
169
+
170
+				$filename = 'event-' . ($event instanceof EE_Event ? $event->slug() : __('unknown', 'event_espresso'));
171
+			}
172
+			$event_query_params[0]['EVT_ID'] = $value_to_equal;
173
+			$related_models_query_params[0]['Event.EVT_ID'] = $value_to_equal;
174
+			$related_through_reg_query_params[0]['Registration.EVT_ID'] = $value_to_equal;
175
+			$datetime_ticket_query_params[0]['Datetime.EVT_ID'] = $value_to_equal;
176
+			$price_query_params[0]['Ticket.Datetime.EVT_ID'] = $value_to_equal;
177
+			$price_type_query_params[0]['Price.Ticket.Datetime.EVT_ID'] = $value_to_equal;
178
+			$term_query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $value_to_equal;
179
+			$state_country_query_params[0]['Venue.Event.EVT_ID'] = $value_to_equal;
180
+			$question_group_query_params[0]['Event.EVT_ID'] = $value_to_equal;
181
+			$question_query_params[0]['Question_Group.Event.EVT_ID'] = $value_to_equal;
182
+		} else {
183
+			$filename = 'all-events';
184
+		}
185
+
186
+
187
+		// array in the format:  table name =>  query where clause
188
+		$models_to_export = array(
189
+			'Event'                   => $event_query_params,
190
+			'Datetime'                => $related_models_query_params,
191
+			'Ticket_Template'         => $price_query_params,
192
+			'Ticket'                  => $datetime_ticket_query_params,
193
+			'Datetime_Ticket'         => $datetime_ticket_query_params,
194
+			'Price_Type'              => $price_type_query_params,
195
+			'Price'                   => $price_query_params,
196
+			'Ticket_Price'            => $price_query_params,
197
+			'Term'                    => $term_query_params,
198
+			'Term_Taxonomy'           => $related_models_query_params,
199
+			'Term_Relationship'       => $related_models_query_params, // model has NO primary key...
200
+			'Country'                 => $state_country_query_params,
201
+			'State'                   => $state_country_query_params,
202
+			'Venue'                   => $related_models_query_params,
203
+			'Event_Venue'             => $related_models_query_params,
204
+			'Question_Group'          => $question_group_query_params,
205
+			'Event_Question_Group'    => $question_group_query_params,
206
+			'Question'                => $question_query_params,
207
+			'Question_Group_Question' => $question_query_params,
208
+			// 'Transaction'=>$related_through_reg_query_params,
209
+			// 'Registration'=>$related_models_query_params,
210
+			// 'Attendee'=>$related_through_reg_query_params,
211
+			// 'Line_Item'=>
212
+
213
+		);
214
+
215
+		$model_data = $this->_get_export_data_for_models($models_to_export);
216
+
217
+		$filename = $this->generate_filename($filename);
218
+
219
+		if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $model_data)) {
220
+			EE_Error::add_error(
221
+				__(
222
+					"'An error occurred and the Event details could not be exported from the database.'",
223
+					"event_espresso"
224
+				),
225
+				__FILE__,
226
+				__FUNCTION__,
227
+				__LINE__
228
+			);
229
+		}
230
+	}
231
+
232
+	public function report_attendees()
233
+	{
234
+		$attendee_rows = EEM_Attendee::instance()->get_all_wpdb_results(
235
+			array(
236
+				'force_join' => array('State', 'Country'),
237
+				'caps'       => EEM_Base::caps_read_admin,
238
+			)
239
+		);
240
+		$csv_data = array();
241
+		foreach ($attendee_rows as $attendee_row) {
242
+			$csv_row = array();
243
+			foreach (EEM_Attendee::instance()->field_settings() as $field_name => $field_obj) {
244
+				if ($field_name == 'STA_ID') {
245
+					$state_name_field = EEM_State::instance()->field_settings_for('STA_name');
246
+					$csv_row[ __('State', 'event_espresso') ] = $attendee_row[ $state_name_field->get_qualified_column(
247
+					) ];
248
+				} elseif ($field_name == 'CNT_ISO') {
249
+					$country_name_field = EEM_Country::instance()->field_settings_for('CNT_name');
250
+					$csv_row[ __(
251
+						'Country',
252
+						'event_espresso'
253
+					) ] = $attendee_row[ $country_name_field->get_qualified_column() ];
254
+				} else {
255
+					$csv_row[ $field_obj->get_nicename() ] = $attendee_row[ $field_obj->get_qualified_column() ];
256
+				}
257
+			}
258
+			$csv_data[] = $csv_row;
259
+		}
260
+
261
+		$filename = $this->generate_filename('contact-list-report');
262
+
263
+		$handle = $this->EE_CSV->begin_sending_csv($filename);
264
+		$this->EE_CSV->write_data_array_to_csv($handle, $csv_data);
265
+		$this->EE_CSV->end_sending_csv($handle);
266
+	}
267
+
268
+
269
+	/**
270
+	 * @Export data for ALL attendees
271
+	 * @access public
272
+	 * @return void
273
+	 */
274
+	public function export_attendees()
275
+	{
276
+
277
+		$states_that_have_an_attendee = EEM_State::instance()->get_all(
278
+			array(0 => array('Attendee.ATT_ID' => array('IS NOT NULL')))
279
+		);
280
+		$countries_that_have_an_attendee = EEM_Country::instance()->get_all(
281
+			array(0 => array('Attendee.ATT_ID' => array('IS NOT NULL')))
282
+		);
283
+		// $states_to_export_query_params
284
+		$models_to_export = array(
285
+			'Country'  => array(array('CNT_ISO' => array('IN', array_keys($countries_that_have_an_attendee)))),
286
+			'State'    => array(array('STA_ID' => array('IN', array_keys($states_that_have_an_attendee)))),
287
+			'Attendee' => array(),
288
+		);
289
+
290
+
291
+		$model_data = $this->_get_export_data_for_models($models_to_export);
292
+		$filename = $this->generate_filename('all-attendees');
293
+
294
+		if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $model_data)) {
295
+			EE_Error::add_error(
296
+				__(
297
+					'An error occurred and the Attendee data could not be exported from the database.',
298
+					'event_espresso'
299
+				),
300
+				__FILE__,
301
+				__FUNCTION__,
302
+				__LINE__
303
+			);
304
+		}
305
+	}
306
+
307
+	/**
308
+	 * Shortcut for preparing a database result for display
309
+	 *
310
+	 * @param EEM_Base       $model
311
+	 * @param string         $field_name
312
+	 * @param string         $raw_db_value
313
+	 * @param boolean|string $pretty_schema true to display pretty, a string to use a specific "Schema", or false to
314
+	 *                                      NOT display pretty
315
+	 * @return string
316
+	 */
317
+	protected function _prepare_value_from_db_for_display($model, $field_name, $raw_db_value, $pretty_schema = true)
318
+	{
319
+		$field_obj = $model->field_settings_for($field_name);
320
+		$value_on_model_obj = $field_obj->prepare_for_set_from_db($raw_db_value);
321
+		if ($field_obj instanceof EE_Datetime_Field) {
322
+			$field_obj->set_date_format(
323
+				EE_CSV::instance()->get_date_format_for_csv($field_obj->get_date_format($pretty_schema)),
324
+				$pretty_schema
325
+			);
326
+			$field_obj->set_time_format(
327
+				EE_CSV::instance()->get_time_format_for_csv($field_obj->get_time_format($pretty_schema)),
328
+				$pretty_schema
329
+			);
330
+		}
331
+		if ($pretty_schema === true) {
332
+			return $field_obj->prepare_for_pretty_echoing($value_on_model_obj);
333
+		} elseif (is_string($pretty_schema)) {
334
+			return $field_obj->prepare_for_pretty_echoing($value_on_model_obj, $pretty_schema);
335
+		} else {
336
+			return $field_obj->prepare_for_get($value_on_model_obj);
337
+		}
338
+	}
339
+
340
+	/**
341
+	 * Export a custom CSV of registration info including: A bunch of the reg fields, the time of the event, the price
342
+	 * name, and the questions associated with the registrations
343
+	 *
344
+	 * @param int $event_id
345
+	 */
346
+	public function report_registrations_for_event($event_id = null)
347
+	{
348
+		$reg_fields_to_include = array(
349
+			'TXN_ID',
350
+			'ATT_ID',
351
+			'REG_ID',
352
+			'REG_date',
353
+			'REG_code',
354
+			'REG_count',
355
+			'REG_final_price',
356
+
357
+		);
358
+		$att_fields_to_include = array(
359
+			'ATT_fname',
360
+			'ATT_lname',
361
+			'ATT_email',
362
+			'ATT_address',
363
+			'ATT_address2',
364
+			'ATT_city',
365
+			'STA_ID',
366
+			'CNT_ISO',
367
+			'ATT_zip',
368
+			'ATT_phone',
369
+		);
370
+
371
+		$registrations_csv_ready_array = array();
372
+		$reg_model = EE_Registry::instance()->load_model('Registration');
373
+		$query_params = apply_filters(
374
+			'FHEE__EE_Export__report_registration_for_event',
375
+			array(
376
+				array(
377
+					'OR'                 => array(
378
+						// don't include registrations from failed or abandoned transactions...
379
+						'Transaction.STS_ID' => array(
380
+							'NOT IN',
381
+							array(EEM_Transaction::failed_status_code, EEM_Transaction::abandoned_status_code),
382
+						),
383
+						// unless the registration is approved, in which case include it regardless of transaction status
384
+						'STS_ID'             => EEM_Registration::status_id_approved,
385
+					),
386
+					'Ticket.TKT_deleted' => array('IN', array(true, false)),
387
+				),
388
+				'order_by'   => array('Transaction.TXN_ID' => 'asc', 'REG_count' => 'asc'),
389
+				'force_join' => array('Transaction', 'Ticket', 'Attendee'),
390
+				'caps'       => EEM_Base::caps_read_admin,
391
+			),
392
+			$event_id
393
+		);
394
+		if ($event_id) {
395
+			$query_params[0]['EVT_ID'] = $event_id;
396
+		} else {
397
+			$query_params['force_join'][] = 'Event';
398
+		}
399
+		$registration_rows = $reg_model->get_all_wpdb_results($query_params);
400
+		// get all questions which relate to someone in this group
401
+		$registration_ids = array();
402
+		foreach ($registration_rows as $reg_row) {
403
+			$registration_ids[] = intval($reg_row['Registration.REG_ID']);
404
+		}
405
+		// EEM_Question::instance()->show_next_x_db_queries();
406
+		$questions_for_these_regs_rows = EEM_Question::instance()->get_all_wpdb_results(
407
+			array(array('Answer.REG_ID' => array('IN', $registration_ids)))
408
+		);
409
+		foreach ($registration_rows as $reg_row) {
410
+			if (is_array($reg_row)) {
411
+				$reg_csv_array = array();
412
+				if (! $event_id) {
413
+					// get the event's name and Id
414
+					$reg_csv_array[ __('Event', 'event_espresso') ] = sprintf(
415
+						__('%1$s (%2$s)', 'event_espresso'),
416
+						$this->_prepare_value_from_db_for_display(
417
+							EEM_Event::instance(),
418
+							'EVT_name',
419
+							$reg_row['Event_CPT.post_title']
420
+						),
421
+						$reg_row['Event_CPT.ID']
422
+					);
423
+				}
424
+				$is_primary_reg = $reg_row['Registration.REG_count'] == '1' ? true : false;
425
+				/*@var $reg_row EE_Registration */
426
+				foreach ($reg_fields_to_include as $field_name) {
427
+					$field = $reg_model->field_settings_for($field_name);
428
+					if ($field_name == 'REG_final_price') {
429
+						$value = $this->_prepare_value_from_db_for_display(
430
+							$reg_model,
431
+							$field_name,
432
+							$reg_row['Registration.REG_final_price'],
433
+							'localized_float'
434
+						);
435
+					} elseif ($field_name == 'REG_count') {
436
+						$value = sprintf(
437
+							__('%s of %s', 'event_espresso'),
438
+							$this->_prepare_value_from_db_for_display(
439
+								$reg_model,
440
+								'REG_count',
441
+								$reg_row['Registration.REG_count']
442
+							),
443
+							$this->_prepare_value_from_db_for_display(
444
+								$reg_model,
445
+								'REG_group_size',
446
+								$reg_row['Registration.REG_group_size']
447
+							)
448
+						);
449
+					} elseif ($field_name == 'REG_date') {
450
+						$value = $this->_prepare_value_from_db_for_display(
451
+							$reg_model,
452
+							$field_name,
453
+							$reg_row['Registration.REG_date'],
454
+							'no_html'
455
+						);
456
+					} else {
457
+						$value = $this->_prepare_value_from_db_for_display(
458
+							$reg_model,
459
+							$field_name,
460
+							$reg_row[ $field->get_qualified_column() ]
461
+						);
462
+					}
463
+					$reg_csv_array[ $this->_get_column_name_for_field($field) ] = $value;
464
+					if ($field_name == 'REG_final_price') {
465
+						// add a column named Currency after the final price
466
+						$reg_csv_array[ __("Currency", "event_espresso") ] = EE_Config::instance()->currency->code;
467
+					}
468
+				}
469
+				// get pretty status
470
+				$stati = EEM_Status::instance()->localized_status(
471
+					array(
472
+						$reg_row['Registration.STS_ID']     => __('unknown', 'event_espresso'),
473
+						$reg_row['TransactionTable.STS_ID'] => __('unknown', 'event_espresso'),
474
+					),
475
+					false,
476
+					'sentence'
477
+				);
478
+				$reg_csv_array[ __(
479
+					"Registration Status",
480
+					'event_espresso'
481
+				) ] = $stati[ $reg_row['Registration.STS_ID'] ];
482
+				// get pretty trnasaction status
483
+				$reg_csv_array[ __(
484
+					"Transaction Status",
485
+					'event_espresso'
486
+				) ] = $stati[ $reg_row['TransactionTable.STS_ID'] ];
487
+				$reg_csv_array[ __('Transaction Amount Due', 'event_espresso') ] = $is_primary_reg
488
+					? $this->_prepare_value_from_db_for_display(
489
+						EEM_Transaction::instance(),
490
+						'TXN_total',
491
+						$reg_row['TransactionTable.TXN_total'],
492
+						'localized_float'
493
+					) : '0.00';
494
+				$reg_csv_array[ __('Amount Paid', 'event_espresso') ] = $is_primary_reg
495
+					? $this->_prepare_value_from_db_for_display(
496
+						EEM_Transaction::instance(),
497
+						'TXN_paid',
498
+						$reg_row['TransactionTable.TXN_paid'],
499
+						'localized_float'
500
+					) : '0.00';
501
+				$payment_methods = array();
502
+				$gateway_txn_ids_etc = array();
503
+				$payment_times = array();
504
+				if ($is_primary_reg && $reg_row['TransactionTable.TXN_ID']) {
505
+					$payments_info = EEM_Payment::instance()->get_all_wpdb_results(
506
+						array(
507
+							array(
508
+								'TXN_ID' => $reg_row['TransactionTable.TXN_ID'],
509
+								'STS_ID' => EEM_Payment::status_id_approved,
510
+							),
511
+							'force_join' => array('Payment_Method'),
512
+						),
513
+						ARRAY_A,
514
+						'Payment_Method.PMD_admin_name as name, Payment.PAY_txn_id_chq_nmbr as gateway_txn_id, Payment.PAY_timestamp as payment_time'
515
+					);
516
+
517
+					foreach ($payments_info as $payment_method_and_gateway_txn_id) {
518
+						$payment_methods[] = isset($payment_method_and_gateway_txn_id['name'])
519
+							? $payment_method_and_gateway_txn_id['name'] : __('Unknown', 'event_espresso');
520
+						$gateway_txn_ids_etc[] = isset($payment_method_and_gateway_txn_id['gateway_txn_id'])
521
+							? $payment_method_and_gateway_txn_id['gateway_txn_id'] : '';
522
+						$payment_times[] = isset($payment_method_and_gateway_txn_id['payment_time'])
523
+							? $payment_method_and_gateway_txn_id['payment_time'] : '';
524
+					}
525
+				}
526
+				$reg_csv_array[ __('Payment Date(s)', 'event_espresso') ] = implode(',', $payment_times);
527
+				$reg_csv_array[ __('Payment Method(s)', 'event_espresso') ] = implode(",", $payment_methods);
528
+				$reg_csv_array[ __('Gateway Transaction ID(s)', 'event_espresso') ] = implode(
529
+					',',
530
+					$gateway_txn_ids_etc
531
+				);
532
+
533
+				// get whether or not the user has checked in
534
+				$reg_csv_array[ __("Check-Ins", "event_espresso") ] = $reg_model->count_related(
535
+					$reg_row['Registration.REG_ID'],
536
+					'Checkin'
537
+				);
538
+				// get ticket of registration and its price
539
+				$ticket_model = EE_Registry::instance()->load_model('Ticket');
540
+				if ($reg_row['Ticket.TKT_ID']) {
541
+					$ticket_name = $this->_prepare_value_from_db_for_display(
542
+						$ticket_model,
543
+						'TKT_name',
544
+						$reg_row['Ticket.TKT_name']
545
+					);
546
+					$datetimes_strings = array();
547
+					foreach (EEM_Datetime::instance()->get_all_wpdb_results(
548
+						array(
549
+							array('Ticket.TKT_ID' => $reg_row['Ticket.TKT_ID']),
550
+							'order_by'                 => array('DTT_EVT_start' => 'ASC'),
551
+							'default_where_conditions' => 'none',
552
+						)
553
+					) as $datetime) {
554
+						$datetimes_strings[] = $this->_prepare_value_from_db_for_display(
555
+							EEM_Datetime::instance(),
556
+							'DTT_EVT_start',
557
+							$datetime['Datetime.DTT_EVT_start']
558
+						);
559
+					}
560
+				} else {
561
+					$ticket_name = __('Unknown', 'event_espresso');
562
+					$datetimes_strings = array(__('Unknown', 'event_espresso'));
563
+				}
564
+				$reg_csv_array[ $ticket_model->field_settings_for('TKT_name')->get_nicename() ] = $ticket_name;
565
+				$reg_csv_array[ __("Datetimes of Ticket", "event_espresso") ] = implode(", ", $datetimes_strings);
566
+				// get datetime(s) of registration
567
+
568
+				// add attendee columns
569
+				foreach ($att_fields_to_include as $att_field_name) {
570
+					$field_obj = EEM_Attendee::instance()->field_settings_for($att_field_name);
571
+					if ($reg_row['Attendee_CPT.ID']) {
572
+						if ($att_field_name == 'STA_ID') {
573
+							$value = EEM_State::instance()->get_var(
574
+								array(array('STA_ID' => $reg_row['Attendee_Meta.STA_ID'])),
575
+								'STA_name'
576
+							);
577
+						} elseif ($att_field_name == 'CNT_ISO') {
578
+							$value = EEM_Country::instance()->get_var(
579
+								array(array('CNT_ISO' => $reg_row['Attendee_Meta.CNT_ISO'])),
580
+								'CNT_name'
581
+							);
582
+						} else {
583
+							$value = $this->_prepare_value_from_db_for_display(
584
+								EEM_Attendee::instance(),
585
+								$att_field_name,
586
+								$reg_row[ $field_obj->get_qualified_column() ]
587
+							);
588
+						}
589
+					} else {
590
+						$value = '';
591
+					}
592
+
593
+					$reg_csv_array[ $this->_get_column_name_for_field($field_obj) ] = $value;
594
+				}
595
+
596
+				// make sure each registration has the same questions in the same order
597
+				foreach ($questions_for_these_regs_rows as $question_row) {
598
+					if (! isset($reg_csv_array[ $question_row['Question.QST_admin_label'] ])) {
599
+						$reg_csv_array[ $question_row['Question.QST_admin_label'] ] = null;
600
+					}
601
+				}
602
+				// now fill out the questions THEY answered
603
+				foreach (EEM_Answer::instance()->get_all_wpdb_results(
604
+					array(array('REG_ID' => $reg_row['Registration.REG_ID']), 'force_join' => array('Question'))
605
+				) as $answer_row) {
606
+					/* @var $answer EE_Answer */
607
+					if ($answer_row['Question.QST_ID']) {
608
+						$question_label = $this->_prepare_value_from_db_for_display(
609
+							EEM_Question::instance(),
610
+							'QST_admin_label',
611
+							$answer_row['Question.QST_admin_label']
612
+						);
613
+					} else {
614
+						$question_label = sprintf(__('Question $s', 'event_espresso'), $answer_row['Answer.QST_ID']);
615
+					}
616
+					if (isset($answer_row['Question.QST_type']) && $answer_row['Question.QST_type'] == EEM_Question::QST_type_state) {
617
+						$reg_csv_array[ $question_label ] = EEM_State::instance()->get_state_name_by_ID(
618
+							$answer_row['Answer.ANS_value']
619
+						);
620
+					} else {
621
+						$reg_csv_array[ $question_label ] = $this->_prepare_value_from_db_for_display(
622
+							EEM_Answer::instance(),
623
+							'ANS_value',
624
+							$answer_row['Answer.ANS_value']
625
+						);
626
+					}
627
+				}
628
+				$registrations_csv_ready_array[] = apply_filters(
629
+					'FHEE__EE_Export__report_registrations__reg_csv_array',
630
+					$reg_csv_array,
631
+					$reg_row
632
+				);
633
+			}
634
+		}
635
+
636
+		// if we couldn't export anything, we want to at least show the column headers
637
+		if (empty($registrations_csv_ready_array)) {
638
+			$reg_csv_array = array();
639
+			$model_and_fields_to_include = array(
640
+				'Registration' => $reg_fields_to_include,
641
+				'Attendee'     => $att_fields_to_include,
642
+			);
643
+			foreach ($model_and_fields_to_include as $model_name => $field_list) {
644
+				$model = EE_Registry::instance()->load_model($model_name);
645
+				foreach ($field_list as $field_name) {
646
+					$field = $model->field_settings_for($field_name);
647
+					$reg_csv_array[ $this->_get_column_name_for_field(
648
+						$field
649
+					) ] = null;// $registration->get($field->get_name());
650
+				}
651
+			}
652
+			$registrations_csv_ready_array [] = $reg_csv_array;
653
+		}
654
+		if ($event_id) {
655
+			$event_slug = EEM_Event::instance()->get_var(array(array('EVT_ID' => $event_id)), 'EVT_slug');
656
+			if (! $event_slug) {
657
+				$event_slug = __('unknown', 'event_espresso');
658
+			}
659
+		} else {
660
+			$event_slug = __('all', 'event_espresso');
661
+		}
662
+		$filename = sprintf("registrations-for-%s", $event_slug);
663
+
664
+		$handle = $this->EE_CSV->begin_sending_csv($filename);
665
+		$this->EE_CSV->write_data_array_to_csv($handle, $registrations_csv_ready_array);
666
+		$this->EE_CSV->end_sending_csv($handle);
667
+	}
668
+
669
+	/**
670
+	 * Gets the 'normal' column named for fields
671
+	 *
672
+	 * @param EE_Model_Field_Base $field
673
+	 * @return string
674
+	 */
675
+	protected function _get_column_name_for_field(EE_Model_Field_Base $field)
676
+	{
677
+		return $field->get_nicename() . "[" . $field->get_name() . "]";
678
+	}
679
+
680
+
681
+	/**
682
+	 * @Export data for ALL events
683
+	 * @access public
684
+	 * @return void
685
+	 */
686
+	public function export_categories()
687
+	{
688
+		// are any Event IDs set?
689
+		$query_params = array();
690
+		if (isset($this->_req_data['EVT_CAT_ID'])) {
691
+			// do we have an array of IDs ?
692
+			if (is_array($this->_req_data['EVT_CAT_ID'])) {
693
+				// generate an "IN (CSV)" where clause
694
+				$EVT_CAT_IDs = array_map('sanitize_text_field', $this->_req_data['EVT_CAT_ID']);
695
+				$filename = 'event-categories';
696
+				$query_params[0]['term_taxonomy_id'] = array('IN', $EVT_CAT_IDs);
697
+			} else {
698
+				// generate regular where = clause
699
+				$EVT_CAT_ID = absint($this->_req_data['EVT_CAT_ID']);
700
+				$filename = 'event-category#' . $EVT_CAT_ID;
701
+				$query_params[0]['term_taxonomy_id'] = $EVT_CAT_ID;
702
+			}
703
+		} else {
704
+			// no IDs means we will d/l the entire table
705
+			$filename = 'all-categories';
706
+		}
707
+
708
+		$tables_to_export = array(
709
+			'Term_Taxonomy' => $query_params,
710
+		);
711
+
712
+		$table_data = $this->_get_export_data_for_models($tables_to_export);
713
+		$filename = $this->generate_filename($filename);
714
+
715
+		if (! $this->EE_CSV->export_multiple_model_data_to_csv($filename, $table_data)) {
716
+			EE_Error::add_error(
717
+				__(
718
+					'An error occurred and the Category details could not be exported from the database.',
719
+					'event_espresso'
720
+				),
721
+				__FILE__,
722
+				__FUNCTION__,
723
+				__LINE__
724
+			);
725
+		}
726
+	}
727
+
728
+
729
+	/**
730
+	 * @process export name to create a suitable filename
731
+	 * @access  private
732
+	 * @param string - export_name
733
+	 * @return string on success, FALSE on fail
734
+	 */
735
+	private function generate_filename($export_name = '')
736
+	{
737
+		if ($export_name != '') {
738
+			$filename = get_bloginfo('name') . '-' . $export_name;
739
+			$filename = sanitize_key($filename) . '-' . $this->today;
740
+			return $filename;
741
+		} else {
742
+			EE_Error::add_error(__("No filename was provided", "event_espresso"), __FILE__, __FUNCTION__, __LINE__);
743
+		}
744
+		return false;
745
+	}
746
+
747
+
748
+	/**
749
+	 * @recursive function for exporting table data and merging the results with the next results
750
+	 * @access    private
751
+	 * @param array $models_to_export keys are model names (eg 'Event', 'Attendee', etc.) and values are arrays of
752
+	 *                                query params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
753
+	 * @return array on success, FALSE on fail
754
+	 */
755
+	private function _get_export_data_for_models($models_to_export = array())
756
+	{
757
+		$table_data = false;
758
+		if (is_array($models_to_export)) {
759
+			foreach ($models_to_export as $model_name => $query_params) {
760
+				// check for a numerically-indexed array. in that case, $model_name is the value!!
761
+				if (is_int($model_name)) {
762
+					$model_name = $query_params;
763
+					$query_params = array();
764
+				}
765
+				$model = EE_Registry::instance()->load_model($model_name);
766
+				$model_objects = $model->get_all($query_params);
767
+
768
+				$table_data[ $model_name ] = array();
769
+				foreach ($model_objects as $model_object) {
770
+					$model_data_array = array();
771
+					$fields = $model->field_settings();
772
+					foreach ($fields as $field) {
773
+						$column_name = $field->get_nicename() . "[" . $field->get_name() . "]";
774
+						if ($field instanceof EE_Datetime_Field) {
775
+							// $field->set_date_format('Y-m-d');
776
+							// $field->set_time_format('H:i:s');
777
+							$model_data_array[ $column_name ] = $model_object->get_datetime(
778
+								$field->get_name(),
779
+								'Y-m-d',
780
+								'H:i:s'
781
+							);
782
+						} else {
783
+							$model_data_array[ $column_name ] = $model_object->get($field->get_name());
784
+						}
785
+					}
786
+					$table_data[ $model_name ][] = $model_data_array;
787
+				}
788
+			}
789
+		}
790
+		return $table_data;
791
+	}
792 792
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Answer.class.php 1 patch
Indentation   +138 added lines, -138 removed lines patch added patch discarded remove patch
@@ -10,144 +10,144 @@
 block discarded – undo
10 10
 class EE_Answer extends EE_Base_Class
11 11
 {
12 12
 
13
-    /**
14
-     *
15
-     * @param array $props_n_values
16
-     * @return EE_Answer
17
-     */
18
-    public static function new_instance($props_n_values = array())
19
-    {
20
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
21
-        return $has_object ? $has_object : new self($props_n_values);
22
-    }
23
-
24
-
25
-    /**
26
-     *
27
-     * @param array $props_n_values
28
-     * @return EE_Answer
29
-     */
30
-    public static function new_instance_from_db($props_n_values = array())
31
-    {
32
-        return new self($props_n_values, true);
33
-    }
34
-
35
-
36
-    /**
37
-     *    Set Question ID
38
-     *
39
-     * @access        public
40
-     * @param int $QST_ID
41
-     */
42
-    public function set_question($QST_ID = 0)
43
-    {
44
-        $this->set('QST_ID', $QST_ID);
45
-    }
46
-
47
-
48
-    /**
49
-     *    Set Registration ID
50
-     *
51
-     * @access        public
52
-     * @param int $REG_ID
53
-     */
54
-    public function set_registration($REG_ID = 0)
55
-    {
56
-        $this->set('REG_ID', $REG_ID);
57
-    }
58
-
59
-
60
-    /**
61
-     *    Set Answer value
62
-     *
63
-     * @access        public
64
-     * @param mixed $ANS_value
65
-     */
66
-    public function set_value($ANS_value = '')
67
-    {
68
-        $this->set('ANS_value', $ANS_value);
69
-    }
70
-
71
-
72
-    /**
73
-     *    get Attendee First Name
74
-     *
75
-     * @access        public
76
-     * @return        int
77
-     */
78
-    public function registration_ID()
79
-    {
80
-        return $this->get('REG_ID');
81
-    }
82
-
83
-
84
-    /**
85
-     *    get Attendee Last Name
86
-     *
87
-     * @access        public
88
-     * @return        int
89
-     */
90
-    public function question_ID()
91
-    {
92
-        return $this->get('QST_ID');
93
-    }
94
-
95
-
96
-    /**
97
-     *    get Attendee Address
98
-     *
99
-     * @access        public
100
-     * @return        string
101
-     */
102
-    public function value()
103
-    {
104
-        return $this->get('ANS_value');
105
-    }
106
-
107
-
108
-    /**
109
-     * Gets a pretty form of the value (mostly applies to answers that have multiple answers)
110
-     *
111
-     * @param null $schema
112
-     * @return string
113
-     */
114
-    public function pretty_value($schema = null)
115
-    {
116
-        return $this->get_pretty('ANS_value', $schema);
117
-    }
118
-
119
-
120
-    /**
121
-     * Echoes out a pretty value (even for multi-choice options)
122
-     *
123
-     * @param string $schema
124
-     */
125
-    public function e_value($schema = null)
126
-    {
127
-        $this->e('ANS_value', $schema);
128
-    }
129
-
130
-
131
-    /**
132
-     * Gets the related EE_Question to this EE_Answer
133
-     *
134
-     * @return EE_Question
135
-     */
136
-    public function question()
137
-    {
138
-        return $this->get_first_related('Question');
139
-    }
140
-
141
-
142
-    /**
143
-     * Gets the related EE_Registration to this EE_Answer
144
-     *
145
-     * @return EE_Registration
146
-     */
147
-    public function registration()
148
-    {
149
-        return $this->get_first_related('Registration');
150
-    }
13
+	/**
14
+	 *
15
+	 * @param array $props_n_values
16
+	 * @return EE_Answer
17
+	 */
18
+	public static function new_instance($props_n_values = array())
19
+	{
20
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
21
+		return $has_object ? $has_object : new self($props_n_values);
22
+	}
23
+
24
+
25
+	/**
26
+	 *
27
+	 * @param array $props_n_values
28
+	 * @return EE_Answer
29
+	 */
30
+	public static function new_instance_from_db($props_n_values = array())
31
+	{
32
+		return new self($props_n_values, true);
33
+	}
34
+
35
+
36
+	/**
37
+	 *    Set Question ID
38
+	 *
39
+	 * @access        public
40
+	 * @param int $QST_ID
41
+	 */
42
+	public function set_question($QST_ID = 0)
43
+	{
44
+		$this->set('QST_ID', $QST_ID);
45
+	}
46
+
47
+
48
+	/**
49
+	 *    Set Registration ID
50
+	 *
51
+	 * @access        public
52
+	 * @param int $REG_ID
53
+	 */
54
+	public function set_registration($REG_ID = 0)
55
+	{
56
+		$this->set('REG_ID', $REG_ID);
57
+	}
58
+
59
+
60
+	/**
61
+	 *    Set Answer value
62
+	 *
63
+	 * @access        public
64
+	 * @param mixed $ANS_value
65
+	 */
66
+	public function set_value($ANS_value = '')
67
+	{
68
+		$this->set('ANS_value', $ANS_value);
69
+	}
70
+
71
+
72
+	/**
73
+	 *    get Attendee First Name
74
+	 *
75
+	 * @access        public
76
+	 * @return        int
77
+	 */
78
+	public function registration_ID()
79
+	{
80
+		return $this->get('REG_ID');
81
+	}
82
+
83
+
84
+	/**
85
+	 *    get Attendee Last Name
86
+	 *
87
+	 * @access        public
88
+	 * @return        int
89
+	 */
90
+	public function question_ID()
91
+	{
92
+		return $this->get('QST_ID');
93
+	}
94
+
95
+
96
+	/**
97
+	 *    get Attendee Address
98
+	 *
99
+	 * @access        public
100
+	 * @return        string
101
+	 */
102
+	public function value()
103
+	{
104
+		return $this->get('ANS_value');
105
+	}
106
+
107
+
108
+	/**
109
+	 * Gets a pretty form of the value (mostly applies to answers that have multiple answers)
110
+	 *
111
+	 * @param null $schema
112
+	 * @return string
113
+	 */
114
+	public function pretty_value($schema = null)
115
+	{
116
+		return $this->get_pretty('ANS_value', $schema);
117
+	}
118
+
119
+
120
+	/**
121
+	 * Echoes out a pretty value (even for multi-choice options)
122
+	 *
123
+	 * @param string $schema
124
+	 */
125
+	public function e_value($schema = null)
126
+	{
127
+		$this->e('ANS_value', $schema);
128
+	}
129
+
130
+
131
+	/**
132
+	 * Gets the related EE_Question to this EE_Answer
133
+	 *
134
+	 * @return EE_Question
135
+	 */
136
+	public function question()
137
+	{
138
+		return $this->get_first_related('Question');
139
+	}
140
+
141
+
142
+	/**
143
+	 * Gets the related EE_Registration to this EE_Answer
144
+	 *
145
+	 * @return EE_Registration
146
+	 */
147
+	public function registration()
148
+	{
149
+		return $this->get_first_related('Registration');
150
+	}
151 151
 }
152 152
 
153 153
 /* End of file EE_Answer.class.php */
Please login to merge, or discard this patch.
core/db_classes/EE_Country.class.php 1 patch
Indentation   +119 added lines, -119 removed lines patch added patch discarded remove patch
@@ -10,123 +10,123 @@
 block discarded – undo
10 10
 class EE_Country extends EE_Base_Class
11 11
 {
12 12
 
13
-    /**
14
-     * @param array $props_n_values
15
-     * @return EE_Country|mixed
16
-     */
17
-    public static function new_instance($props_n_values = array())
18
-    {
19
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
20
-        return $has_object ? $has_object : new self($props_n_values);
21
-    }
22
-
23
-
24
-    /**
25
-     * @param array $props_n_values
26
-     * @return EE_Country
27
-     */
28
-    public static function new_instance_from_db($props_n_values = array())
29
-    {
30
-        return new self($props_n_values, true);
31
-    }
32
-
33
-
34
-    /**
35
-     * Gets the country name
36
-     *
37
-     * @return string
38
-     */
39
-    public function name()
40
-    {
41
-        return $this->get('CNT_name');
42
-    }
43
-
44
-
45
-    /**
46
-     * gets the country's currency code
47
-     *
48
-     * @return string
49
-     */
50
-    public function currency_code()
51
-    {
52
-        return $this->get('CNT_cur_code');
53
-    }
54
-
55
-
56
-    /**
57
-     * gets the country's currency sign/symbol
58
-     *
59
-     * @return string
60
-     */
61
-    public function currency_sign()
62
-    {
63
-        $CNT_cur_sign = $this->get('CNT_cur_sign');
64
-        return $CNT_cur_sign ? $CNT_cur_sign : '';
65
-    }
66
-
67
-
68
-    /**
69
-     * Currency name singular
70
-     *
71
-     * @return string
72
-     */
73
-    public function currency_name_single()
74
-    {
75
-        return $this->get('CNT_cur_single');
76
-    }
77
-
78
-
79
-    /**
80
-     * Currency name plural
81
-     *
82
-     * @return string
83
-     */
84
-    public function currency_name_plural()
85
-    {
86
-        return $this->get('CNT_cur_plural');
87
-    }
88
-
89
-
90
-    /**
91
-     * currency_sign_before - ie: $TRUE  or  FALSE$
92
-     *
93
-     * @return boolean
94
-     */
95
-    public function currency_sign_before()
96
-    {
97
-        return $this->get('CNT_cur_sign_b4');
98
-    }
99
-
100
-
101
-    /**
102
-     * currency_decimal_places : 2 = 0.00   3 = 0.000
103
-     *
104
-     * @return integer
105
-     */
106
-    public function currency_decimal_places()
107
-    {
108
-        return $this->get('CNT_cur_dec_plc');
109
-    }
110
-
111
-
112
-    /**
113
-     * currency_decimal_mark :   (comma) ',' = 0,01   or   (decimal) '.' = 0.01
114
-     *
115
-     * @return string
116
-     */
117
-    public function currency_decimal_mark()
118
-    {
119
-        return $this->get('CNT_cur_dec_mrk');
120
-    }
121
-
122
-
123
-    /**
124
-     * currency thousands separator:   (comma) ',' = 1,000   or   (decimal) '.' = 1.000
125
-     *
126
-     * @return string
127
-     */
128
-    public function currency_thousands_separator()
129
-    {
130
-        return $this->get('CNT_cur_thsnds');
131
-    }
13
+	/**
14
+	 * @param array $props_n_values
15
+	 * @return EE_Country|mixed
16
+	 */
17
+	public static function new_instance($props_n_values = array())
18
+	{
19
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
20
+		return $has_object ? $has_object : new self($props_n_values);
21
+	}
22
+
23
+
24
+	/**
25
+	 * @param array $props_n_values
26
+	 * @return EE_Country
27
+	 */
28
+	public static function new_instance_from_db($props_n_values = array())
29
+	{
30
+		return new self($props_n_values, true);
31
+	}
32
+
33
+
34
+	/**
35
+	 * Gets the country name
36
+	 *
37
+	 * @return string
38
+	 */
39
+	public function name()
40
+	{
41
+		return $this->get('CNT_name');
42
+	}
43
+
44
+
45
+	/**
46
+	 * gets the country's currency code
47
+	 *
48
+	 * @return string
49
+	 */
50
+	public function currency_code()
51
+	{
52
+		return $this->get('CNT_cur_code');
53
+	}
54
+
55
+
56
+	/**
57
+	 * gets the country's currency sign/symbol
58
+	 *
59
+	 * @return string
60
+	 */
61
+	public function currency_sign()
62
+	{
63
+		$CNT_cur_sign = $this->get('CNT_cur_sign');
64
+		return $CNT_cur_sign ? $CNT_cur_sign : '';
65
+	}
66
+
67
+
68
+	/**
69
+	 * Currency name singular
70
+	 *
71
+	 * @return string
72
+	 */
73
+	public function currency_name_single()
74
+	{
75
+		return $this->get('CNT_cur_single');
76
+	}
77
+
78
+
79
+	/**
80
+	 * Currency name plural
81
+	 *
82
+	 * @return string
83
+	 */
84
+	public function currency_name_plural()
85
+	{
86
+		return $this->get('CNT_cur_plural');
87
+	}
88
+
89
+
90
+	/**
91
+	 * currency_sign_before - ie: $TRUE  or  FALSE$
92
+	 *
93
+	 * @return boolean
94
+	 */
95
+	public function currency_sign_before()
96
+	{
97
+		return $this->get('CNT_cur_sign_b4');
98
+	}
99
+
100
+
101
+	/**
102
+	 * currency_decimal_places : 2 = 0.00   3 = 0.000
103
+	 *
104
+	 * @return integer
105
+	 */
106
+	public function currency_decimal_places()
107
+	{
108
+		return $this->get('CNT_cur_dec_plc');
109
+	}
110
+
111
+
112
+	/**
113
+	 * currency_decimal_mark :   (comma) ',' = 0,01   or   (decimal) '.' = 0.01
114
+	 *
115
+	 * @return string
116
+	 */
117
+	public function currency_decimal_mark()
118
+	{
119
+		return $this->get('CNT_cur_dec_mrk');
120
+	}
121
+
122
+
123
+	/**
124
+	 * currency thousands separator:   (comma) ',' = 1,000   or   (decimal) '.' = 1.000
125
+	 *
126
+	 * @return string
127
+	 */
128
+	public function currency_thousands_separator()
129
+	{
130
+		return $this->get('CNT_cur_thsnds');
131
+	}
132 132
 }
Please login to merge, or discard this patch.
core/db_classes/EE_CSV.class.php 2 patches
Indentation   +669 added lines, -669 removed lines patch added patch discarded remove patch
@@ -16,673 +16,673 @@
 block discarded – undo
16 16
 class EE_CSV
17 17
 {
18 18
 
19
-    // instance of the EE_CSV object
20
-    private static $_instance = null;
21
-
22
-
23
-    // multidimensional array to store update & error messages
24
-    // var $_notices = array( 'updates' => array(), 'errors' => array() );
25
-
26
-
27
-    private $_primary_keys;
28
-
29
-    /**
30
-     *
31
-     * @var EE_Registry
32
-     */
33
-    private $EE;
34
-    /**
35
-     * string used for 1st cell in exports, which indicates that the following 2 rows will be metadata keys and values
36
-     */
37
-    const metadata_header = 'Event Espresso Export Meta Data';
38
-
39
-    /**
40
-     *        private constructor to prevent direct creation
41
-     *
42
-     * @Constructor
43
-     * @access private
44
-     * @return void
45
-     */
46
-    private function __construct()
47
-    {
48
-        global $wpdb;
49
-
50
-        $this->_primary_keys = array(
51
-            $wpdb->prefix . 'esp_answer'                  => array('ANS_ID'),
52
-            $wpdb->prefix . 'esp_attendee'                => array('ATT_ID'),
53
-            $wpdb->prefix . 'esp_datetime'                => array('DTT_ID'),
54
-            $wpdb->prefix . 'esp_event_question_group'    => array('EQG_ID'),
55
-            $wpdb->prefix . 'esp_message_template'        => array('MTP_ID'),
56
-            $wpdb->prefix . 'esp_payment'                 => array('PAY_ID'),
57
-            $wpdb->prefix . 'esp_price'                   => array('PRC_ID'),
58
-            $wpdb->prefix . 'esp_price_type'              => array('PRT_ID'),
59
-            $wpdb->prefix . 'esp_question'                => array('QST_ID'),
60
-            $wpdb->prefix . 'esp_question_group'          => array('QSG_ID'),
61
-            $wpdb->prefix . 'esp_question_group_question' => array('QGQ_ID'),
62
-            $wpdb->prefix . 'esp_question_option'         => array('QSO_ID'),
63
-            $wpdb->prefix . 'esp_registration'            => array('REG_ID'),
64
-            $wpdb->prefix . 'esp_status'                  => array('STS_ID'),
65
-            $wpdb->prefix . 'esp_transaction'             => array('TXN_ID'),
66
-            $wpdb->prefix . 'esp_transaction'             => array('TXN_ID'),
67
-            $wpdb->prefix . 'events_detail'               => array('id'),
68
-            $wpdb->prefix . 'events_category_detail'      => array('id'),
69
-            $wpdb->prefix . 'events_category_rel'         => array('id'),
70
-            $wpdb->prefix . 'events_venue'                => array('id'),
71
-            $wpdb->prefix . 'events_venue_rel'            => array('emeta_id'),
72
-            $wpdb->prefix . 'events_locale'               => array('id'),
73
-            $wpdb->prefix . 'events_locale_rel'           => array('id'),
74
-            $wpdb->prefix . 'events_personnel'            => array('id'),
75
-            $wpdb->prefix . 'events_personnel_rel'        => array('id'),
76
-        );
77
-    }
78
-
79
-
80
-    /**
81
-     *        @ singleton method used to instantiate class object
82
-     *        @ access public
83
-     *
84
-     * @return EE_CSV
85
-     */
86
-    public static function instance()
87
-    {
88
-        // check if class object is instantiated
89
-        if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_CSV)) {
90
-            self::$_instance = new self();
91
-        }
92
-        return self::$_instance;
93
-    }
94
-
95
-    /**
96
-     * Opens a unicode or utf file (normal file_get_contents has difficulty readin ga unicode file. @see
97
-     * http://stackoverflow.com/questions/15092764/how-to-read-unicode-text-file-in-php
98
-     *
99
-     * @param string $file_path
100
-     * @return string
101
-     * @throws EE_Error
102
-     */
103
-    private function read_unicode_file($file_path)
104
-    {
105
-        $fc = "";
106
-        $fh = fopen($file_path, "rb");
107
-        if (! $fh) {
108
-            throw new EE_Error(sprintf(__("Cannot open file for read: %s<br>\n", 'event_espresso'), $file_path));
109
-        }
110
-        $flen = filesize($file_path);
111
-        $bc = fread($fh, $flen);
112
-        for ($i = 0; $i < $flen; $i++) {
113
-            $c = substr($bc, $i, 1);
114
-            if ((ord($c) != 0) && (ord($c) != 13)) {
115
-                $fc = $fc . $c;
116
-            }
117
-        }
118
-        if ((ord(substr($fc, 0, 1)) == 255) && (ord(substr($fc, 1, 1)) == 254)) {
119
-            $fc = substr($fc, 2);
120
-        }
121
-        return ($fc);
122
-    }
123
-
124
-
125
-    /**
126
-     * Generic CSV-functionality to turn an entire CSV file into a single array that's
127
-     * NOT in a specific format to EE. It's just a 2-level array, with top-level arrays
128
-     * representing each row in the CSV file, and the second-level arrays being each column in that row
129
-     *
130
-     * @param string $path_to_file
131
-     * @return array of arrays. Top-level array has rows, second-level array has each item
132
-     */
133
-    public function import_csv_to_multi_dimensional_array($path_to_file)
134
-    {
135
-        // needed to deal with Mac line endings
136
-        ini_set('auto_detect_line_endings', true);
137
-
138
-        // because fgetcsv does not correctly deal with backslashed quotes such as \"
139
-        // we'll read the file into a string
140
-        $file_contents = $this->read_unicode_file($path_to_file);
141
-        // replace backslashed quotes with CSV enclosures
142
-        $file_contents = str_replace('\\"', '"""', $file_contents);
143
-        // HEY YOU! PUT THAT FILE BACK!!!
144
-        file_put_contents($path_to_file, $file_contents);
145
-
146
-        if (($file_handle = fopen($path_to_file, "r")) !== false) {
147
-            # Set the parent multidimensional array key to 0.
148
-            $nn = 0;
149
-            $csvarray = array();
150
-
151
-            // 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?
152
-            if (version_compare(PHP_VERSION, '5.3.0') < 0) {
153
-                //  PHP 5.2- version
154
-                // loop through each row of the file
155
-                while (($data = fgetcsv($file_handle, 0, ',', '"')) !== false) {
156
-                    $csvarray[] = $data;
157
-                }
158
-            } else {
159
-                // loop through each row of the file
160
-                while (($data = fgetcsv($file_handle, 0, ',', '"', '\\')) !== false) {
161
-                    $csvarray[] = $data;
162
-                }
163
-            }
164
-            # Close the File.
165
-            fclose($file_handle);
166
-            return $csvarray;
167
-        } else {
168
-            EE_Error::add_error(
169
-                sprintf(__("An error occurred - the file: %s could not opened.", "event_espresso"), $path_to_file),
170
-                __FILE__,
171
-                __FUNCTION__,
172
-                __LINE__
173
-            );
174
-            return false;
175
-        }
176
-    }
177
-
178
-
179
-    /**
180
-     * @Import contents of csv file and store values in an array to be manipulated by other functions
181
-     * @access public
182
-     * @param string  $path_to_file         - the csv file to be imported including the path to it's location.
183
-     *                                      If $model_name is provided, assumes that each row in the CSV represents a
184
-     *                                      model object for that model If $model_name ISN'T provided, assumes that
185
-     *                                      before model object data, there is a row where the first entry is simply
186
-     *                                      'MODEL', and next entry is the model's name, (untranslated) like Event, and
187
-     *                                      then maybe a row of headers, and then the model data. Eg.
188
-     *                                      '<br>MODEL,Event,<br>EVT_ID,EVT_name,...<br>1,Monkey
189
-     *                                      Party,...<br>2,Llamarama,...<br>MODEL,Venue,<br>VNU_ID,VNU_name<br>1,The
190
-     *                                      Forest
191
-     * @param string  $model_name           model name if we know what model we're importing
192
-     * @param boolean $first_row_is_headers - whether the first row of data is headers or not - TRUE = headers, FALSE =
193
-     *                                      data
194
-     * @return mixed - array on success - multi dimensional with headers as keys (if headers exist) OR string on fail -
195
-     *               error message like the following array('Event'=>array( array('EVT_ID'=>1,'EVT_name'=>'bob
196
-     *               party',...), array('EVT_ID'=>2,'EVT_name'=>'llamarama',...),
197
-     *                                      ...
198
-     *                                      )
199
-     *                                      'Venue'=>array(
200
-     *                                      array('VNU_ID'=>1,'VNU_name'=>'the shack',...),
201
-     *                                      array('VNU_ID'=>2,'VNU_name'=>'tree house',...),
202
-     *                                      ...
203
-     *                                      )
204
-     *                                      ...
205
-     *                                      )
206
-     */
207
-    public function import_csv_to_model_data_array($path_to_file, $model_name = false, $first_row_is_headers = true)
208
-    {
209
-        $multi_dimensional_array = $this->import_csv_to_multi_dimensional_array($path_to_file);
210
-        if (! $multi_dimensional_array) {
211
-            return false;
212
-        }
213
-        // gotta start somewhere
214
-        $row = 1;
215
-        // array to store csv data in
216
-        $ee_formatted_data = array();
217
-        // array to store headers (column names)
218
-        $headers = array();
219
-        foreach ($multi_dimensional_array as $data) {
220
-            // if first cell is MODEL, then second cell is the MODEL name
221
-            if ($data[0] == 'MODEL') {
222
-                $model_name = $data[1];
223
-                // don't bother looking for model data in this row. The rest of this
224
-                // row should be blank
225
-                // AND pretend this is the first row again
226
-                $row = 1;
227
-                // reset headers
228
-                $headers = array();
229
-                continue;
230
-            }
231
-            if (strpos($data[0], EE_CSV::metadata_header) !== false) {
232
-                $model_name = EE_CSV::metadata_header;
233
-                // store like model data, we just won't try importing it etc.
234
-                $row = 1;
235
-                continue;
236
-            }
237
-
238
-
239
-            // how many columns are there?
240
-            $columns = count($data);
241
-
242
-            $model_entry = array();
243
-            // loop through each column
244
-            for ($i = 0; $i < $columns; $i++) {
245
-                // replace csv_enclosures with backslashed quotes
246
-                $data[ $i ] = str_replace('"""', '\\"', $data[ $i ]);
247
-                // do we need to grab the column names?
248
-                if ($row === 1) {
249
-                    if ($first_row_is_headers) {
250
-                        // store the column names to use for keys
251
-                        $column_name = $data[ $i ];
252
-                        // check it's not blank... sometimes CSV editign programs adda bunch of empty columns onto the end...
253
-                        if (! $column_name) {
254
-                            continue;
255
-                        }
256
-                        $matches = array();
257
-                        if ($model_name == EE_CSV::metadata_header) {
258
-                            $headers[ $i ] = $column_name;
259
-                        } else {
260
-                            // now get the db table name from it (the part between square brackets)
261
-                            $success = preg_match('~(.*)\[(.*)\]~', $column_name, $matches);
262
-                            if (! $success) {
263
-                                EE_Error::add_error(
264
-                                    sprintf(
265
-                                        __(
266
-                                            "The column titled %s is invalid for importing. It must be be in the format of 'Nice Name[model_field_name]' in row %s",
267
-                                            "event_espresso"
268
-                                        ),
269
-                                        $column_name,
270
-                                        implode(",", $data)
271
-                                    ),
272
-                                    __FILE__,
273
-                                    __FUNCTION__,
274
-                                    __LINE__
275
-                                );
276
-                                return false;
277
-                            }
278
-                            $headers[ $i ] = $matches[2];
279
-                        }
280
-                    } else {
281
-                        // no column names means our final array will just use counters for keys
282
-                        $model_entry[ $headers[ $i ] ] = $data[ $i ];
283
-                        $headers[ $i ] = $i;
284
-                    }
285
-                    // and we need to store csv data
286
-                } else {
287
-                    // this column isn' ta header, store it if there is a header for it
288
-                    if (isset($headers[ $i ])) {
289
-                        $model_entry[ $headers[ $i ] ] = $data[ $i ];
290
-                    }
291
-                }
292
-            }
293
-            // save the row's data IF it's a non-header-row
294
-            if (! $first_row_is_headers || ($first_row_is_headers && $row > 1)) {
295
-                $ee_formatted_data[ $model_name ][] = $model_entry;
296
-            }
297
-            // advance to next row
298
-            $row++;
299
-        }
300
-
301
-        // delete the uploaded file
302
-        unlink($path_to_file);
303
-        // 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>';
304
-        // die();
305
-
306
-        // it's good to give back
307
-        return $ee_formatted_data;
308
-    }
309
-
310
-
311
-    public function save_csv_to_db($csv_data_array, $model_name = false)
312
-    {
313
-        EE_Error::doing_it_wrong(
314
-            'save_csv_to_db',
315
-            __(
316
-                'Function moved to EE_Import and renamed to save_csv_data_array_to_db',
317
-                'event_espresso'
318
-            ),
319
-            '4.6.7'
320
-        );
321
-        return EE_Import::instance()->save_csv_data_array_to_db($csv_data_array, $model_name);
322
-    }
323
-
324
-    /**
325
-     * Sends HTTP headers to indicate that the browser should download a file,
326
-     * and starts writing the file to PHP's output. Returns the file handle so other functions can
327
-     * also write to it
328
-     *
329
-     * @param string $new_filename the name of the file that the user will download
330
-     * @return resource, like the results of fopen(), which can be used for fwrite, fputcsv2, etc.
331
-     */
332
-    public function begin_sending_csv($filename)
333
-    {
334
-        // grab file extension
335
-        $ext = substr(strrchr($filename, '.'), 1);
336
-        if ($ext == '.csv' or $ext == '.xls') {
337
-            str_replace($ext, '', $filename);
338
-        }
339
-        $filename .= '.csv';
340
-
341
-        // if somebody's been naughty and already started outputting stuff, trash it
342
-        // and start writing our stuff.
343
-        if (ob_get_length()) {
344
-            @ob_flush();
345
-            @flush();
346
-            @ob_end_flush();
347
-        }
348
-        @ob_start();
349
-        header("Pragma: public");
350
-        header("Expires: 0");
351
-        header("Pragma: no-cache");
352
-        header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
353
-        // header("Content-Type: application/force-download");
354
-        // header("Content-Type: application/octet-stream");
355
-        // header("Content-Type: application/download");
356
-        header('Content-disposition: attachment; filename=' . $filename);
357
-        header("Content-Type: text/csv; charset=utf-8");
358
-        do_action('AHEE__EE_CSV__begin_sending_csv__headers');
359
-        echo apply_filters(
360
-            'FHEE__EE_CSV__begin_sending_csv__start_writing',
361
-            "\xEF\xBB\xBF"
362
-        ); // makes excel open it as UTF-8. UTF-8 BOM, see http://stackoverflow.com/a/4440143/2773835
363
-        $fh = fopen('php://output', 'w');
364
-        return $fh;
365
-    }
366
-
367
-    /**
368
-     * Writes some meta data to the CSV as a bunch of columns. Initially we're only
369
-     * mentioning the version and timezone
370
-     *
371
-     * @param resource $filehandle
372
-     */
373
-    public function write_metadata_to_csv($filehandle)
374
-    {
375
-        $data_row = array(EE_CSV::metadata_header);// do NOT translate because this exact string is used when importing
376
-        $this->fputcsv2($filehandle, $data_row);
377
-        $meta_data = array(
378
-            0 => array(
379
-                'version'        => espresso_version(),
380
-                'timezone'       => EEH_DTT_Helper::get_timezone(),
381
-                'time_of_export' => current_time('mysql'),
382
-                'site_url'       => site_url(),
383
-            ),
384
-        );
385
-        $this->write_data_array_to_csv($filehandle, $meta_data);
386
-    }
387
-
388
-
389
-    /**
390
-     * Writes $data to the csv file open in $filehandle. uses the array indices of $data for column headers
391
-     *
392
-     * @param array   $data                 2D array, first numerically-indexed, and next-level-down preferably indexed
393
-     *                                      by string
394
-     * @param boolean $add_csv_column_names whether or not we should add the keys in the bottom-most array as a row for
395
-     *                                      headers in the CSV. Eg, if $data looked like
396
-     *                                      array(0=>array('EVT_ID'=>1,'EVT_name'=>'monkey'...), 1=>array(...),...))
397
-     *                                      then the first row we'd write to the CSV would be "EVT_ID,EVT_name,..."
398
-     * @return boolean if we successfully wrote to the CSV or not. If there's no $data, we consider that a success
399
-     *                 (because we wrote everything there was...nothing)
400
-     */
401
-    public function write_data_array_to_csv($filehandle, $data)
402
-    {
403
-
404
-
405
-        // determine if $data is actually a 2d array
406
-        if ($data && is_array($data) && is_array(EEH_Array::get_one_item_from_array($data))) {
407
-            // make sure top level is numerically indexed,
408
-
409
-            if (EEH_Array::is_associative_array($data)) {
410
-                throw new EE_Error(
411
-                    sprintf(
412
-                        __(
413
-                            "top-level array must be numerically indexed. Does these look like numbers to you? %s",
414
-                            "event_espresso"
415
-                        ),
416
-                        implode(",", array_keys($data))
417
-                    )
418
-                );
419
-            }
420
-            $item_in_top_level_array = EEH_Array::get_one_item_from_array($data);
421
-            // now, is the last item in the top-level array of $data an associative or numeric array?
422
-            if (EEH_Array::is_associative_array($item_in_top_level_array)) {
423
-                // its associative, so we want to output its keys as column headers
424
-                $keys = array_keys($item_in_top_level_array);
425
-                echo $this->fputcsv2($filehandle, $keys);
426
-            }
427
-            // start writing data
428
-            foreach ($data as $data_row) {
429
-                echo $this->fputcsv2($filehandle, $data_row);
430
-            }
431
-            return true;
432
-        } else {
433
-            // no data TO write... so we can assume that's a success
434
-            return true;
435
-        }
436
-        // //if 2nd level is indexed by strings, use those as csv column headers (ie, the first row)
437
-        //
438
-        //
439
-        // $no_table = TRUE;
440
-        //
441
-        // // loop through data and add each row to the file/stream as csv
442
-        // foreach ( $data as $model_name => $model_data ) {
443
-        // // test first row to see if it is data or a model name
444
-        // $model = EE_Registry::instance();->load_model($model_name);
445
-        // //if the model really exists,
446
-        // if ( $model ) {
447
-        //
448
-        // // we have a table name
449
-        // $no_table = FALSE;
450
-        //
451
-        // // put the tablename into an array cuz that's how fputcsv rolls
452
-        // $model_name_row = array( 'MODEL', $model_name );
453
-        //
454
-        // // add table name to csv output
455
-        // echo self::fputcsv2($filehandle, $model_name_row);
456
-        //
457
-        // // now get the rest of the data
458
-        // foreach ( $model_data as $row ) {
459
-        // // output the row
460
-        // echo self::fputcsv2($filehandle, $row);
461
-        // }
462
-        //
463
-        // }
464
-        //
465
-        // if ( $no_table ) {
466
-        // // no table so just put the data
467
-        // echo self::fputcsv2($filehandle, $model_data);
468
-        // }
469
-        //
470
-        // } // END OF foreach ( $data )
471
-    }
472
-
473
-    /**
474
-     * Should be called after begin_sending_csv(), and one or more write_data_array_to_csv()s.
475
-     * Calls exit to prevent polluting the CSV file with other junk
476
-     *
477
-     * @param resource $fh filehandle where we're writing the CSV to
478
-     */
479
-    public function end_sending_csv($fh)
480
-    {
481
-        fclose($fh);
482
-        exit(0);
483
-    }
484
-
485
-    /**
486
-     * Given an open file, writes all the model data to it in the format the importer expects.
487
-     * Usually preceded by begin_sending_csv($filename), and followed by end_sending_csv($filehandle).
488
-     *
489
-     * @param resource $filehandle
490
-     * @param array    $model_data_array is assumed to be a 3d array: 1st layer has keys of model names (eg 'Event'),
491
-     *                                   next layer is numerically indexed to represent each model object (eg, each
492
-     *                                   individual event), and the last layer has all the attributes o fthat model
493
-     *                                   object (eg, the event's id, name, etc)
494
-     * @return boolean success
495
-     */
496
-    public function write_model_data_to_csv($filehandle, $model_data_array)
497
-    {
498
-        $this->write_metadata_to_csv($filehandle);
499
-        foreach ($model_data_array as $model_name => $model_instance_arrays) {
500
-            // first: output a special row stating the model
501
-            echo $this->fputcsv2($filehandle, array('MODEL', $model_name));
502
-            // if we have items to put in the CSV, do it normally
503
-
504
-            if (! empty($model_instance_arrays)) {
505
-                $this->write_data_array_to_csv($filehandle, $model_instance_arrays);
506
-            } else {
507
-                // echo "no data to write... so just write the headers";
508
-                // so there's actually NO model objects for that model.
509
-                // probably still want to show the columns
510
-                $model = EE_Registry::instance()->load_model($model_name);
511
-                $column_names = array();
512
-                foreach ($model->field_settings() as $field) {
513
-                    $column_names[ $field->get_nicename() . "[" . $field->get_name() . "]" ] = null;
514
-                }
515
-                $this->write_data_array_to_csv($filehandle, array($column_names));
516
-            }
517
-        }
518
-    }
519
-
520
-    /**
521
-     * Writes the CSV file to the output buffer, with rows corresponding to $model_data_array,
522
-     * and dies (in order to avoid other plugins from messing up the csv output)
523
-     *
524
-     * @param string $filename         the filename you want to give the file
525
-     * @param array  $model_data_array 3d array, as described in EE_CSV::write_model_data_to_csv()
526
-     * @return bool | void writes CSV file to output and dies
527
-     */
528
-    public function export_multiple_model_data_to_csv($filename, $model_data_array)
529
-    {
530
-        $filehandle = $this->begin_sending_csv($filename);
531
-        $this->write_model_data_to_csv($filehandle, $model_data_array);
532
-        $this->end_sending_csv($filehandle);
533
-    }
534
-
535
-    /**
536
-     * @Export contents of an array to csv file
537
-     * @access public
538
-     * @param array  $data     - the array of data to be converted to csv and exported
539
-     * @param string $filename - name for newly created csv file
540
-     * @return TRUE on success, FALSE on fail
541
-     */
542
-    public function export_array_to_csv($data = false, $filename = false)
543
-    {
544
-
545
-        // no data file?? get outta here
546
-        if (! $data or ! is_array($data) or empty($data)) {
547
-            return false;
548
-        }
549
-
550
-        // no filename?? get outta here
551
-        if (! $filename) {
552
-            return false;
553
-        }
554
-
555
-
556
-        // somebody told me i might need this ???
557
-        global $wpdb;
558
-        $prefix = $wpdb->prefix;
559
-
560
-
561
-        $fh = $this->begin_sending_csv($filename);
562
-
563
-
564
-        $this->end_sending_csv($fh);
565
-    }
566
-
567
-
568
-    /**
569
-     * @Determine the maximum upload file size based on php.ini settings
570
-     * @access    public
571
-     * @param int $percent_of_max - desired percentage of the max upload_mb
572
-     * @return int KB
573
-     */
574
-    public function get_max_upload_size($percent_of_max = false)
575
-    {
576
-
577
-        $max_upload = (int) (ini_get('upload_max_filesize'));
578
-        $max_post = (int) (ini_get('post_max_size'));
579
-        $memory_limit = (int) (ini_get('memory_limit'));
580
-
581
-        // determine the smallest of the three values from above
582
-        $upload_mb = min($max_upload, $max_post, $memory_limit);
583
-
584
-        // convert MB to KB
585
-        $upload_mb = $upload_mb * 1024;
586
-
587
-        // don't want the full monty? then reduce the max uplaod size
588
-        if ($percent_of_max) {
589
-            // is percent_of_max like this -> 50 or like this -> 0.50 ?
590
-            if ($percent_of_max > 1) {
591
-                // chnages 50 to 0.50
592
-                $percent_of_max = $percent_of_max / 100;
593
-            }
594
-            // make upload_mb a percentage of the max upload_mb
595
-            $upload_mb = $upload_mb * $percent_of_max;
596
-        }
597
-
598
-        return $upload_mb;
599
-    }
600
-
601
-
602
-    /**
603
-     * @Drop   in replacement for PHP's fputcsv function - but this one works!!!
604
-     * @access private
605
-     * @param resource $fh         - file handle - what we are writing to
606
-     * @param array    $row        - individual row of csv data
607
-     * @param string   $delimiter  - csv delimiter
608
-     * @param string   $enclosure  - csv enclosure
609
-     * @param string   $mysql_null - allows php NULL to be overridden with MySQl's insertable NULL value
610
-     * @return void
611
-     */
612
-    private function fputcsv2($fh, array $row, $delimiter = ',', $enclosure = '"', $mysql_null = false)
613
-    {
614
-        // Allow user to filter the csv delimiter and enclosure for other countries csv standards
615
-        $delimiter = apply_filters('FHEE__EE_CSV__fputcsv2__delimiter', $delimiter);
616
-        $enclosure = apply_filters('FHEE__EE_CSV__fputcsv2__enclosure', $enclosure);
617
-
618
-        $delimiter_esc = preg_quote($delimiter, '/');
619
-        $enclosure_esc = preg_quote($enclosure, '/');
620
-
621
-        $output = array();
622
-        foreach ($row as $field_value) {
623
-            if (is_object($field_value) || is_array($field_value)) {
624
-                $field_value = serialize($field_value);
625
-            }
626
-            if ($field_value === null && $mysql_null) {
627
-                $output[] = 'NULL';
628
-                continue;
629
-            }
630
-
631
-            $output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field_value) ?
632
-                ($enclosure . str_replace($enclosure, $enclosure . $enclosure, $field_value) . $enclosure)
633
-                : $field_value;
634
-        }
635
-
636
-        fwrite($fh, join($delimiter, $output) . PHP_EOL);
637
-    }
638
-
639
-
640
-    // /**
641
-    //  * @CSV    Import / Export messages
642
-    //  * @access public
643
-    //  * @return void
644
-    //  */
645
-    // public function csv_admin_notices()
646
-    // {
647
-    //
648
-    //     // We play both kinds of music here! Country AND Western! - err... I mean, cycle through both types of notices
649
-    //     foreach (array('updates', 'errors') as $type) {
650
-    //
651
-    //         // if particular notice type is not empty, then "You've got Mail"
652
-    //         if (! empty($this->_notices[ $type ])) {
653
-    //
654
-    //             // is it an update or an error ?
655
-    //             $msg_class = $type == 'updates' ? 'updated' : 'error';
656
-    //             echo '<div id="message" class="' . $msg_class . '">';
657
-    //             // display each notice, however many that may be
658
-    //             foreach ($this->_notices[ $type ] as $message) {
659
-    //                 echo '<p>' . $message . '</p>';
660
-    //             }
661
-    //             // wrap it up
662
-    //             echo '</div>';
663
-    //         }
664
-    //     }
665
-    // }
666
-
667
-    /**
668
-     * Gets the date format to use in teh csv. filterable
669
-     *
670
-     * @param string $current_format
671
-     * @return string
672
-     */
673
-    public function get_date_format_for_csv($current_format = null)
674
-    {
675
-        return apply_filters('FHEE__EE_CSV__get_date_format_for_csv__format', 'Y-m-d', $current_format);
676
-    }
677
-
678
-    /**
679
-     * Gets the time format we want to use in CSV reports. Filterable
680
-     *
681
-     * @param string $current_format
682
-     * @return string
683
-     */
684
-    public function get_time_format_for_csv($current_format = null)
685
-    {
686
-        return apply_filters('FHEE__EE_CSV__get_time_format_for_csv__format', 'H:i:s', $current_format);
687
-    }
19
+	// instance of the EE_CSV object
20
+	private static $_instance = null;
21
+
22
+
23
+	// multidimensional array to store update & error messages
24
+	// var $_notices = array( 'updates' => array(), 'errors' => array() );
25
+
26
+
27
+	private $_primary_keys;
28
+
29
+	/**
30
+	 *
31
+	 * @var EE_Registry
32
+	 */
33
+	private $EE;
34
+	/**
35
+	 * string used for 1st cell in exports, which indicates that the following 2 rows will be metadata keys and values
36
+	 */
37
+	const metadata_header = 'Event Espresso Export Meta Data';
38
+
39
+	/**
40
+	 *        private constructor to prevent direct creation
41
+	 *
42
+	 * @Constructor
43
+	 * @access private
44
+	 * @return void
45
+	 */
46
+	private function __construct()
47
+	{
48
+		global $wpdb;
49
+
50
+		$this->_primary_keys = array(
51
+			$wpdb->prefix . 'esp_answer'                  => array('ANS_ID'),
52
+			$wpdb->prefix . 'esp_attendee'                => array('ATT_ID'),
53
+			$wpdb->prefix . 'esp_datetime'                => array('DTT_ID'),
54
+			$wpdb->prefix . 'esp_event_question_group'    => array('EQG_ID'),
55
+			$wpdb->prefix . 'esp_message_template'        => array('MTP_ID'),
56
+			$wpdb->prefix . 'esp_payment'                 => array('PAY_ID'),
57
+			$wpdb->prefix . 'esp_price'                   => array('PRC_ID'),
58
+			$wpdb->prefix . 'esp_price_type'              => array('PRT_ID'),
59
+			$wpdb->prefix . 'esp_question'                => array('QST_ID'),
60
+			$wpdb->prefix . 'esp_question_group'          => array('QSG_ID'),
61
+			$wpdb->prefix . 'esp_question_group_question' => array('QGQ_ID'),
62
+			$wpdb->prefix . 'esp_question_option'         => array('QSO_ID'),
63
+			$wpdb->prefix . 'esp_registration'            => array('REG_ID'),
64
+			$wpdb->prefix . 'esp_status'                  => array('STS_ID'),
65
+			$wpdb->prefix . 'esp_transaction'             => array('TXN_ID'),
66
+			$wpdb->prefix . 'esp_transaction'             => array('TXN_ID'),
67
+			$wpdb->prefix . 'events_detail'               => array('id'),
68
+			$wpdb->prefix . 'events_category_detail'      => array('id'),
69
+			$wpdb->prefix . 'events_category_rel'         => array('id'),
70
+			$wpdb->prefix . 'events_venue'                => array('id'),
71
+			$wpdb->prefix . 'events_venue_rel'            => array('emeta_id'),
72
+			$wpdb->prefix . 'events_locale'               => array('id'),
73
+			$wpdb->prefix . 'events_locale_rel'           => array('id'),
74
+			$wpdb->prefix . 'events_personnel'            => array('id'),
75
+			$wpdb->prefix . 'events_personnel_rel'        => array('id'),
76
+		);
77
+	}
78
+
79
+
80
+	/**
81
+	 *        @ singleton method used to instantiate class object
82
+	 *        @ access public
83
+	 *
84
+	 * @return EE_CSV
85
+	 */
86
+	public static function instance()
87
+	{
88
+		// check if class object is instantiated
89
+		if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_CSV)) {
90
+			self::$_instance = new self();
91
+		}
92
+		return self::$_instance;
93
+	}
94
+
95
+	/**
96
+	 * Opens a unicode or utf file (normal file_get_contents has difficulty readin ga unicode file. @see
97
+	 * http://stackoverflow.com/questions/15092764/how-to-read-unicode-text-file-in-php
98
+	 *
99
+	 * @param string $file_path
100
+	 * @return string
101
+	 * @throws EE_Error
102
+	 */
103
+	private function read_unicode_file($file_path)
104
+	{
105
+		$fc = "";
106
+		$fh = fopen($file_path, "rb");
107
+		if (! $fh) {
108
+			throw new EE_Error(sprintf(__("Cannot open file for read: %s<br>\n", 'event_espresso'), $file_path));
109
+		}
110
+		$flen = filesize($file_path);
111
+		$bc = fread($fh, $flen);
112
+		for ($i = 0; $i < $flen; $i++) {
113
+			$c = substr($bc, $i, 1);
114
+			if ((ord($c) != 0) && (ord($c) != 13)) {
115
+				$fc = $fc . $c;
116
+			}
117
+		}
118
+		if ((ord(substr($fc, 0, 1)) == 255) && (ord(substr($fc, 1, 1)) == 254)) {
119
+			$fc = substr($fc, 2);
120
+		}
121
+		return ($fc);
122
+	}
123
+
124
+
125
+	/**
126
+	 * Generic CSV-functionality to turn an entire CSV file into a single array that's
127
+	 * NOT in a specific format to EE. It's just a 2-level array, with top-level arrays
128
+	 * representing each row in the CSV file, and the second-level arrays being each column in that row
129
+	 *
130
+	 * @param string $path_to_file
131
+	 * @return array of arrays. Top-level array has rows, second-level array has each item
132
+	 */
133
+	public function import_csv_to_multi_dimensional_array($path_to_file)
134
+	{
135
+		// needed to deal with Mac line endings
136
+		ini_set('auto_detect_line_endings', true);
137
+
138
+		// because fgetcsv does not correctly deal with backslashed quotes such as \"
139
+		// we'll read the file into a string
140
+		$file_contents = $this->read_unicode_file($path_to_file);
141
+		// replace backslashed quotes with CSV enclosures
142
+		$file_contents = str_replace('\\"', '"""', $file_contents);
143
+		// HEY YOU! PUT THAT FILE BACK!!!
144
+		file_put_contents($path_to_file, $file_contents);
145
+
146
+		if (($file_handle = fopen($path_to_file, "r")) !== false) {
147
+			# Set the parent multidimensional array key to 0.
148
+			$nn = 0;
149
+			$csvarray = array();
150
+
151
+			// 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?
152
+			if (version_compare(PHP_VERSION, '5.3.0') < 0) {
153
+				//  PHP 5.2- version
154
+				// loop through each row of the file
155
+				while (($data = fgetcsv($file_handle, 0, ',', '"')) !== false) {
156
+					$csvarray[] = $data;
157
+				}
158
+			} else {
159
+				// loop through each row of the file
160
+				while (($data = fgetcsv($file_handle, 0, ',', '"', '\\')) !== false) {
161
+					$csvarray[] = $data;
162
+				}
163
+			}
164
+			# Close the File.
165
+			fclose($file_handle);
166
+			return $csvarray;
167
+		} else {
168
+			EE_Error::add_error(
169
+				sprintf(__("An error occurred - the file: %s could not opened.", "event_espresso"), $path_to_file),
170
+				__FILE__,
171
+				__FUNCTION__,
172
+				__LINE__
173
+			);
174
+			return false;
175
+		}
176
+	}
177
+
178
+
179
+	/**
180
+	 * @Import contents of csv file and store values in an array to be manipulated by other functions
181
+	 * @access public
182
+	 * @param string  $path_to_file         - the csv file to be imported including the path to it's location.
183
+	 *                                      If $model_name is provided, assumes that each row in the CSV represents a
184
+	 *                                      model object for that model If $model_name ISN'T provided, assumes that
185
+	 *                                      before model object data, there is a row where the first entry is simply
186
+	 *                                      'MODEL', and next entry is the model's name, (untranslated) like Event, and
187
+	 *                                      then maybe a row of headers, and then the model data. Eg.
188
+	 *                                      '<br>MODEL,Event,<br>EVT_ID,EVT_name,...<br>1,Monkey
189
+	 *                                      Party,...<br>2,Llamarama,...<br>MODEL,Venue,<br>VNU_ID,VNU_name<br>1,The
190
+	 *                                      Forest
191
+	 * @param string  $model_name           model name if we know what model we're importing
192
+	 * @param boolean $first_row_is_headers - whether the first row of data is headers or not - TRUE = headers, FALSE =
193
+	 *                                      data
194
+	 * @return mixed - array on success - multi dimensional with headers as keys (if headers exist) OR string on fail -
195
+	 *               error message like the following array('Event'=>array( array('EVT_ID'=>1,'EVT_name'=>'bob
196
+	 *               party',...), array('EVT_ID'=>2,'EVT_name'=>'llamarama',...),
197
+	 *                                      ...
198
+	 *                                      )
199
+	 *                                      'Venue'=>array(
200
+	 *                                      array('VNU_ID'=>1,'VNU_name'=>'the shack',...),
201
+	 *                                      array('VNU_ID'=>2,'VNU_name'=>'tree house',...),
202
+	 *                                      ...
203
+	 *                                      )
204
+	 *                                      ...
205
+	 *                                      )
206
+	 */
207
+	public function import_csv_to_model_data_array($path_to_file, $model_name = false, $first_row_is_headers = true)
208
+	{
209
+		$multi_dimensional_array = $this->import_csv_to_multi_dimensional_array($path_to_file);
210
+		if (! $multi_dimensional_array) {
211
+			return false;
212
+		}
213
+		// gotta start somewhere
214
+		$row = 1;
215
+		// array to store csv data in
216
+		$ee_formatted_data = array();
217
+		// array to store headers (column names)
218
+		$headers = array();
219
+		foreach ($multi_dimensional_array as $data) {
220
+			// if first cell is MODEL, then second cell is the MODEL name
221
+			if ($data[0] == 'MODEL') {
222
+				$model_name = $data[1];
223
+				// don't bother looking for model data in this row. The rest of this
224
+				// row should be blank
225
+				// AND pretend this is the first row again
226
+				$row = 1;
227
+				// reset headers
228
+				$headers = array();
229
+				continue;
230
+			}
231
+			if (strpos($data[0], EE_CSV::metadata_header) !== false) {
232
+				$model_name = EE_CSV::metadata_header;
233
+				// store like model data, we just won't try importing it etc.
234
+				$row = 1;
235
+				continue;
236
+			}
237
+
238
+
239
+			// how many columns are there?
240
+			$columns = count($data);
241
+
242
+			$model_entry = array();
243
+			// loop through each column
244
+			for ($i = 0; $i < $columns; $i++) {
245
+				// replace csv_enclosures with backslashed quotes
246
+				$data[ $i ] = str_replace('"""', '\\"', $data[ $i ]);
247
+				// do we need to grab the column names?
248
+				if ($row === 1) {
249
+					if ($first_row_is_headers) {
250
+						// store the column names to use for keys
251
+						$column_name = $data[ $i ];
252
+						// check it's not blank... sometimes CSV editign programs adda bunch of empty columns onto the end...
253
+						if (! $column_name) {
254
+							continue;
255
+						}
256
+						$matches = array();
257
+						if ($model_name == EE_CSV::metadata_header) {
258
+							$headers[ $i ] = $column_name;
259
+						} else {
260
+							// now get the db table name from it (the part between square brackets)
261
+							$success = preg_match('~(.*)\[(.*)\]~', $column_name, $matches);
262
+							if (! $success) {
263
+								EE_Error::add_error(
264
+									sprintf(
265
+										__(
266
+											"The column titled %s is invalid for importing. It must be be in the format of 'Nice Name[model_field_name]' in row %s",
267
+											"event_espresso"
268
+										),
269
+										$column_name,
270
+										implode(",", $data)
271
+									),
272
+									__FILE__,
273
+									__FUNCTION__,
274
+									__LINE__
275
+								);
276
+								return false;
277
+							}
278
+							$headers[ $i ] = $matches[2];
279
+						}
280
+					} else {
281
+						// no column names means our final array will just use counters for keys
282
+						$model_entry[ $headers[ $i ] ] = $data[ $i ];
283
+						$headers[ $i ] = $i;
284
+					}
285
+					// and we need to store csv data
286
+				} else {
287
+					// this column isn' ta header, store it if there is a header for it
288
+					if (isset($headers[ $i ])) {
289
+						$model_entry[ $headers[ $i ] ] = $data[ $i ];
290
+					}
291
+				}
292
+			}
293
+			// save the row's data IF it's a non-header-row
294
+			if (! $first_row_is_headers || ($first_row_is_headers && $row > 1)) {
295
+				$ee_formatted_data[ $model_name ][] = $model_entry;
296
+			}
297
+			// advance to next row
298
+			$row++;
299
+		}
300
+
301
+		// delete the uploaded file
302
+		unlink($path_to_file);
303
+		// 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>';
304
+		// die();
305
+
306
+		// it's good to give back
307
+		return $ee_formatted_data;
308
+	}
309
+
310
+
311
+	public function save_csv_to_db($csv_data_array, $model_name = false)
312
+	{
313
+		EE_Error::doing_it_wrong(
314
+			'save_csv_to_db',
315
+			__(
316
+				'Function moved to EE_Import and renamed to save_csv_data_array_to_db',
317
+				'event_espresso'
318
+			),
319
+			'4.6.7'
320
+		);
321
+		return EE_Import::instance()->save_csv_data_array_to_db($csv_data_array, $model_name);
322
+	}
323
+
324
+	/**
325
+	 * Sends HTTP headers to indicate that the browser should download a file,
326
+	 * and starts writing the file to PHP's output. Returns the file handle so other functions can
327
+	 * also write to it
328
+	 *
329
+	 * @param string $new_filename the name of the file that the user will download
330
+	 * @return resource, like the results of fopen(), which can be used for fwrite, fputcsv2, etc.
331
+	 */
332
+	public function begin_sending_csv($filename)
333
+	{
334
+		// grab file extension
335
+		$ext = substr(strrchr($filename, '.'), 1);
336
+		if ($ext == '.csv' or $ext == '.xls') {
337
+			str_replace($ext, '', $filename);
338
+		}
339
+		$filename .= '.csv';
340
+
341
+		// if somebody's been naughty and already started outputting stuff, trash it
342
+		// and start writing our stuff.
343
+		if (ob_get_length()) {
344
+			@ob_flush();
345
+			@flush();
346
+			@ob_end_flush();
347
+		}
348
+		@ob_start();
349
+		header("Pragma: public");
350
+		header("Expires: 0");
351
+		header("Pragma: no-cache");
352
+		header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
353
+		// header("Content-Type: application/force-download");
354
+		// header("Content-Type: application/octet-stream");
355
+		// header("Content-Type: application/download");
356
+		header('Content-disposition: attachment; filename=' . $filename);
357
+		header("Content-Type: text/csv; charset=utf-8");
358
+		do_action('AHEE__EE_CSV__begin_sending_csv__headers');
359
+		echo apply_filters(
360
+			'FHEE__EE_CSV__begin_sending_csv__start_writing',
361
+			"\xEF\xBB\xBF"
362
+		); // makes excel open it as UTF-8. UTF-8 BOM, see http://stackoverflow.com/a/4440143/2773835
363
+		$fh = fopen('php://output', 'w');
364
+		return $fh;
365
+	}
366
+
367
+	/**
368
+	 * Writes some meta data to the CSV as a bunch of columns. Initially we're only
369
+	 * mentioning the version and timezone
370
+	 *
371
+	 * @param resource $filehandle
372
+	 */
373
+	public function write_metadata_to_csv($filehandle)
374
+	{
375
+		$data_row = array(EE_CSV::metadata_header);// do NOT translate because this exact string is used when importing
376
+		$this->fputcsv2($filehandle, $data_row);
377
+		$meta_data = array(
378
+			0 => array(
379
+				'version'        => espresso_version(),
380
+				'timezone'       => EEH_DTT_Helper::get_timezone(),
381
+				'time_of_export' => current_time('mysql'),
382
+				'site_url'       => site_url(),
383
+			),
384
+		);
385
+		$this->write_data_array_to_csv($filehandle, $meta_data);
386
+	}
387
+
388
+
389
+	/**
390
+	 * Writes $data to the csv file open in $filehandle. uses the array indices of $data for column headers
391
+	 *
392
+	 * @param array   $data                 2D array, first numerically-indexed, and next-level-down preferably indexed
393
+	 *                                      by string
394
+	 * @param boolean $add_csv_column_names whether or not we should add the keys in the bottom-most array as a row for
395
+	 *                                      headers in the CSV. Eg, if $data looked like
396
+	 *                                      array(0=>array('EVT_ID'=>1,'EVT_name'=>'monkey'...), 1=>array(...),...))
397
+	 *                                      then the first row we'd write to the CSV would be "EVT_ID,EVT_name,..."
398
+	 * @return boolean if we successfully wrote to the CSV or not. If there's no $data, we consider that a success
399
+	 *                 (because we wrote everything there was...nothing)
400
+	 */
401
+	public function write_data_array_to_csv($filehandle, $data)
402
+	{
403
+
404
+
405
+		// determine if $data is actually a 2d array
406
+		if ($data && is_array($data) && is_array(EEH_Array::get_one_item_from_array($data))) {
407
+			// make sure top level is numerically indexed,
408
+
409
+			if (EEH_Array::is_associative_array($data)) {
410
+				throw new EE_Error(
411
+					sprintf(
412
+						__(
413
+							"top-level array must be numerically indexed. Does these look like numbers to you? %s",
414
+							"event_espresso"
415
+						),
416
+						implode(",", array_keys($data))
417
+					)
418
+				);
419
+			}
420
+			$item_in_top_level_array = EEH_Array::get_one_item_from_array($data);
421
+			// now, is the last item in the top-level array of $data an associative or numeric array?
422
+			if (EEH_Array::is_associative_array($item_in_top_level_array)) {
423
+				// its associative, so we want to output its keys as column headers
424
+				$keys = array_keys($item_in_top_level_array);
425
+				echo $this->fputcsv2($filehandle, $keys);
426
+			}
427
+			// start writing data
428
+			foreach ($data as $data_row) {
429
+				echo $this->fputcsv2($filehandle, $data_row);
430
+			}
431
+			return true;
432
+		} else {
433
+			// no data TO write... so we can assume that's a success
434
+			return true;
435
+		}
436
+		// //if 2nd level is indexed by strings, use those as csv column headers (ie, the first row)
437
+		//
438
+		//
439
+		// $no_table = TRUE;
440
+		//
441
+		// // loop through data and add each row to the file/stream as csv
442
+		// foreach ( $data as $model_name => $model_data ) {
443
+		// // test first row to see if it is data or a model name
444
+		// $model = EE_Registry::instance();->load_model($model_name);
445
+		// //if the model really exists,
446
+		// if ( $model ) {
447
+		//
448
+		// // we have a table name
449
+		// $no_table = FALSE;
450
+		//
451
+		// // put the tablename into an array cuz that's how fputcsv rolls
452
+		// $model_name_row = array( 'MODEL', $model_name );
453
+		//
454
+		// // add table name to csv output
455
+		// echo self::fputcsv2($filehandle, $model_name_row);
456
+		//
457
+		// // now get the rest of the data
458
+		// foreach ( $model_data as $row ) {
459
+		// // output the row
460
+		// echo self::fputcsv2($filehandle, $row);
461
+		// }
462
+		//
463
+		// }
464
+		//
465
+		// if ( $no_table ) {
466
+		// // no table so just put the data
467
+		// echo self::fputcsv2($filehandle, $model_data);
468
+		// }
469
+		//
470
+		// } // END OF foreach ( $data )
471
+	}
472
+
473
+	/**
474
+	 * Should be called after begin_sending_csv(), and one or more write_data_array_to_csv()s.
475
+	 * Calls exit to prevent polluting the CSV file with other junk
476
+	 *
477
+	 * @param resource $fh filehandle where we're writing the CSV to
478
+	 */
479
+	public function end_sending_csv($fh)
480
+	{
481
+		fclose($fh);
482
+		exit(0);
483
+	}
484
+
485
+	/**
486
+	 * Given an open file, writes all the model data to it in the format the importer expects.
487
+	 * Usually preceded by begin_sending_csv($filename), and followed by end_sending_csv($filehandle).
488
+	 *
489
+	 * @param resource $filehandle
490
+	 * @param array    $model_data_array is assumed to be a 3d array: 1st layer has keys of model names (eg 'Event'),
491
+	 *                                   next layer is numerically indexed to represent each model object (eg, each
492
+	 *                                   individual event), and the last layer has all the attributes o fthat model
493
+	 *                                   object (eg, the event's id, name, etc)
494
+	 * @return boolean success
495
+	 */
496
+	public function write_model_data_to_csv($filehandle, $model_data_array)
497
+	{
498
+		$this->write_metadata_to_csv($filehandle);
499
+		foreach ($model_data_array as $model_name => $model_instance_arrays) {
500
+			// first: output a special row stating the model
501
+			echo $this->fputcsv2($filehandle, array('MODEL', $model_name));
502
+			// if we have items to put in the CSV, do it normally
503
+
504
+			if (! empty($model_instance_arrays)) {
505
+				$this->write_data_array_to_csv($filehandle, $model_instance_arrays);
506
+			} else {
507
+				// echo "no data to write... so just write the headers";
508
+				// so there's actually NO model objects for that model.
509
+				// probably still want to show the columns
510
+				$model = EE_Registry::instance()->load_model($model_name);
511
+				$column_names = array();
512
+				foreach ($model->field_settings() as $field) {
513
+					$column_names[ $field->get_nicename() . "[" . $field->get_name() . "]" ] = null;
514
+				}
515
+				$this->write_data_array_to_csv($filehandle, array($column_names));
516
+			}
517
+		}
518
+	}
519
+
520
+	/**
521
+	 * Writes the CSV file to the output buffer, with rows corresponding to $model_data_array,
522
+	 * and dies (in order to avoid other plugins from messing up the csv output)
523
+	 *
524
+	 * @param string $filename         the filename you want to give the file
525
+	 * @param array  $model_data_array 3d array, as described in EE_CSV::write_model_data_to_csv()
526
+	 * @return bool | void writes CSV file to output and dies
527
+	 */
528
+	public function export_multiple_model_data_to_csv($filename, $model_data_array)
529
+	{
530
+		$filehandle = $this->begin_sending_csv($filename);
531
+		$this->write_model_data_to_csv($filehandle, $model_data_array);
532
+		$this->end_sending_csv($filehandle);
533
+	}
534
+
535
+	/**
536
+	 * @Export contents of an array to csv file
537
+	 * @access public
538
+	 * @param array  $data     - the array of data to be converted to csv and exported
539
+	 * @param string $filename - name for newly created csv file
540
+	 * @return TRUE on success, FALSE on fail
541
+	 */
542
+	public function export_array_to_csv($data = false, $filename = false)
543
+	{
544
+
545
+		// no data file?? get outta here
546
+		if (! $data or ! is_array($data) or empty($data)) {
547
+			return false;
548
+		}
549
+
550
+		// no filename?? get outta here
551
+		if (! $filename) {
552
+			return false;
553
+		}
554
+
555
+
556
+		// somebody told me i might need this ???
557
+		global $wpdb;
558
+		$prefix = $wpdb->prefix;
559
+
560
+
561
+		$fh = $this->begin_sending_csv($filename);
562
+
563
+
564
+		$this->end_sending_csv($fh);
565
+	}
566
+
567
+
568
+	/**
569
+	 * @Determine the maximum upload file size based on php.ini settings
570
+	 * @access    public
571
+	 * @param int $percent_of_max - desired percentage of the max upload_mb
572
+	 * @return int KB
573
+	 */
574
+	public function get_max_upload_size($percent_of_max = false)
575
+	{
576
+
577
+		$max_upload = (int) (ini_get('upload_max_filesize'));
578
+		$max_post = (int) (ini_get('post_max_size'));
579
+		$memory_limit = (int) (ini_get('memory_limit'));
580
+
581
+		// determine the smallest of the three values from above
582
+		$upload_mb = min($max_upload, $max_post, $memory_limit);
583
+
584
+		// convert MB to KB
585
+		$upload_mb = $upload_mb * 1024;
586
+
587
+		// don't want the full monty? then reduce the max uplaod size
588
+		if ($percent_of_max) {
589
+			// is percent_of_max like this -> 50 or like this -> 0.50 ?
590
+			if ($percent_of_max > 1) {
591
+				// chnages 50 to 0.50
592
+				$percent_of_max = $percent_of_max / 100;
593
+			}
594
+			// make upload_mb a percentage of the max upload_mb
595
+			$upload_mb = $upload_mb * $percent_of_max;
596
+		}
597
+
598
+		return $upload_mb;
599
+	}
600
+
601
+
602
+	/**
603
+	 * @Drop   in replacement for PHP's fputcsv function - but this one works!!!
604
+	 * @access private
605
+	 * @param resource $fh         - file handle - what we are writing to
606
+	 * @param array    $row        - individual row of csv data
607
+	 * @param string   $delimiter  - csv delimiter
608
+	 * @param string   $enclosure  - csv enclosure
609
+	 * @param string   $mysql_null - allows php NULL to be overridden with MySQl's insertable NULL value
610
+	 * @return void
611
+	 */
612
+	private function fputcsv2($fh, array $row, $delimiter = ',', $enclosure = '"', $mysql_null = false)
613
+	{
614
+		// Allow user to filter the csv delimiter and enclosure for other countries csv standards
615
+		$delimiter = apply_filters('FHEE__EE_CSV__fputcsv2__delimiter', $delimiter);
616
+		$enclosure = apply_filters('FHEE__EE_CSV__fputcsv2__enclosure', $enclosure);
617
+
618
+		$delimiter_esc = preg_quote($delimiter, '/');
619
+		$enclosure_esc = preg_quote($enclosure, '/');
620
+
621
+		$output = array();
622
+		foreach ($row as $field_value) {
623
+			if (is_object($field_value) || is_array($field_value)) {
624
+				$field_value = serialize($field_value);
625
+			}
626
+			if ($field_value === null && $mysql_null) {
627
+				$output[] = 'NULL';
628
+				continue;
629
+			}
630
+
631
+			$output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field_value) ?
632
+				($enclosure . str_replace($enclosure, $enclosure . $enclosure, $field_value) . $enclosure)
633
+				: $field_value;
634
+		}
635
+
636
+		fwrite($fh, join($delimiter, $output) . PHP_EOL);
637
+	}
638
+
639
+
640
+	// /**
641
+	//  * @CSV    Import / Export messages
642
+	//  * @access public
643
+	//  * @return void
644
+	//  */
645
+	// public function csv_admin_notices()
646
+	// {
647
+	//
648
+	//     // We play both kinds of music here! Country AND Western! - err... I mean, cycle through both types of notices
649
+	//     foreach (array('updates', 'errors') as $type) {
650
+	//
651
+	//         // if particular notice type is not empty, then "You've got Mail"
652
+	//         if (! empty($this->_notices[ $type ])) {
653
+	//
654
+	//             // is it an update or an error ?
655
+	//             $msg_class = $type == 'updates' ? 'updated' : 'error';
656
+	//             echo '<div id="message" class="' . $msg_class . '">';
657
+	//             // display each notice, however many that may be
658
+	//             foreach ($this->_notices[ $type ] as $message) {
659
+	//                 echo '<p>' . $message . '</p>';
660
+	//             }
661
+	//             // wrap it up
662
+	//             echo '</div>';
663
+	//         }
664
+	//     }
665
+	// }
666
+
667
+	/**
668
+	 * Gets the date format to use in teh csv. filterable
669
+	 *
670
+	 * @param string $current_format
671
+	 * @return string
672
+	 */
673
+	public function get_date_format_for_csv($current_format = null)
674
+	{
675
+		return apply_filters('FHEE__EE_CSV__get_date_format_for_csv__format', 'Y-m-d', $current_format);
676
+	}
677
+
678
+	/**
679
+	 * Gets the time format we want to use in CSV reports. Filterable
680
+	 *
681
+	 * @param string $current_format
682
+	 * @return string
683
+	 */
684
+	public function get_time_format_for_csv($current_format = null)
685
+	{
686
+		return apply_filters('FHEE__EE_CSV__get_time_format_for_csv__format', 'H:i:s', $current_format);
687
+	}
688 688
 }
Please login to merge, or discard this patch.
Spacing   +48 added lines, -48 removed lines patch added patch discarded remove patch
@@ -48,31 +48,31 @@  discard block
 block discarded – undo
48 48
         global $wpdb;
49 49
 
50 50
         $this->_primary_keys = array(
51
-            $wpdb->prefix . 'esp_answer'                  => array('ANS_ID'),
52
-            $wpdb->prefix . 'esp_attendee'                => array('ATT_ID'),
53
-            $wpdb->prefix . 'esp_datetime'                => array('DTT_ID'),
54
-            $wpdb->prefix . 'esp_event_question_group'    => array('EQG_ID'),
55
-            $wpdb->prefix . 'esp_message_template'        => array('MTP_ID'),
56
-            $wpdb->prefix . 'esp_payment'                 => array('PAY_ID'),
57
-            $wpdb->prefix . 'esp_price'                   => array('PRC_ID'),
58
-            $wpdb->prefix . 'esp_price_type'              => array('PRT_ID'),
59
-            $wpdb->prefix . 'esp_question'                => array('QST_ID'),
60
-            $wpdb->prefix . 'esp_question_group'          => array('QSG_ID'),
61
-            $wpdb->prefix . 'esp_question_group_question' => array('QGQ_ID'),
62
-            $wpdb->prefix . 'esp_question_option'         => array('QSO_ID'),
63
-            $wpdb->prefix . 'esp_registration'            => array('REG_ID'),
64
-            $wpdb->prefix . 'esp_status'                  => array('STS_ID'),
65
-            $wpdb->prefix . 'esp_transaction'             => array('TXN_ID'),
66
-            $wpdb->prefix . 'esp_transaction'             => array('TXN_ID'),
67
-            $wpdb->prefix . 'events_detail'               => array('id'),
68
-            $wpdb->prefix . 'events_category_detail'      => array('id'),
69
-            $wpdb->prefix . 'events_category_rel'         => array('id'),
70
-            $wpdb->prefix . 'events_venue'                => array('id'),
71
-            $wpdb->prefix . 'events_venue_rel'            => array('emeta_id'),
72
-            $wpdb->prefix . 'events_locale'               => array('id'),
73
-            $wpdb->prefix . 'events_locale_rel'           => array('id'),
74
-            $wpdb->prefix . 'events_personnel'            => array('id'),
75
-            $wpdb->prefix . 'events_personnel_rel'        => array('id'),
51
+            $wpdb->prefix.'esp_answer'                  => array('ANS_ID'),
52
+            $wpdb->prefix.'esp_attendee'                => array('ATT_ID'),
53
+            $wpdb->prefix.'esp_datetime'                => array('DTT_ID'),
54
+            $wpdb->prefix.'esp_event_question_group'    => array('EQG_ID'),
55
+            $wpdb->prefix.'esp_message_template'        => array('MTP_ID'),
56
+            $wpdb->prefix.'esp_payment'                 => array('PAY_ID'),
57
+            $wpdb->prefix.'esp_price'                   => array('PRC_ID'),
58
+            $wpdb->prefix.'esp_price_type'              => array('PRT_ID'),
59
+            $wpdb->prefix.'esp_question'                => array('QST_ID'),
60
+            $wpdb->prefix.'esp_question_group'          => array('QSG_ID'),
61
+            $wpdb->prefix.'esp_question_group_question' => array('QGQ_ID'),
62
+            $wpdb->prefix.'esp_question_option'         => array('QSO_ID'),
63
+            $wpdb->prefix.'esp_registration'            => array('REG_ID'),
64
+            $wpdb->prefix.'esp_status'                  => array('STS_ID'),
65
+            $wpdb->prefix.'esp_transaction'             => array('TXN_ID'),
66
+            $wpdb->prefix.'esp_transaction'             => array('TXN_ID'),
67
+            $wpdb->prefix.'events_detail'               => array('id'),
68
+            $wpdb->prefix.'events_category_detail'      => array('id'),
69
+            $wpdb->prefix.'events_category_rel'         => array('id'),
70
+            $wpdb->prefix.'events_venue'                => array('id'),
71
+            $wpdb->prefix.'events_venue_rel'            => array('emeta_id'),
72
+            $wpdb->prefix.'events_locale'               => array('id'),
73
+            $wpdb->prefix.'events_locale_rel'           => array('id'),
74
+            $wpdb->prefix.'events_personnel'            => array('id'),
75
+            $wpdb->prefix.'events_personnel_rel'        => array('id'),
76 76
         );
77 77
     }
78 78
 
@@ -104,7 +104,7 @@  discard block
 block discarded – undo
104 104
     {
105 105
         $fc = "";
106 106
         $fh = fopen($file_path, "rb");
107
-        if (! $fh) {
107
+        if ( ! $fh) {
108 108
             throw new EE_Error(sprintf(__("Cannot open file for read: %s<br>\n", 'event_espresso'), $file_path));
109 109
         }
110 110
         $flen = filesize($file_path);
@@ -112,7 +112,7 @@  discard block
 block discarded – undo
112 112
         for ($i = 0; $i < $flen; $i++) {
113 113
             $c = substr($bc, $i, 1);
114 114
             if ((ord($c) != 0) && (ord($c) != 13)) {
115
-                $fc = $fc . $c;
115
+                $fc = $fc.$c;
116 116
             }
117 117
         }
118 118
         if ((ord(substr($fc, 0, 1)) == 255) && (ord(substr($fc, 1, 1)) == 254)) {
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
     public function import_csv_to_model_data_array($path_to_file, $model_name = false, $first_row_is_headers = true)
208 208
     {
209 209
         $multi_dimensional_array = $this->import_csv_to_multi_dimensional_array($path_to_file);
210
-        if (! $multi_dimensional_array) {
210
+        if ( ! $multi_dimensional_array) {
211 211
             return false;
212 212
         }
213 213
         // gotta start somewhere
@@ -243,23 +243,23 @@  discard block
 block discarded – undo
243 243
             // loop through each column
244 244
             for ($i = 0; $i < $columns; $i++) {
245 245
                 // replace csv_enclosures with backslashed quotes
246
-                $data[ $i ] = str_replace('"""', '\\"', $data[ $i ]);
246
+                $data[$i] = str_replace('"""', '\\"', $data[$i]);
247 247
                 // do we need to grab the column names?
248 248
                 if ($row === 1) {
249 249
                     if ($first_row_is_headers) {
250 250
                         // store the column names to use for keys
251
-                        $column_name = $data[ $i ];
251
+                        $column_name = $data[$i];
252 252
                         // check it's not blank... sometimes CSV editign programs adda bunch of empty columns onto the end...
253
-                        if (! $column_name) {
253
+                        if ( ! $column_name) {
254 254
                             continue;
255 255
                         }
256 256
                         $matches = array();
257 257
                         if ($model_name == EE_CSV::metadata_header) {
258
-                            $headers[ $i ] = $column_name;
258
+                            $headers[$i] = $column_name;
259 259
                         } else {
260 260
                             // now get the db table name from it (the part between square brackets)
261 261
                             $success = preg_match('~(.*)\[(.*)\]~', $column_name, $matches);
262
-                            if (! $success) {
262
+                            if ( ! $success) {
263 263
                                 EE_Error::add_error(
264 264
                                     sprintf(
265 265
                                         __(
@@ -275,24 +275,24 @@  discard block
 block discarded – undo
275 275
                                 );
276 276
                                 return false;
277 277
                             }
278
-                            $headers[ $i ] = $matches[2];
278
+                            $headers[$i] = $matches[2];
279 279
                         }
280 280
                     } else {
281 281
                         // no column names means our final array will just use counters for keys
282
-                        $model_entry[ $headers[ $i ] ] = $data[ $i ];
283
-                        $headers[ $i ] = $i;
282
+                        $model_entry[$headers[$i]] = $data[$i];
283
+                        $headers[$i] = $i;
284 284
                     }
285 285
                     // and we need to store csv data
286 286
                 } else {
287 287
                     // this column isn' ta header, store it if there is a header for it
288
-                    if (isset($headers[ $i ])) {
289
-                        $model_entry[ $headers[ $i ] ] = $data[ $i ];
288
+                    if (isset($headers[$i])) {
289
+                        $model_entry[$headers[$i]] = $data[$i];
290 290
                     }
291 291
                 }
292 292
             }
293 293
             // save the row's data IF it's a non-header-row
294
-            if (! $first_row_is_headers || ($first_row_is_headers && $row > 1)) {
295
-                $ee_formatted_data[ $model_name ][] = $model_entry;
294
+            if ( ! $first_row_is_headers || ($first_row_is_headers && $row > 1)) {
295
+                $ee_formatted_data[$model_name][] = $model_entry;
296 296
             }
297 297
             // advance to next row
298 298
             $row++;
@@ -353,7 +353,7 @@  discard block
 block discarded – undo
353 353
         // header("Content-Type: application/force-download");
354 354
         // header("Content-Type: application/octet-stream");
355 355
         // header("Content-Type: application/download");
356
-        header('Content-disposition: attachment; filename=' . $filename);
356
+        header('Content-disposition: attachment; filename='.$filename);
357 357
         header("Content-Type: text/csv; charset=utf-8");
358 358
         do_action('AHEE__EE_CSV__begin_sending_csv__headers');
359 359
         echo apply_filters(
@@ -372,7 +372,7 @@  discard block
 block discarded – undo
372 372
      */
373 373
     public function write_metadata_to_csv($filehandle)
374 374
     {
375
-        $data_row = array(EE_CSV::metadata_header);// do NOT translate because this exact string is used when importing
375
+        $data_row = array(EE_CSV::metadata_header); // do NOT translate because this exact string is used when importing
376 376
         $this->fputcsv2($filehandle, $data_row);
377 377
         $meta_data = array(
378 378
             0 => array(
@@ -501,7 +501,7 @@  discard block
 block discarded – undo
501 501
             echo $this->fputcsv2($filehandle, array('MODEL', $model_name));
502 502
             // if we have items to put in the CSV, do it normally
503 503
 
504
-            if (! empty($model_instance_arrays)) {
504
+            if ( ! empty($model_instance_arrays)) {
505 505
                 $this->write_data_array_to_csv($filehandle, $model_instance_arrays);
506 506
             } else {
507 507
                 // echo "no data to write... so just write the headers";
@@ -510,7 +510,7 @@  discard block
 block discarded – undo
510 510
                 $model = EE_Registry::instance()->load_model($model_name);
511 511
                 $column_names = array();
512 512
                 foreach ($model->field_settings() as $field) {
513
-                    $column_names[ $field->get_nicename() . "[" . $field->get_name() . "]" ] = null;
513
+                    $column_names[$field->get_nicename()."[".$field->get_name()."]"] = null;
514 514
                 }
515 515
                 $this->write_data_array_to_csv($filehandle, array($column_names));
516 516
             }
@@ -543,12 +543,12 @@  discard block
 block discarded – undo
543 543
     {
544 544
 
545 545
         // no data file?? get outta here
546
-        if (! $data or ! is_array($data) or empty($data)) {
546
+        if ( ! $data or ! is_array($data) or empty($data)) {
547 547
             return false;
548 548
         }
549 549
 
550 550
         // no filename?? get outta here
551
-        if (! $filename) {
551
+        if ( ! $filename) {
552 552
             return false;
553 553
         }
554 554
 
@@ -629,11 +629,11 @@  discard block
 block discarded – undo
629 629
             }
630 630
 
631 631
             $output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field_value) ?
632
-                ($enclosure . str_replace($enclosure, $enclosure . $enclosure, $field_value) . $enclosure)
632
+                ($enclosure.str_replace($enclosure, $enclosure.$enclosure, $field_value).$enclosure)
633 633
                 : $field_value;
634 634
         }
635 635
 
636
-        fwrite($fh, join($delimiter, $output) . PHP_EOL);
636
+        fwrite($fh, join($delimiter, $output).PHP_EOL);
637 637
     }
638 638
 
639 639
 
Please login to merge, or discard this patch.