Completed
Branch BUG/fatal-with-paypal-debug-li... (3a6198)
by
unknown
17:52 queued 09:26
created

EEM_Payment_Method::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 90

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 90
rs 8.2181
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
use EventEspresso\core\domain\entities\notifications\PersistentAdminNotice;
4
use EventEspresso\core\exceptions\InvalidDataTypeException;
5
6
/**
7
 * Payment Method Model
8
 * For storing all payment methods (things that interact between EE and gateways).
9
 * As of 4.3, payment methods are NOT singletons so there can be multiple instances of payment methods
10
 * of the same type, with different details. Eg, multiple paypal standard gateways so different
11
 * events can have their proceeds going to different paypal accounts
12
 *
13
 * @package    Event Espresso
14
 * @subpackage includes/models/EEM_Checkin.model.php
15
 * @author     Mike Nelson
16
 */
17
class EEM_Payment_Method extends EEM_Base
18
{
19
20
    const scope_cart = 'CART';
21
22
    const scope_admin = 'ADMIN';
23
24
    const scope_api = 'API';
25
26
    /**
27
     * @type EEM_Payment_Method
28
     */
29
    protected static $_instance = null;
30
31
32
    /**
33
     * private constructor to prevent direct creation
34
     *
35
     * @param null $timezone
36
     * @throws EE_Error
37
     */
38
    protected function __construct($timezone = null)
39
    {
40
        $this->singular_item = esc_html__('Payment Method', 'event_espresso');
41
        $this->plural_item = esc_html__('Payment Methods', 'event_espresso');
42
        $this->_tables = [
43
            'Payment_Method' => new EE_Primary_Table('esp_payment_method', 'PMD_ID'),
44
        ];
45
        $this->_fields = [
46
            'Payment_Method' => [
47
                'PMD_ID'              => new EE_Primary_Key_Int_Field(
48
                    'PMD_ID',
49
                    esc_html__('ID', 'event_espresso')
50
                ),
51
                'PMD_type'            => new EE_Plain_Text_Field(
52
                    'PMD_type',
53
                    esc_html__('Payment Method Type', 'event_espresso'),
54
                    false,
55
                    'Admin_Only'
56
                ),
57
                'PMD_name'            => new EE_Plain_Text_Field(
58
                    'PMD_name',
59
                    esc_html__('Name', 'event_espresso'),
60
                    false
61
                ),
62
                'PMD_desc'            => new EE_Post_Content_Field(
63
                    'PMD_desc',
64
                    esc_html__('Description', 'event_espresso'),
65
                    false,
66
                    ''
67
                ),
68
                'PMD_admin_name'      => new EE_Plain_Text_Field(
69
                    'PMD_admin_name',
70
                    esc_html__('Admin-Only Name', 'event_espresso'),
71
                    true
72
                ),
73
                'PMD_admin_desc'      => new EE_Post_Content_Field(
74
                    'PMD_admin_desc',
75
                    esc_html__('Admin-Only Description', 'event_espresso'),
76
                    true
77
                ),
78
                'PMD_slug'            => new EE_Slug_Field(
79
                    'PMD_slug',
80
                    esc_html__('Slug', 'event_espresso'),
81
                    false
82
                ),
83
                'PMD_order'           => new EE_Integer_Field(
84
                    'PMD_order',
85
                    esc_html__('Order', 'event_espresso'),
86
                    false,
87
                    0
88
                ),
89
                'PMD_debug_mode'      => new EE_Boolean_Field(
90
                    'PMD_debug_mode',
91
                    esc_html__('Debug Mode On?', 'event_espresso'),
92
                    false,
93
                    false
94
                ),
95
                'PMD_wp_user'         => new EE_WP_User_Field(
96
                    'PMD_wp_user',
97
                    esc_html__('Payment Method Creator ID', 'event_espresso'),
98
                    false
99
                ),
100
                'PMD_open_by_default' => new EE_Boolean_Field(
101
                    'PMD_open_by_default',
102
                    esc_html__('Open by Default?', 'event_espresso'),
103
                    false,
104
                    false
105
                ),
106
                'PMD_button_url'      => new EE_Plain_Text_Field(
107
                    'PMD_button_url',
108
                    esc_html__('Button URL', 'event_espresso'),
109
                    true,
110
                    ''
111
                ),
112
                'PMD_scope'           => new EE_Serialized_Text_Field(
113
                    'PMD_scope',
114
                    esc_html__('Usable From?', 'event_espresso'),
115
                    false,
116
                    []// possible values currently are 'CART','ADMIN','API'
117
                ),
118
            ],
119
        ];
120
        $this->_model_relations = [
121
            'Payment'     => new EE_Has_Many_Relation(),
122
            'Currency'    => new EE_HABTM_Relation('Currency_Payment_Method'),
123
            'Transaction' => new EE_Has_Many_Relation(),
124
            'WP_User'     => new EE_Belongs_To_Relation(),
125
        ];
126
        parent::__construct($timezone);
127
    }
128
129
130
    /**
131
     * Gets one by the slug provided
132
     *
133
     * @param string $slug
134
     * @return EE_Base_Class|EE_Payment_Method|EE_Soft_Delete_Base_Class|NULL
135
     * @throws EE_Error
136
     */
137
    public function get_one_by_slug($slug)
138
    {
139
        return $this->get_one([['PMD_slug' => $slug]]);
140
    }
141
142
143
    /**
144
     * Gets all the acceptable scopes for payment methods.
145
     * Keys are their names as store din the DB, and values are nice names for displaying them
146
     *
147
     * @return array
148
     */
149
    public function scopes()
150
    {
151
        return apply_filters(
152
            'FHEE__EEM_Payment_Method__scopes',
153
            [
154
                EEM_Payment_Method::scope_cart  => esc_html__('Front-end Registration Page', 'event_espresso'),
155
                EEM_Payment_Method::scope_admin => esc_html__(
156
                    'Admin Registration Page (no online processing)',
157
                    'event_espresso'
158
                ),
159
            ]
160
        );
161
    }
162
163
164
    /**
165
     * Determines if this is an valid scope
166
     *
167
     * @param string $scope like one of EEM_Payment_Method::instance()->scopes()
168
     * @return boolean
169
     */
170
    public function is_valid_scope($scope)
171
    {
172
        $scopes = $this->scopes();
173
        if (isset($scopes[ $scope ])) {
174
            return true;
175
        }
176
        return false;
177
    }
178
179
180
    /**
181
     * Gets all active payment methods
182
     *
183
     * @param string $scope one of
184
     * @param array  $query_params
185
     * @return EE_Base_Class[]|EE_Payment_Method[]
186
     * @throws EE_Error
187
     */
188
    public function get_all_active($scope = null, $query_params = [])
189
    {
190
        if (! isset($query_params['order_by']) && ! isset($query_params['order'])) {
191
            $query_params['order_by'] = ['PMD_order' => 'ASC', 'PMD_ID' => 'ASC'];
192
        }
193
        return $this->get_all($this->_get_query_params_for_all_active($scope, $query_params));
194
    }
195
196
197
    /**
198
     * Counts all active gateways in the specified scope
199
     *
200
     * @param string $scope one of EEM_Payment_Method::scope_*
201
     * @param array  $query_params
202
     * @return int
203
     * @throws EE_Error
204
     */
205
    public function count_active($scope = null, $query_params = [])
206
    {
207
        return $this->count($this->_get_query_params_for_all_active($scope, $query_params));
208
    }
209
210
211
    /**
212
     * Creates the $query_params that can be passed into any EEM_Payment_Method as their $query_params
213
     * argument to get all active for a given scope
214
     *
215
     * @param string $scope one of the constants EEM_Payment_Method::scope_*
216
     * @param array  $query_params
217
     * @return array
218
     * @throws EE_Error
219
     * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
220
     */
221
    protected function _get_query_params_for_all_active($scope = null, $query_params = [])
222
    {
223
        if ($scope) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $scope of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
224
            if ($this->is_valid_scope($scope)) {
225
                return array_replace_recursive([['PMD_scope' => ['LIKE', "%$scope%"]]], $query_params);
226
            }
227
            throw new EE_Error(
228
                sprintf(
229
                    esc_html__("'%s' is not a valid scope for a payment method", 'event_espresso'),
230
                    $scope
231
                )
232
            );
233
        }
234
        $acceptable_scopes = [];
235
        $count = 0;
236
        foreach ($this->scopes() as $scope_name => $desc) {
237
            $count++;
238
            $acceptable_scopes[ 'PMD_scope*' . $count ] = ['LIKE', '%' . $scope_name . '%'];
239
        }
240
        return array_replace_recursive([['OR*active_scope' => $acceptable_scopes]], $query_params);
241
    }
242
243
244
    /**
245
     * Creates the $query_params that can be passed into any EEM_Payment_Method as their $query_params
246
     * argument to get all active for a given scope
247
     *
248
     * @param string $scope one of the constants EEM_Payment_Method::scope_*
249
     * @param array  $query_params
250
     * @return array
251
     * @throws EE_Error
252
     * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
253
     */
254
    public function get_query_params_for_all_active($scope = null, $query_params = [])
255
    {
256
        return $this->_get_query_params_for_all_active($scope, $query_params);
257
    }
258
259
260
    /**
261
     * Gets one active payment method. see @get_all_active for documentation
262
     *
263
     * @param string $scope
264
     * @param array  $query_params
265
     * @return EE_Base_Class|EE_Payment_Method|EE_Soft_Delete_Base_Class|NULL
266
     * @throws EE_Error
267
     */
268
    public function get_one_active($scope = null, $query_params = [])
269
    {
270
        return $this->get_one($this->_get_query_params_for_all_active($scope, $query_params));
271
    }
272
273
274
    /**
275
     * Gets one payment method of that type, regardless of whether its active or not
276
     *
277
     * @param string $type
278
     * @return EE_Base_Class|EE_Payment_Method|EE_Soft_Delete_Base_Class|NULL
279
     * @throws EE_Error
280
     */
281
    public function get_one_of_type($type)
282
    {
283
        return $this->get_one([['PMD_type' => $type]]);
284
    }
285
286
287
    /**
288
     * Overrides parent ot also check by the slug
289
     *
290
     * @param string|int|EE_Payment_Method $base_class_obj_or_id
291
     * @param boolean                      $ensure_is_in_db
292
     * @return EE_Base_Class|EE_Payment_Method|EE_Soft_Delete_Base_Class|int|string
293
     * @throws EE_Error
294
     * @see EEM_Base::ensure_is_obj()
295
     */
296
    public function ensure_is_obj($base_class_obj_or_id, $ensure_is_in_db = false)
297
    {
298
        // first: check if it's a slug
299
        if (is_string($base_class_obj_or_id)) {
300
            $obj = $this->get_one_by_slug($base_class_obj_or_id);
301
            if ($obj) {
302
                return $obj;
303
            }
304
        }
305
        // ok so it wasn't a slug we were passed. try the usual then (ie, it's an object or an ID)
306
        try {
307
            return parent::ensure_is_obj($base_class_obj_or_id, $ensure_is_in_db);
308
        } catch (EE_Error $e) {
309
            // handle it outside the catch
310
        }
311
        throw new EE_Error(
312
            sprintf(
313
                esc_html__("'%s' is neither a Payment Method ID, slug, nor object.", 'event_espresso'),
314
                $base_class_obj_or_id
315
            )
316
        );
317
    }
318
319
320
    /**
321
     * Gets the ID of this object, or if its a string finds the object's id
322
     * associated with that slug
323
     *
324
     * @param mixed $base_obj_or_id_or_slug
325
     * @return int
326
     * @throws EE_Error
327
     */
328
    public function ensure_is_ID($base_obj_or_id_or_slug)
329
    {
330
        if (is_string($base_obj_or_id_or_slug)) {
331
            // assume it's a slug
332
            $base_obj_or_id_or_slug = $this->get_one_by_slug($base_obj_or_id_or_slug);
333
        }
334
        return parent::ensure_is_ID($base_obj_or_id_or_slug);
335
    }
336
337
338
    /**
339
     * Verifies the button urls on all the passed payment methods have a valid button url.
340
     * If not, resets them to their default.
341
     *
342
     * @param EE_Payment_Method[] $payment_methods if NULL, defaults to all payment methods active in the cart
343
     * @throws EE_Error
344
     * @throws ReflectionException
345
     */
346
    public function verify_button_urls($payment_methods = null)
347
    {
348
        $payment_methods = is_array($payment_methods)
349
            ? $payment_methods
350
            : $this->get_all_active(EEM_Payment_Method::scope_cart);
351
        foreach ($payment_methods as $payment_method) {
352
            try {
353
                // If there is really no button URL at all, or if the button URLs still point to decaf folder even
354
                // though this is a caffeinated install, reset it to the default.
355
                $current_button_url = $payment_method->button_url();
356
                if (empty($current_button_url)
357
                    || (
358
                        strpos($current_button_url, 'decaf') !== false
359
                        && strpos($payment_method->type_obj()->default_button_url(), 'decaf') === false
360
                    )
361
                ) {
362
                    $payment_method->save(
363
                        [
364
                            'PMD_button_url' => $payment_method->type_obj()->default_button_url(),
365
                        ]
366
                    );
367
                }
368
            } catch (EE_Error $e) {
369
                $payment_method->deactivate();
370
            }
371
        }
372
    }
373
374
375
    /**
376
     * Overrides parent to not only turn wpdb results into EE_Payment_Method objects,
377
     * but also verifies the payment method type of each is a usable object. If not,
378
     * deactivate it, sets a notification, and deactivates it
379
     *
380
     * @param array $rows
381
     * @return EE_Payment_Method[]
382
     * @throws EE_Error
383
     * @throws InvalidDataTypeException
384
     * @throws ReflectionException
385
     */
386
    protected function _create_objects($rows = [])
387
    {
388
        EE_Registry::instance()->load_lib('Payment_Method_Manager');
389
        $payment_methods = parent::_create_objects($rows);
390
        /* @var $payment_methods EE_Payment_Method[] */
391
        $usable_payment_methods = [];
392
        foreach ($payment_methods as $key => $payment_method) {
393
            if (EE_Payment_Method_Manager::instance()->payment_method_type_exists($payment_method->type())) {
394
                $usable_payment_methods[ $key ] = $payment_method;
395
                // some payment methods enqueue their scripts in EE_PMT_*::__construct
396
                // which is kinda a no-no (just because it's being constructed doesn't mean we need to enqueue
397
                // its scripts). but for backwards-compat we should continue to do that
398
                $payment_method->type_obj();
399
            } elseif ($payment_method->active()) {
400
                // only deactivate and notify the admin if the payment is active somewhere
401
                $payment_method->deactivate();
402
                $payment_method->save();
403
                do_action(
404
                    'AHEE__EEM_Payment_Method___create_objects_auto_deactivated_payment_method',
405
                    $payment_method
406
                );
407
                new PersistentAdminNotice(
408
                    'auto-deactivated-' . $payment_method->type(),
409
                    sprintf(
410
                        esc_html__(
411
                            'The payment method %1$s was automatically deactivated because it appears its associated Event Espresso Addon was recently deactivated.%2$sIt can be reactivated on the %3$sPlugins admin page%4$s, then you can reactivate the payment method.',
412
                            'event_espresso'
413
                        ),
414
                        $payment_method->admin_name(),
415
                        '<br />',
416
                        '<a href="' . admin_url('plugins.php') . '">',
417
                        '</a>'
418
                    ),
419
                    true
420
                );
421
            }
422
        }
423
        return $usable_payment_methods;
424
    }
425
426
427
    /**
428
     * Gets all the payment methods which can be used for transaction
429
     * (according to the relations between payment methods and events, and
430
     * the currencies used for the transaction and their relation to payment methods)
431
     *
432
     * @param EE_Transaction $transaction
433
     * @param string         $scope @see EEM_Payment_Method::get_all_for_events
434
     * @return EE_Payment_Method[]
435
     * @throws EE_Error
436
     */
437
    public function get_all_for_transaction($transaction, $scope)
438
    {
439
        // give addons a chance to override what payment methods are chosen based on the transaction
440
        return apply_filters(
441
            'FHEE__EEM_Payment_Method__get_all_for_transaction__payment_methods',
442
            $this->get_all_active($scope, ['group_by' => 'PMD_type']),
443
            $transaction,
444
            $scope
445
        );
446
    }
447
448
449
    /**
450
     * Returns the payment method used for the last payment made for a registration.
451
     * Note: if an offline payment method was selected on the related transaction then this will have no payment
452
     * methods returned. It will ONLY return a payment method for a PAYMENT recorded against the registration.
453
     *
454
     * @param EE_Registration|int $registration_or_reg_id Either the EE_Registration object or the id for the
455
     *                                                    registration.
456
     * @return EE_Payment|null
457
     * @throws EE_Error
458
     */
459
    public function get_last_used_for_registration($registration_or_reg_id)
460
    {
461
        $registration_id = EEM_Registration::instance()->ensure_is_ID($registration_or_reg_id);
462
463
        $query_params = [
464
            0          => [
465
                'Payment.Registration.REG_ID' => $registration_id,
466
            ],
467
            'order_by' => ['Payment.PAY_ID' => 'DESC'],
468
        ];
469
        return $this->get_one($query_params);
470
    }
471
}
472