Completed
Branch Gutenberg/event-attendees-bloc... (dcb43c)
by
unknown
43:02 queued 34:56
created
core/services/container/CoffeeShop.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -361,7 +361,7 @@  discard block
 block discarded – undo
361 361
      * Adds instructions on how to brew objects
362 362
      *
363 363
      * @param RecipeInterface $recipe
364
-     * @return mixed
364
+     * @return boolean
365 365
      * @throws InvalidIdentifierException
366 366
      */
367 367
     public function addRecipe(RecipeInterface $recipe)
@@ -461,7 +461,7 @@  discard block
 block discarded – undo
461 461
     /**
462 462
      * Adds a service to one of the internal collections
463 463
      *
464
-     * @param        $identifier
464
+     * @param        string $identifier
465 465
      * @param array  $arguments
466 466
      * @param string $type
467 467
      * @return mixed
Please login to merge, or discard this patch.
Indentation   +565 added lines, -565 removed lines patch added patch discarded remove patch
@@ -30,569 +30,569 @@
 block discarded – undo
30 30
 {
31 31
 
32 32
 
33
-    /**
34
-     * This was the best coffee related name I could think of to represent class name "aliases"
35
-     * So classes can be found via an alias identifier,
36
-     * that is revealed when it is run through... the filters... eh? get it?
37
-     *
38
-     * @var array $filters
39
-     */
40
-    private $filters;
41
-
42
-    /**
43
-     * These are the classes that will actually build the objects (to order of course)
44
-     *
45
-     * @var array $coffee_makers
46
-     */
47
-    private $coffee_makers;
48
-
49
-    /**
50
-     * where the instantiated "singleton" objects are stored
51
-     *
52
-     * @var CollectionInterface $carafe
53
-     */
54
-    private $carafe;
55
-
56
-    /**
57
-     * collection of Recipes that instruct us how to brew objects
58
-     *
59
-     * @var CollectionInterface $recipes
60
-     */
61
-    private $recipes;
62
-
63
-    /**
64
-     * collection of closures for brewing objects
65
-     *
66
-     * @var CollectionInterface $reservoir
67
-     */
68
-    private $reservoir;
69
-
70
-
71
-    /**
72
-     * CoffeeShop constructor
73
-     *
74
-     * @throws InvalidInterfaceException
75
-     */
76
-    public function __construct()
77
-    {
78
-        // array for storing class aliases
79
-        $this->filters = array();
80
-        // create collection for storing shared services
81
-        $this->carafe = new LooseCollection('');
82
-        // create collection for storing recipes that tell us how to build services and entities
83
-        $this->recipes = new Collection('EventEspresso\core\services\container\RecipeInterface');
84
-        // create collection for storing closures for constructing new entities
85
-        $this->reservoir = new Collection('Closure');
86
-        // create collection for storing the generators that build our services and entity closures
87
-        $this->coffee_makers = new Collection('EventEspresso\core\services\container\CoffeeMakerInterface');
88
-    }
89
-
90
-
91
-    /**
92
-     * Returns true if the container can return an entry for the given identifier.
93
-     * Returns false otherwise.
94
-     * `has($identifier)` returning true does not mean that `get($identifier)` will not throw an exception.
95
-     * It does however mean that `get($identifier)` will not throw a `ServiceNotFoundException`.
96
-     *
97
-     * @param string $identifier  Identifier of the entry to look for.
98
-     *                            Typically a Fully Qualified Class Name
99
-     * @return boolean
100
-     * @throws InvalidIdentifierException
101
-     */
102
-    public function has($identifier)
103
-    {
104
-        $identifier = $this->filterIdentifier($identifier);
105
-        return $this->carafe->has($identifier);
106
-    }
107
-
108
-
109
-    /**
110
-     * finds a previously brewed (SHARED) service and returns it
111
-     *
112
-     * @param  string $identifier Identifier for the entity class to be constructed.
113
-     *                            Typically a Fully Qualified Class Name
114
-     * @return mixed
115
-     * @throws InvalidIdentifierException
116
-     * @throws ServiceNotFoundException No service was found for this identifier.
117
-     */
118
-    public function get($identifier)
119
-    {
120
-        $identifier = $this->filterIdentifier($identifier);
121
-        if ($this->carafe->has($identifier)) {
122
-            return $this->carafe->get($identifier);
123
-        }
124
-        throw new ServiceNotFoundException($identifier);
125
-    }
126
-
127
-
128
-    /**
129
-     * returns an instance of the requested entity type using the supplied arguments.
130
-     * If a shared service is requested and an instance is already in the carafe, then it will be returned.
131
-     * If it is not already in the carafe, then the service will be constructed, added to the carafe, and returned
132
-     * If the request is for a new entity and a closure exists in the reservoir for creating it,
133
-     * then a new entity will be instantiated from the closure and returned.
134
-     * If a closure does not exist, then one will be built and added to the reservoir
135
-     * before instantiating the requested entity.
136
-     *
137
-     * @param  string $identifier Identifier for the entity class to be constructed.
138
-     *                            Typically a Fully Qualified Class Name
139
-     * @param array   $arguments  an array of arguments to be passed to the entity constructor
140
-     * @param string  $type
141
-     * @return mixed
142
-     * @throws OutOfBoundsException
143
-     * @throws InstantiationException
144
-     * @throws InvalidDataTypeException
145
-     * @throws InvalidClassException
146
-     * @throws InvalidIdentifierException
147
-     * @throws ServiceExistsException
148
-     * @throws ServiceNotFoundException No service was found for this identifier.
149
-     */
150
-    public function brew($identifier, $arguments = array(), $type = '')
151
-    {
152
-        // resolve any class aliases that may exist
153
-        $identifier = $this->filterIdentifier($identifier);
154
-        // is a shared service being requested and already exists in the carafe?
155
-        $brewed = $this->getShared($identifier, $type);
156
-        // then return whatever was found
157
-        if ($brewed !== false) {
158
-            return $brewed;
159
-        }
160
-        // if the reservoir doesn't have a closure already for the requested identifier,
161
-        // then neither a shared service nor a closure for making entities has been built yet
162
-        if (! $this->reservoir->has($identifier)) {
163
-            // so let's brew something up and add it to the proper collection
164
-            $brewed = $this->makeCoffee($identifier, $arguments, $type);
165
-        }
166
-        // did the requested class only require loading, and if so, was that successful?
167
-        if ($this->brewedLoadOnly($brewed, $identifier, $type) === true) {
168
-            return true;
169
-        }
170
-        // was the brewed item a callable factory function ?
171
-        if (is_callable($brewed)) {
172
-            // then instantiate a new entity from the cached closure
173
-            return $brewed($arguments);
174
-        }
175
-        if ($brewed) {
176
-            // requested object was a shared entity, so attempt to get it from the carafe again
177
-            // because if it wasn't there before, then it should have just been brewed and added,
178
-            // but if it still isn't there, then this time the thrown ServiceNotFoundException will not be caught
179
-            return $this->get($identifier);
180
-        }
181
-        // if identifier is for a non-shared entity,
182
-        // then either a cached closure already existed, or was just brewed
183
-        return $this->brewedClosure($identifier, $arguments);
184
-    }
185
-
186
-
187
-    /**
188
-     * @param string $identifier
189
-     * @param string $type
190
-     * @return bool|mixed
191
-     * @throws InvalidIdentifierException
192
-     */
193
-    protected function getShared($identifier, $type)
194
-    {
195
-        try {
196
-            if (empty($type) || $type === CoffeeMaker::BREW_SHARED) {
197
-                // if a shared service was requested and an instance is in the carafe, then return it
198
-                return $this->get($identifier);
199
-            }
200
-        } catch (ServiceNotFoundException $e) {
201
-            // if not then we'll just catch the ServiceNotFoundException but not do anything just yet,
202
-            // and instead, attempt to build whatever was requested
203
-        }
204
-        return false;
205
-    }
206
-
207
-
208
-    /**
209
-     * @param mixed  $brewed
210
-     * @param string $identifier
211
-     * @param string $type
212
-     * @return bool
213
-     * @throws InvalidClassException
214
-     * @throws InvalidDataTypeException
215
-     * @throws InvalidIdentifierException
216
-     * @throws OutOfBoundsException
217
-     * @throws ServiceExistsException
218
-     * @throws ServiceNotFoundException
219
-     */
220
-    protected function brewedLoadOnly($brewed, $identifier, $type)
221
-    {
222
-        if ($type === CoffeeMaker::BREW_LOAD_ONLY) {
223
-            if ($brewed !== true) {
224
-                throw new ServiceNotFoundException(
225
-                    sprintf(
226
-                        esc_html__(
227
-                            'The "%1$s" class could not be loaded.',
228
-                            'event_espresso'
229
-                        ),
230
-                        $identifier
231
-                    )
232
-                );
233
-            }
234
-            return true;
235
-        }
236
-        return false;
237
-    }
238
-
239
-
240
-    /**
241
-     * @param string $identifier
242
-     * @param array  $arguments
243
-     * @return mixed
244
-     * @throws InstantiationException
245
-     */
246
-    protected function brewedClosure($identifier, array $arguments)
247
-    {
248
-        $closure = $this->reservoir->get($identifier);
249
-        if (empty($closure)) {
250
-            throw new InstantiationException(
251
-                sprintf(
252
-                    esc_html__(
253
-                        'Could not brew an instance of "%1$s".',
254
-                        'event_espresso'
255
-                    ),
256
-                    $identifier
257
-                )
258
-            );
259
-        }
260
-        return $closure($arguments);
261
-    }
262
-
263
-
264
-    /**
265
-     * @param CoffeeMakerInterface $coffee_maker
266
-     * @param string               $type
267
-     * @return bool
268
-     * @throws InvalidIdentifierException
269
-     * @throws InvalidEntityException
270
-     */
271
-    public function addCoffeeMaker(CoffeeMakerInterface $coffee_maker, $type)
272
-    {
273
-        $type = CoffeeMaker::validateType($type);
274
-        return $this->coffee_makers->add($coffee_maker, $type);
275
-    }
276
-
277
-
278
-    /**
279
-     * @param string   $identifier
280
-     * @param callable $closure
281
-     * @return callable|null
282
-     * @throws InvalidIdentifierException
283
-     * @throws InvalidDataTypeException
284
-     */
285
-    public function addClosure($identifier, $closure)
286
-    {
287
-        if (! is_callable($closure)) {
288
-            throw new InvalidDataTypeException('$closure', $closure, 'Closure');
289
-        }
290
-        $identifier = $this->processIdentifier($identifier);
291
-        if ($this->reservoir->add($closure, $identifier)) {
292
-            return $closure;
293
-        }
294
-        return null;
295
-    }
296
-
297
-
298
-    /**
299
-     * @param string $identifier
300
-     * @return boolean
301
-     * @throws InvalidIdentifierException
302
-     */
303
-    public function removeClosure($identifier)
304
-    {
305
-        $identifier = $this->processIdentifier($identifier);
306
-        if ($this->reservoir->has($identifier)) {
307
-            return $this->reservoir->remove($this->reservoir->get($identifier));
308
-        }
309
-        return false;
310
-    }
311
-
312
-
313
-    /**
314
-     * @param  string $identifier Identifier for the entity class that the service applies to
315
-     *                            Typically a Fully Qualified Class Name
316
-     * @param mixed   $service
317
-     * @return bool
318
-     * @throws \EventEspresso\core\services\container\exceptions\InvalidServiceException
319
-     * @throws InvalidIdentifierException
320
-     */
321
-    public function addService($identifier, $service)
322
-    {
323
-        $identifier = $this->processIdentifier($identifier);
324
-        $service = $this->validateService($identifier, $service);
325
-        return $this->carafe->add($service, $identifier);
326
-    }
327
-
328
-
329
-    /**
330
-     * @param string $identifier
331
-     * @return boolean
332
-     * @throws InvalidIdentifierException
333
-     */
334
-    public function removeService($identifier)
335
-    {
336
-        $identifier = $this->processIdentifier($identifier);
337
-        if ($this->carafe->has($identifier)) {
338
-            return $this->carafe->remove($this->carafe->get($identifier));
339
-        }
340
-        return false;
341
-    }
342
-
343
-
344
-    /**
345
-     * Adds instructions on how to brew objects
346
-     *
347
-     * @param RecipeInterface $recipe
348
-     * @return mixed
349
-     * @throws InvalidIdentifierException
350
-     */
351
-    public function addRecipe(RecipeInterface $recipe)
352
-    {
353
-        $this->addAliases($recipe->identifier(), $recipe->filters());
354
-        $identifier = $this->processIdentifier($recipe->identifier());
355
-        return $this->recipes->add($recipe, $identifier);
356
-    }
357
-
358
-
359
-    /**
360
-     * @param string $identifier The Recipe's identifier
361
-     * @return boolean
362
-     * @throws InvalidIdentifierException
363
-     */
364
-    public function removeRecipe($identifier)
365
-    {
366
-        $identifier = $this->processIdentifier($identifier);
367
-        if ($this->recipes->has($identifier)) {
368
-            return $this->recipes->remove($this->recipes->get($identifier));
369
-        }
370
-        return false;
371
-    }
372
-
373
-
374
-    /**
375
-     * Get instructions on how to brew objects
376
-     *
377
-     * @param  string $identifier Identifier for the entity class that the recipe applies to
378
-     *                            Typically a Fully Qualified Class Name
379
-     * @param string  $type
380
-     * @return RecipeInterface
381
-     * @throws OutOfBoundsException
382
-     * @throws InvalidIdentifierException
383
-     */
384
-    public function getRecipe($identifier, $type = '')
385
-    {
386
-        $identifier = $this->processIdentifier($identifier);
387
-        if ($this->recipes->has($identifier)) {
388
-            return $this->recipes->get($identifier);
389
-        }
390
-        $default_recipes = $this->getDefaultRecipes();
391
-        $matches = array();
392
-        foreach ($default_recipes as $wildcard => $default_recipe) {
393
-            // is the wildcard recipe prefix in the identifier ?
394
-            if (strpos($identifier, $wildcard) !== false) {
395
-                // track matches and use the number of wildcard characters matched for the key
396
-                $matches[ strlen($wildcard) ] = $default_recipe;
397
-            }
398
-        }
399
-        if (count($matches) > 0) {
400
-            // sort our recipes by the number of wildcard characters matched
401
-            ksort($matches);
402
-            // then grab the last recipe form the list, since it had the most matching characters
403
-            $match = array_pop($matches);
404
-            // since we are using a default recipe, we need to set it's identifier and fqcn
405
-            return $this->copyDefaultRecipe($match, $identifier, $type);
406
-        }
407
-        if ($this->recipes->has(Recipe::DEFAULT_ID)) {
408
-            // since we are using a default recipe, we need to set it's identifier and fqcn
409
-            return $this->copyDefaultRecipe($this->recipes->get(Recipe::DEFAULT_ID), $identifier, $type);
410
-        }
411
-        throw new OutOfBoundsException(
412
-            sprintf(
413
-                __('Could not brew coffee because no recipes were found for class "%1$s".', 'event_espresso'),
414
-                $identifier
415
-            )
416
-        );
417
-    }
418
-
419
-
420
-    /**
421
-     * adds class name aliases to list of filters
422
-     *
423
-     * @param  string       $identifier Identifier for the entity class that the alias applies to
424
-     *                                  Typically a Fully Qualified Class Name
425
-     * @param  array|string $aliases
426
-     * @return void
427
-     * @throws InvalidIdentifierException
428
-     */
429
-    public function addAliases($identifier, $aliases)
430
-    {
431
-        if (empty($aliases)) {
432
-            return;
433
-        }
434
-        $identifier = $this->processIdentifier($identifier);
435
-        foreach ((array) $aliases as $alias) {
436
-            $this->filters[ $this->processIdentifier($alias) ] = $identifier;
437
-        }
438
-    }
439
-
440
-
441
-    /**
442
-     * Adds a service to one of the internal collections
443
-     *
444
-     * @param        $identifier
445
-     * @param array  $arguments
446
-     * @param string $type
447
-     * @return mixed
448
-     * @throws InvalidDataTypeException
449
-     * @throws InvalidClassException
450
-     * @throws OutOfBoundsException
451
-     * @throws InvalidIdentifierException
452
-     * @throws ServiceExistsException
453
-     */
454
-    private function makeCoffee($identifier, $arguments = array(), $type = '')
455
-    {
456
-        if ((empty($type) || $type === CoffeeMaker::BREW_SHARED) && $this->has($identifier)) {
457
-            throw new ServiceExistsException($identifier);
458
-        }
459
-        $identifier = $this->filterIdentifier($identifier);
460
-        $recipe = $this->getRecipe($identifier, $type);
461
-        $type = ! empty($type) ? $type : $recipe->type();
462
-        $coffee_maker = $this->getCoffeeMaker($type);
463
-        return $coffee_maker->brew($recipe, $arguments);
464
-    }
465
-
466
-
467
-    /**
468
-     * filters alias identifiers to find the real class name
469
-     *
470
-     * @param  string $identifier Identifier for the entity class that the filter applies to
471
-     *                            Typically a Fully Qualified Class Name
472
-     * @return string
473
-     * @throws InvalidIdentifierException
474
-     */
475
-    private function filterIdentifier($identifier)
476
-    {
477
-        $identifier = $this->processIdentifier($identifier);
478
-        return isset($this->filters[ $identifier ]) && ! empty($this->filters[ $identifier ])
479
-            ? $this->filters[ $identifier ]
480
-            : $identifier;
481
-    }
482
-
483
-
484
-    /**
485
-     * verifies and standardizes identifiers
486
-     *
487
-     * @param  string $identifier Identifier for the entity class
488
-     *                            Typically a Fully Qualified Class Name
489
-     * @return string
490
-     * @throws InvalidIdentifierException
491
-     */
492
-    private function processIdentifier($identifier)
493
-    {
494
-        if (! is_string($identifier)) {
495
-            throw new InvalidIdentifierException(
496
-                is_object($identifier) ? get_class($identifier) : gettype($identifier),
497
-                '\Fully\Qualified\ClassName'
498
-            );
499
-        }
500
-        return ltrim($identifier, '\\');
501
-    }
502
-
503
-
504
-    /**
505
-     * @param string $type
506
-     * @return CoffeeMakerInterface
507
-     * @throws OutOfBoundsException
508
-     * @throws InvalidDataTypeException
509
-     * @throws InvalidClassException
510
-     */
511
-    private function getCoffeeMaker($type)
512
-    {
513
-        if (! $this->coffee_makers->has($type)) {
514
-            throw new OutOfBoundsException(
515
-                __('The requested coffee maker is either missing or invalid.', 'event_espresso')
516
-            );
517
-        }
518
-        return $this->coffee_makers->get($type);
519
-    }
520
-
521
-
522
-    /**
523
-     * Retrieves all recipes that use a wildcard "*" in their identifier
524
-     * This allows recipes to be set up for handling
525
-     * legacy classes that do not support PSR-4 autoloading.
526
-     * for example:
527
-     * using "EEM_*" for a recipe identifier would target all legacy models like EEM_Attendee
528
-     *
529
-     * @return array
530
-     */
531
-    private function getDefaultRecipes()
532
-    {
533
-        $default_recipes = array();
534
-        $this->recipes->rewind();
535
-        while ($this->recipes->valid()) {
536
-            $identifier = $this->recipes->getInfo();
537
-            // does this recipe use a wildcard ? (but is NOT the global default)
538
-            if ($identifier !== Recipe::DEFAULT_ID && strpos($identifier, '*') !== false) {
539
-                // strip the wildcard and use identifier as key
540
-                $default_recipes[ str_replace('*', '', $identifier) ] = $this->recipes->current();
541
-            }
542
-            $this->recipes->next();
543
-        }
544
-        return $default_recipes;
545
-    }
546
-
547
-
548
-    /**
549
-     * clones a default recipe and then copies details
550
-     * from the incoming request to it so that it can be used
551
-     *
552
-     * @param RecipeInterface $default_recipe
553
-     * @param string          $identifier
554
-     * @param string          $type
555
-     * @return RecipeInterface
556
-     */
557
-    private function copyDefaultRecipe(RecipeInterface $default_recipe, $identifier, $type = '')
558
-    {
559
-        $recipe = clone $default_recipe;
560
-        if (! empty($type)) {
561
-            $recipe->setType($type);
562
-        }
563
-        // is this the base default recipe ?
564
-        if ($default_recipe->identifier() === Recipe::DEFAULT_ID) {
565
-            $recipe->setIdentifier($identifier);
566
-            $recipe->setFqcn($identifier);
567
-            return $recipe;
568
-        }
569
-        $recipe->setIdentifier($identifier);
570
-        foreach ($default_recipe->paths() as $path) {
571
-            $path = str_replace('*', $identifier, $path);
572
-            if (is_readable($path)) {
573
-                $recipe->setPaths($path);
574
-            }
575
-        }
576
-        $recipe->setFqcn($identifier);
577
-        return $recipe;
578
-    }
579
-
580
-
581
-    /**
582
-     * @param  string $identifier Identifier for the entity class that the service applies to
583
-     *                            Typically a Fully Qualified Class Name
584
-     * @param mixed   $service
585
-     * @return mixed
586
-     * @throws InvalidServiceException
587
-     */
588
-    private function validateService($identifier, $service)
589
-    {
590
-        if (! is_object($service)) {
591
-            throw new InvalidServiceException(
592
-                $identifier,
593
-                $service
594
-            );
595
-        }
596
-        return $service;
597
-    }
33
+	/**
34
+	 * This was the best coffee related name I could think of to represent class name "aliases"
35
+	 * So classes can be found via an alias identifier,
36
+	 * that is revealed when it is run through... the filters... eh? get it?
37
+	 *
38
+	 * @var array $filters
39
+	 */
40
+	private $filters;
41
+
42
+	/**
43
+	 * These are the classes that will actually build the objects (to order of course)
44
+	 *
45
+	 * @var array $coffee_makers
46
+	 */
47
+	private $coffee_makers;
48
+
49
+	/**
50
+	 * where the instantiated "singleton" objects are stored
51
+	 *
52
+	 * @var CollectionInterface $carafe
53
+	 */
54
+	private $carafe;
55
+
56
+	/**
57
+	 * collection of Recipes that instruct us how to brew objects
58
+	 *
59
+	 * @var CollectionInterface $recipes
60
+	 */
61
+	private $recipes;
62
+
63
+	/**
64
+	 * collection of closures for brewing objects
65
+	 *
66
+	 * @var CollectionInterface $reservoir
67
+	 */
68
+	private $reservoir;
69
+
70
+
71
+	/**
72
+	 * CoffeeShop constructor
73
+	 *
74
+	 * @throws InvalidInterfaceException
75
+	 */
76
+	public function __construct()
77
+	{
78
+		// array for storing class aliases
79
+		$this->filters = array();
80
+		// create collection for storing shared services
81
+		$this->carafe = new LooseCollection('');
82
+		// create collection for storing recipes that tell us how to build services and entities
83
+		$this->recipes = new Collection('EventEspresso\core\services\container\RecipeInterface');
84
+		// create collection for storing closures for constructing new entities
85
+		$this->reservoir = new Collection('Closure');
86
+		// create collection for storing the generators that build our services and entity closures
87
+		$this->coffee_makers = new Collection('EventEspresso\core\services\container\CoffeeMakerInterface');
88
+	}
89
+
90
+
91
+	/**
92
+	 * Returns true if the container can return an entry for the given identifier.
93
+	 * Returns false otherwise.
94
+	 * `has($identifier)` returning true does not mean that `get($identifier)` will not throw an exception.
95
+	 * It does however mean that `get($identifier)` will not throw a `ServiceNotFoundException`.
96
+	 *
97
+	 * @param string $identifier  Identifier of the entry to look for.
98
+	 *                            Typically a Fully Qualified Class Name
99
+	 * @return boolean
100
+	 * @throws InvalidIdentifierException
101
+	 */
102
+	public function has($identifier)
103
+	{
104
+		$identifier = $this->filterIdentifier($identifier);
105
+		return $this->carafe->has($identifier);
106
+	}
107
+
108
+
109
+	/**
110
+	 * finds a previously brewed (SHARED) service and returns it
111
+	 *
112
+	 * @param  string $identifier Identifier for the entity class to be constructed.
113
+	 *                            Typically a Fully Qualified Class Name
114
+	 * @return mixed
115
+	 * @throws InvalidIdentifierException
116
+	 * @throws ServiceNotFoundException No service was found for this identifier.
117
+	 */
118
+	public function get($identifier)
119
+	{
120
+		$identifier = $this->filterIdentifier($identifier);
121
+		if ($this->carafe->has($identifier)) {
122
+			return $this->carafe->get($identifier);
123
+		}
124
+		throw new ServiceNotFoundException($identifier);
125
+	}
126
+
127
+
128
+	/**
129
+	 * returns an instance of the requested entity type using the supplied arguments.
130
+	 * If a shared service is requested and an instance is already in the carafe, then it will be returned.
131
+	 * If it is not already in the carafe, then the service will be constructed, added to the carafe, and returned
132
+	 * If the request is for a new entity and a closure exists in the reservoir for creating it,
133
+	 * then a new entity will be instantiated from the closure and returned.
134
+	 * If a closure does not exist, then one will be built and added to the reservoir
135
+	 * before instantiating the requested entity.
136
+	 *
137
+	 * @param  string $identifier Identifier for the entity class to be constructed.
138
+	 *                            Typically a Fully Qualified Class Name
139
+	 * @param array   $arguments  an array of arguments to be passed to the entity constructor
140
+	 * @param string  $type
141
+	 * @return mixed
142
+	 * @throws OutOfBoundsException
143
+	 * @throws InstantiationException
144
+	 * @throws InvalidDataTypeException
145
+	 * @throws InvalidClassException
146
+	 * @throws InvalidIdentifierException
147
+	 * @throws ServiceExistsException
148
+	 * @throws ServiceNotFoundException No service was found for this identifier.
149
+	 */
150
+	public function brew($identifier, $arguments = array(), $type = '')
151
+	{
152
+		// resolve any class aliases that may exist
153
+		$identifier = $this->filterIdentifier($identifier);
154
+		// is a shared service being requested and already exists in the carafe?
155
+		$brewed = $this->getShared($identifier, $type);
156
+		// then return whatever was found
157
+		if ($brewed !== false) {
158
+			return $brewed;
159
+		}
160
+		// if the reservoir doesn't have a closure already for the requested identifier,
161
+		// then neither a shared service nor a closure for making entities has been built yet
162
+		if (! $this->reservoir->has($identifier)) {
163
+			// so let's brew something up and add it to the proper collection
164
+			$brewed = $this->makeCoffee($identifier, $arguments, $type);
165
+		}
166
+		// did the requested class only require loading, and if so, was that successful?
167
+		if ($this->brewedLoadOnly($brewed, $identifier, $type) === true) {
168
+			return true;
169
+		}
170
+		// was the brewed item a callable factory function ?
171
+		if (is_callable($brewed)) {
172
+			// then instantiate a new entity from the cached closure
173
+			return $brewed($arguments);
174
+		}
175
+		if ($brewed) {
176
+			// requested object was a shared entity, so attempt to get it from the carafe again
177
+			// because if it wasn't there before, then it should have just been brewed and added,
178
+			// but if it still isn't there, then this time the thrown ServiceNotFoundException will not be caught
179
+			return $this->get($identifier);
180
+		}
181
+		// if identifier is for a non-shared entity,
182
+		// then either a cached closure already existed, or was just brewed
183
+		return $this->brewedClosure($identifier, $arguments);
184
+	}
185
+
186
+
187
+	/**
188
+	 * @param string $identifier
189
+	 * @param string $type
190
+	 * @return bool|mixed
191
+	 * @throws InvalidIdentifierException
192
+	 */
193
+	protected function getShared($identifier, $type)
194
+	{
195
+		try {
196
+			if (empty($type) || $type === CoffeeMaker::BREW_SHARED) {
197
+				// if a shared service was requested and an instance is in the carafe, then return it
198
+				return $this->get($identifier);
199
+			}
200
+		} catch (ServiceNotFoundException $e) {
201
+			// if not then we'll just catch the ServiceNotFoundException but not do anything just yet,
202
+			// and instead, attempt to build whatever was requested
203
+		}
204
+		return false;
205
+	}
206
+
207
+
208
+	/**
209
+	 * @param mixed  $brewed
210
+	 * @param string $identifier
211
+	 * @param string $type
212
+	 * @return bool
213
+	 * @throws InvalidClassException
214
+	 * @throws InvalidDataTypeException
215
+	 * @throws InvalidIdentifierException
216
+	 * @throws OutOfBoundsException
217
+	 * @throws ServiceExistsException
218
+	 * @throws ServiceNotFoundException
219
+	 */
220
+	protected function brewedLoadOnly($brewed, $identifier, $type)
221
+	{
222
+		if ($type === CoffeeMaker::BREW_LOAD_ONLY) {
223
+			if ($brewed !== true) {
224
+				throw new ServiceNotFoundException(
225
+					sprintf(
226
+						esc_html__(
227
+							'The "%1$s" class could not be loaded.',
228
+							'event_espresso'
229
+						),
230
+						$identifier
231
+					)
232
+				);
233
+			}
234
+			return true;
235
+		}
236
+		return false;
237
+	}
238
+
239
+
240
+	/**
241
+	 * @param string $identifier
242
+	 * @param array  $arguments
243
+	 * @return mixed
244
+	 * @throws InstantiationException
245
+	 */
246
+	protected function brewedClosure($identifier, array $arguments)
247
+	{
248
+		$closure = $this->reservoir->get($identifier);
249
+		if (empty($closure)) {
250
+			throw new InstantiationException(
251
+				sprintf(
252
+					esc_html__(
253
+						'Could not brew an instance of "%1$s".',
254
+						'event_espresso'
255
+					),
256
+					$identifier
257
+				)
258
+			);
259
+		}
260
+		return $closure($arguments);
261
+	}
262
+
263
+
264
+	/**
265
+	 * @param CoffeeMakerInterface $coffee_maker
266
+	 * @param string               $type
267
+	 * @return bool
268
+	 * @throws InvalidIdentifierException
269
+	 * @throws InvalidEntityException
270
+	 */
271
+	public function addCoffeeMaker(CoffeeMakerInterface $coffee_maker, $type)
272
+	{
273
+		$type = CoffeeMaker::validateType($type);
274
+		return $this->coffee_makers->add($coffee_maker, $type);
275
+	}
276
+
277
+
278
+	/**
279
+	 * @param string   $identifier
280
+	 * @param callable $closure
281
+	 * @return callable|null
282
+	 * @throws InvalidIdentifierException
283
+	 * @throws InvalidDataTypeException
284
+	 */
285
+	public function addClosure($identifier, $closure)
286
+	{
287
+		if (! is_callable($closure)) {
288
+			throw new InvalidDataTypeException('$closure', $closure, 'Closure');
289
+		}
290
+		$identifier = $this->processIdentifier($identifier);
291
+		if ($this->reservoir->add($closure, $identifier)) {
292
+			return $closure;
293
+		}
294
+		return null;
295
+	}
296
+
297
+
298
+	/**
299
+	 * @param string $identifier
300
+	 * @return boolean
301
+	 * @throws InvalidIdentifierException
302
+	 */
303
+	public function removeClosure($identifier)
304
+	{
305
+		$identifier = $this->processIdentifier($identifier);
306
+		if ($this->reservoir->has($identifier)) {
307
+			return $this->reservoir->remove($this->reservoir->get($identifier));
308
+		}
309
+		return false;
310
+	}
311
+
312
+
313
+	/**
314
+	 * @param  string $identifier Identifier for the entity class that the service applies to
315
+	 *                            Typically a Fully Qualified Class Name
316
+	 * @param mixed   $service
317
+	 * @return bool
318
+	 * @throws \EventEspresso\core\services\container\exceptions\InvalidServiceException
319
+	 * @throws InvalidIdentifierException
320
+	 */
321
+	public function addService($identifier, $service)
322
+	{
323
+		$identifier = $this->processIdentifier($identifier);
324
+		$service = $this->validateService($identifier, $service);
325
+		return $this->carafe->add($service, $identifier);
326
+	}
327
+
328
+
329
+	/**
330
+	 * @param string $identifier
331
+	 * @return boolean
332
+	 * @throws InvalidIdentifierException
333
+	 */
334
+	public function removeService($identifier)
335
+	{
336
+		$identifier = $this->processIdentifier($identifier);
337
+		if ($this->carafe->has($identifier)) {
338
+			return $this->carafe->remove($this->carafe->get($identifier));
339
+		}
340
+		return false;
341
+	}
342
+
343
+
344
+	/**
345
+	 * Adds instructions on how to brew objects
346
+	 *
347
+	 * @param RecipeInterface $recipe
348
+	 * @return mixed
349
+	 * @throws InvalidIdentifierException
350
+	 */
351
+	public function addRecipe(RecipeInterface $recipe)
352
+	{
353
+		$this->addAliases($recipe->identifier(), $recipe->filters());
354
+		$identifier = $this->processIdentifier($recipe->identifier());
355
+		return $this->recipes->add($recipe, $identifier);
356
+	}
357
+
358
+
359
+	/**
360
+	 * @param string $identifier The Recipe's identifier
361
+	 * @return boolean
362
+	 * @throws InvalidIdentifierException
363
+	 */
364
+	public function removeRecipe($identifier)
365
+	{
366
+		$identifier = $this->processIdentifier($identifier);
367
+		if ($this->recipes->has($identifier)) {
368
+			return $this->recipes->remove($this->recipes->get($identifier));
369
+		}
370
+		return false;
371
+	}
372
+
373
+
374
+	/**
375
+	 * Get instructions on how to brew objects
376
+	 *
377
+	 * @param  string $identifier Identifier for the entity class that the recipe applies to
378
+	 *                            Typically a Fully Qualified Class Name
379
+	 * @param string  $type
380
+	 * @return RecipeInterface
381
+	 * @throws OutOfBoundsException
382
+	 * @throws InvalidIdentifierException
383
+	 */
384
+	public function getRecipe($identifier, $type = '')
385
+	{
386
+		$identifier = $this->processIdentifier($identifier);
387
+		if ($this->recipes->has($identifier)) {
388
+			return $this->recipes->get($identifier);
389
+		}
390
+		$default_recipes = $this->getDefaultRecipes();
391
+		$matches = array();
392
+		foreach ($default_recipes as $wildcard => $default_recipe) {
393
+			// is the wildcard recipe prefix in the identifier ?
394
+			if (strpos($identifier, $wildcard) !== false) {
395
+				// track matches and use the number of wildcard characters matched for the key
396
+				$matches[ strlen($wildcard) ] = $default_recipe;
397
+			}
398
+		}
399
+		if (count($matches) > 0) {
400
+			// sort our recipes by the number of wildcard characters matched
401
+			ksort($matches);
402
+			// then grab the last recipe form the list, since it had the most matching characters
403
+			$match = array_pop($matches);
404
+			// since we are using a default recipe, we need to set it's identifier and fqcn
405
+			return $this->copyDefaultRecipe($match, $identifier, $type);
406
+		}
407
+		if ($this->recipes->has(Recipe::DEFAULT_ID)) {
408
+			// since we are using a default recipe, we need to set it's identifier and fqcn
409
+			return $this->copyDefaultRecipe($this->recipes->get(Recipe::DEFAULT_ID), $identifier, $type);
410
+		}
411
+		throw new OutOfBoundsException(
412
+			sprintf(
413
+				__('Could not brew coffee because no recipes were found for class "%1$s".', 'event_espresso'),
414
+				$identifier
415
+			)
416
+		);
417
+	}
418
+
419
+
420
+	/**
421
+	 * adds class name aliases to list of filters
422
+	 *
423
+	 * @param  string       $identifier Identifier for the entity class that the alias applies to
424
+	 *                                  Typically a Fully Qualified Class Name
425
+	 * @param  array|string $aliases
426
+	 * @return void
427
+	 * @throws InvalidIdentifierException
428
+	 */
429
+	public function addAliases($identifier, $aliases)
430
+	{
431
+		if (empty($aliases)) {
432
+			return;
433
+		}
434
+		$identifier = $this->processIdentifier($identifier);
435
+		foreach ((array) $aliases as $alias) {
436
+			$this->filters[ $this->processIdentifier($alias) ] = $identifier;
437
+		}
438
+	}
439
+
440
+
441
+	/**
442
+	 * Adds a service to one of the internal collections
443
+	 *
444
+	 * @param        $identifier
445
+	 * @param array  $arguments
446
+	 * @param string $type
447
+	 * @return mixed
448
+	 * @throws InvalidDataTypeException
449
+	 * @throws InvalidClassException
450
+	 * @throws OutOfBoundsException
451
+	 * @throws InvalidIdentifierException
452
+	 * @throws ServiceExistsException
453
+	 */
454
+	private function makeCoffee($identifier, $arguments = array(), $type = '')
455
+	{
456
+		if ((empty($type) || $type === CoffeeMaker::BREW_SHARED) && $this->has($identifier)) {
457
+			throw new ServiceExistsException($identifier);
458
+		}
459
+		$identifier = $this->filterIdentifier($identifier);
460
+		$recipe = $this->getRecipe($identifier, $type);
461
+		$type = ! empty($type) ? $type : $recipe->type();
462
+		$coffee_maker = $this->getCoffeeMaker($type);
463
+		return $coffee_maker->brew($recipe, $arguments);
464
+	}
465
+
466
+
467
+	/**
468
+	 * filters alias identifiers to find the real class name
469
+	 *
470
+	 * @param  string $identifier Identifier for the entity class that the filter applies to
471
+	 *                            Typically a Fully Qualified Class Name
472
+	 * @return string
473
+	 * @throws InvalidIdentifierException
474
+	 */
475
+	private function filterIdentifier($identifier)
476
+	{
477
+		$identifier = $this->processIdentifier($identifier);
478
+		return isset($this->filters[ $identifier ]) && ! empty($this->filters[ $identifier ])
479
+			? $this->filters[ $identifier ]
480
+			: $identifier;
481
+	}
482
+
483
+
484
+	/**
485
+	 * verifies and standardizes identifiers
486
+	 *
487
+	 * @param  string $identifier Identifier for the entity class
488
+	 *                            Typically a Fully Qualified Class Name
489
+	 * @return string
490
+	 * @throws InvalidIdentifierException
491
+	 */
492
+	private function processIdentifier($identifier)
493
+	{
494
+		if (! is_string($identifier)) {
495
+			throw new InvalidIdentifierException(
496
+				is_object($identifier) ? get_class($identifier) : gettype($identifier),
497
+				'\Fully\Qualified\ClassName'
498
+			);
499
+		}
500
+		return ltrim($identifier, '\\');
501
+	}
502
+
503
+
504
+	/**
505
+	 * @param string $type
506
+	 * @return CoffeeMakerInterface
507
+	 * @throws OutOfBoundsException
508
+	 * @throws InvalidDataTypeException
509
+	 * @throws InvalidClassException
510
+	 */
511
+	private function getCoffeeMaker($type)
512
+	{
513
+		if (! $this->coffee_makers->has($type)) {
514
+			throw new OutOfBoundsException(
515
+				__('The requested coffee maker is either missing or invalid.', 'event_espresso')
516
+			);
517
+		}
518
+		return $this->coffee_makers->get($type);
519
+	}
520
+
521
+
522
+	/**
523
+	 * Retrieves all recipes that use a wildcard "*" in their identifier
524
+	 * This allows recipes to be set up for handling
525
+	 * legacy classes that do not support PSR-4 autoloading.
526
+	 * for example:
527
+	 * using "EEM_*" for a recipe identifier would target all legacy models like EEM_Attendee
528
+	 *
529
+	 * @return array
530
+	 */
531
+	private function getDefaultRecipes()
532
+	{
533
+		$default_recipes = array();
534
+		$this->recipes->rewind();
535
+		while ($this->recipes->valid()) {
536
+			$identifier = $this->recipes->getInfo();
537
+			// does this recipe use a wildcard ? (but is NOT the global default)
538
+			if ($identifier !== Recipe::DEFAULT_ID && strpos($identifier, '*') !== false) {
539
+				// strip the wildcard and use identifier as key
540
+				$default_recipes[ str_replace('*', '', $identifier) ] = $this->recipes->current();
541
+			}
542
+			$this->recipes->next();
543
+		}
544
+		return $default_recipes;
545
+	}
546
+
547
+
548
+	/**
549
+	 * clones a default recipe and then copies details
550
+	 * from the incoming request to it so that it can be used
551
+	 *
552
+	 * @param RecipeInterface $default_recipe
553
+	 * @param string          $identifier
554
+	 * @param string          $type
555
+	 * @return RecipeInterface
556
+	 */
557
+	private function copyDefaultRecipe(RecipeInterface $default_recipe, $identifier, $type = '')
558
+	{
559
+		$recipe = clone $default_recipe;
560
+		if (! empty($type)) {
561
+			$recipe->setType($type);
562
+		}
563
+		// is this the base default recipe ?
564
+		if ($default_recipe->identifier() === Recipe::DEFAULT_ID) {
565
+			$recipe->setIdentifier($identifier);
566
+			$recipe->setFqcn($identifier);
567
+			return $recipe;
568
+		}
569
+		$recipe->setIdentifier($identifier);
570
+		foreach ($default_recipe->paths() as $path) {
571
+			$path = str_replace('*', $identifier, $path);
572
+			if (is_readable($path)) {
573
+				$recipe->setPaths($path);
574
+			}
575
+		}
576
+		$recipe->setFqcn($identifier);
577
+		return $recipe;
578
+	}
579
+
580
+
581
+	/**
582
+	 * @param  string $identifier Identifier for the entity class that the service applies to
583
+	 *                            Typically a Fully Qualified Class Name
584
+	 * @param mixed   $service
585
+	 * @return mixed
586
+	 * @throws InvalidServiceException
587
+	 */
588
+	private function validateService($identifier, $service)
589
+	{
590
+		if (! is_object($service)) {
591
+			throw new InvalidServiceException(
592
+				$identifier,
593
+				$service
594
+			);
595
+		}
596
+		return $service;
597
+	}
598 598
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -159,7 +159,7 @@  discard block
 block discarded – undo
159 159
         }
160 160
         // if the reservoir doesn't have a closure already for the requested identifier,
161 161
         // then neither a shared service nor a closure for making entities has been built yet
162
-        if (! $this->reservoir->has($identifier)) {
162
+        if ( ! $this->reservoir->has($identifier)) {
163 163
             // so let's brew something up and add it to the proper collection
164 164
             $brewed = $this->makeCoffee($identifier, $arguments, $type);
165 165
         }
@@ -284,7 +284,7 @@  discard block
 block discarded – undo
284 284
      */
285 285
     public function addClosure($identifier, $closure)
286 286
     {
287
-        if (! is_callable($closure)) {
287
+        if ( ! is_callable($closure)) {
288 288
             throw new InvalidDataTypeException('$closure', $closure, 'Closure');
289 289
         }
290 290
         $identifier = $this->processIdentifier($identifier);
@@ -393,7 +393,7 @@  discard block
 block discarded – undo
393 393
             // is the wildcard recipe prefix in the identifier ?
394 394
             if (strpos($identifier, $wildcard) !== false) {
395 395
                 // track matches and use the number of wildcard characters matched for the key
396
-                $matches[ strlen($wildcard) ] = $default_recipe;
396
+                $matches[strlen($wildcard)] = $default_recipe;
397 397
             }
398 398
         }
399 399
         if (count($matches) > 0) {
@@ -433,7 +433,7 @@  discard block
 block discarded – undo
433 433
         }
434 434
         $identifier = $this->processIdentifier($identifier);
435 435
         foreach ((array) $aliases as $alias) {
436
-            $this->filters[ $this->processIdentifier($alias) ] = $identifier;
436
+            $this->filters[$this->processIdentifier($alias)] = $identifier;
437 437
         }
438 438
     }
439 439
 
@@ -475,8 +475,8 @@  discard block
 block discarded – undo
475 475
     private function filterIdentifier($identifier)
476 476
     {
477 477
         $identifier = $this->processIdentifier($identifier);
478
-        return isset($this->filters[ $identifier ]) && ! empty($this->filters[ $identifier ])
479
-            ? $this->filters[ $identifier ]
478
+        return isset($this->filters[$identifier]) && ! empty($this->filters[$identifier])
479
+            ? $this->filters[$identifier]
480 480
             : $identifier;
481 481
     }
482 482
 
@@ -491,7 +491,7 @@  discard block
 block discarded – undo
491 491
      */
492 492
     private function processIdentifier($identifier)
493 493
     {
494
-        if (! is_string($identifier)) {
494
+        if ( ! is_string($identifier)) {
495 495
             throw new InvalidIdentifierException(
496 496
                 is_object($identifier) ? get_class($identifier) : gettype($identifier),
497 497
                 '\Fully\Qualified\ClassName'
@@ -510,7 +510,7 @@  discard block
 block discarded – undo
510 510
      */
511 511
     private function getCoffeeMaker($type)
512 512
     {
513
-        if (! $this->coffee_makers->has($type)) {
513
+        if ( ! $this->coffee_makers->has($type)) {
514 514
             throw new OutOfBoundsException(
515 515
                 __('The requested coffee maker is either missing or invalid.', 'event_espresso')
516 516
             );
@@ -537,7 +537,7 @@  discard block
 block discarded – undo
537 537
             // does this recipe use a wildcard ? (but is NOT the global default)
538 538
             if ($identifier !== Recipe::DEFAULT_ID && strpos($identifier, '*') !== false) {
539 539
                 // strip the wildcard and use identifier as key
540
-                $default_recipes[ str_replace('*', '', $identifier) ] = $this->recipes->current();
540
+                $default_recipes[str_replace('*', '', $identifier)] = $this->recipes->current();
541 541
             }
542 542
             $this->recipes->next();
543 543
         }
@@ -557,7 +557,7 @@  discard block
 block discarded – undo
557 557
     private function copyDefaultRecipe(RecipeInterface $default_recipe, $identifier, $type = '')
558 558
     {
559 559
         $recipe = clone $default_recipe;
560
-        if (! empty($type)) {
560
+        if ( ! empty($type)) {
561 561
             $recipe->setType($type);
562 562
         }
563 563
         // is this the base default recipe ?
@@ -587,7 +587,7 @@  discard block
 block discarded – undo
587 587
      */
588 588
     private function validateService($identifier, $service)
589 589
     {
590
-        if (! is_object($service)) {
590
+        if ( ! is_object($service)) {
591 591
             throw new InvalidServiceException(
592 592
                 $identifier,
593 593
                 $service
Please login to merge, or discard this patch.
core/interfaces/line_items/EEI_Line_Item_Display.interface.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -9,12 +9,12 @@
 block discarded – undo
9 9
 interface EEI_Line_Item_Display
10 10
 {
11 11
 
12
-    /**
13
-     * @param EE_Line_Item $line_item
14
-     * @param array        $options
15
-     * @return mixed
16
-     */
17
-    public function display_line_item(EE_Line_Item $line_item, $options = array());
12
+	/**
13
+	 * @param EE_Line_Item $line_item
14
+	 * @param array        $options
15
+	 * @return mixed
16
+	 */
17
+	public function display_line_item(EE_Line_Item $line_item, $options = array());
18 18
 
19 19
 }
20 20
 
Please login to merge, or discard this patch.
form_sections/strategies/normalization/EE_Int_Normalization.strategy.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@
 block discarded – undo
17 17
 
18 18
     /**
19 19
      * @param string $value_to_normalize
20
-     * @return int|mixed|string
20
+     * @return null|integer
21 21
      * @throws \EE_Validation_Error
22 22
      */
23 23
     public function normalize($value_to_normalize)
Please login to merge, or discard this patch.
Indentation   +74 added lines, -74 removed lines patch added patch discarded remove patch
@@ -10,88 +10,88 @@
 block discarded – undo
10 10
 class EE_Int_Normalization extends EE_Normalization_Strategy_Base
11 11
 {
12 12
 
13
-    /*
13
+	/*
14 14
      * regex pattern that matches for the following:
15 15
      *      * optional negative sign
16 16
      *      * one or more digits
17 17
      */
18
-    const REGEX = '/^(-?)(\d+)(?:\.0+)?$/';
18
+	const REGEX = '/^(-?)(\d+)(?:\.0+)?$/';
19 19
 
20 20
 
21 21
 
22
-    /**
23
-     * @param string $value_to_normalize
24
-     * @return int|mixed|string
25
-     * @throws \EE_Validation_Error
26
-     */
27
-    public function normalize($value_to_normalize)
28
-    {
29
-        if ($value_to_normalize === null) {
30
-            return null;
31
-        }
32
-        if (is_int($value_to_normalize) || is_float($value_to_normalize)) {
33
-            return (int) $value_to_normalize;
34
-        }
35
-        if (! is_string($value_to_normalize)) {
36
-            throw new EE_Validation_Error(
37
-                sprintf(
38
-                    __('The value "%s" must be a string submitted for normalization, it was %s', 'event_espresso'),
39
-                    print_r($value_to_normalize, true),
40
-                    gettype($value_to_normalize)
41
-                )
42
-            );
43
-        }
44
-        $value_to_normalize = filter_var(
45
-            $value_to_normalize,
46
-            FILTER_SANITIZE_NUMBER_FLOAT,
47
-            FILTER_FLAG_ALLOW_FRACTION
48
-        );
49
-        if ($value_to_normalize === '') {
50
-            return null;
51
-        }
52
-        $matches = array();
53
-        if (preg_match(EE_Int_Normalization::REGEX, $value_to_normalize, $matches)) {
54
-            if (count($matches) === 3) {
55
-                // if first match is the negative sign,
56
-                // then the number needs to be multiplied by -1 to remain negative
57
-                return $matches[1] === '-'
58
-                    ? (int) $matches[2] * -1
59
-                    : (int) $matches[2];
60
-            }
61
-        }
62
-        // find if this input has a int validation strategy
63
-        // in which case, use its message
64
-        $validation_error_message = null;
65
-        foreach ($this->_input->get_validation_strategies() as $validation_strategy) {
66
-            if ($validation_strategy instanceof EE_Int_Validation_Strategy) {
67
-                $validation_error_message = $validation_strategy->get_validation_error_message();
68
-            }
69
-        }
70
-        // this really shouldn't ever happen because fields with a int normalization strategy
71
-        // should also have a int validation strategy, but in case it doesn't use the default
72
-        if (! $validation_error_message) {
73
-            $default_validation_strategy = new EE_Int_Validation_Strategy();
74
-            $validation_error_message = $default_validation_strategy->get_validation_error_message();
75
-        }
76
-        throw new EE_Validation_Error($validation_error_message, 'numeric_only');
77
-    }
22
+	/**
23
+	 * @param string $value_to_normalize
24
+	 * @return int|mixed|string
25
+	 * @throws \EE_Validation_Error
26
+	 */
27
+	public function normalize($value_to_normalize)
28
+	{
29
+		if ($value_to_normalize === null) {
30
+			return null;
31
+		}
32
+		if (is_int($value_to_normalize) || is_float($value_to_normalize)) {
33
+			return (int) $value_to_normalize;
34
+		}
35
+		if (! is_string($value_to_normalize)) {
36
+			throw new EE_Validation_Error(
37
+				sprintf(
38
+					__('The value "%s" must be a string submitted for normalization, it was %s', 'event_espresso'),
39
+					print_r($value_to_normalize, true),
40
+					gettype($value_to_normalize)
41
+				)
42
+			);
43
+		}
44
+		$value_to_normalize = filter_var(
45
+			$value_to_normalize,
46
+			FILTER_SANITIZE_NUMBER_FLOAT,
47
+			FILTER_FLAG_ALLOW_FRACTION
48
+		);
49
+		if ($value_to_normalize === '') {
50
+			return null;
51
+		}
52
+		$matches = array();
53
+		if (preg_match(EE_Int_Normalization::REGEX, $value_to_normalize, $matches)) {
54
+			if (count($matches) === 3) {
55
+				// if first match is the negative sign,
56
+				// then the number needs to be multiplied by -1 to remain negative
57
+				return $matches[1] === '-'
58
+					? (int) $matches[2] * -1
59
+					: (int) $matches[2];
60
+			}
61
+		}
62
+		// find if this input has a int validation strategy
63
+		// in which case, use its message
64
+		$validation_error_message = null;
65
+		foreach ($this->_input->get_validation_strategies() as $validation_strategy) {
66
+			if ($validation_strategy instanceof EE_Int_Validation_Strategy) {
67
+				$validation_error_message = $validation_strategy->get_validation_error_message();
68
+			}
69
+		}
70
+		// this really shouldn't ever happen because fields with a int normalization strategy
71
+		// should also have a int validation strategy, but in case it doesn't use the default
72
+		if (! $validation_error_message) {
73
+			$default_validation_strategy = new EE_Int_Validation_Strategy();
74
+			$validation_error_message = $default_validation_strategy->get_validation_error_message();
75
+		}
76
+		throw new EE_Validation_Error($validation_error_message, 'numeric_only');
77
+	}
78 78
 
79 79
 
80 80
 
81
-    /**
82
-     * Converts the int into a string for use in teh html form
83
-     *
84
-     * @param int $normalized_value
85
-     * @return string
86
-     */
87
-    public function unnormalize($normalized_value)
88
-    {
89
-        if ($normalized_value === null || $normalized_value === '') {
90
-            return '';
91
-        }
92
-        if (empty($normalized_value)) {
93
-            return '0';
94
-        }
95
-        return "$normalized_value";
96
-    }
81
+	/**
82
+	 * Converts the int into a string for use in teh html form
83
+	 *
84
+	 * @param int $normalized_value
85
+	 * @return string
86
+	 */
87
+	public function unnormalize($normalized_value)
88
+	{
89
+		if ($normalized_value === null || $normalized_value === '') {
90
+			return '';
91
+		}
92
+		if (empty($normalized_value)) {
93
+			return '0';
94
+		}
95
+		return "$normalized_value";
96
+	}
97 97
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -32,7 +32,7 @@  discard block
 block discarded – undo
32 32
         if (is_int($value_to_normalize) || is_float($value_to_normalize)) {
33 33
             return (int) $value_to_normalize;
34 34
         }
35
-        if (! is_string($value_to_normalize)) {
35
+        if ( ! is_string($value_to_normalize)) {
36 36
             throw new EE_Validation_Error(
37 37
                 sprintf(
38 38
                     __('The value "%s" must be a string submitted for normalization, it was %s', 'event_espresso'),
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
         }
70 70
         // this really shouldn't ever happen because fields with a int normalization strategy
71 71
         // should also have a int validation strategy, but in case it doesn't use the default
72
-        if (! $validation_error_message) {
72
+        if ( ! $validation_error_message) {
73 73
             $default_validation_strategy = new EE_Int_Validation_Strategy();
74 74
             $validation_error_message = $default_validation_strategy->get_validation_error_message();
75 75
         }
Please login to merge, or discard this patch.
core/db_models/EEM_Event.model.php 4 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -217,7 +217,7 @@
 block discarded – undo
217 217
 
218 218
     /**
219 219
      * Used to override the default for the additional limit field.
220
-     * @param $additional_limit
220
+     * @param integer $additional_limit
221 221
      */
222 222
     public static function set_default_additional_limit($additional_limit)
223 223
     {
Please login to merge, or discard this patch.
Unused Use Statements   -2 removed lines patch added patch discarded remove patch
@@ -1,7 +1,5 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-use EventEspresso\core\services\orm\ModelFieldFactory;
4
-
5 3
 /**
6 4
  * EEM_Event Model
7 5
  * extends EEM_CPT_Base which extends EEM_Base
Please login to merge, or discard this patch.
Indentation   +873 added lines, -873 removed lines patch added patch discarded remove patch
@@ -13,877 +13,877 @@
 block discarded – undo
13 13
 class EEM_Event extends EEM_CPT_Base
14 14
 {
15 15
 
16
-    /**
17
-     * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the
18
-     * event
19
-     */
20
-    const sold_out = 'sold_out';
21
-
22
-    /**
23
-     * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later
24
-     * date)
25
-     */
26
-    const postponed = 'postponed';
27
-
28
-    /**
29
-     * constant used by status(), indicating that the event will no longer occur
30
-     */
31
-    const cancelled = 'cancelled';
32
-
33
-
34
-    /**
35
-     * @var string
36
-     */
37
-    protected static $_default_reg_status;
38
-
39
-
40
-    /**
41
-     * This is the default for the additional limit field.
42
-     * @var int
43
-     */
44
-    protected static $_default_additional_limit = 10;
45
-
46
-
47
-    /**
48
-     * private instance of the Event object
49
-     *
50
-     * @var EEM_Event
51
-     */
52
-    protected static $_instance;
53
-
54
-
55
-
56
-
57
-    /**
58
-     * Adds a relationship to Term_Taxonomy for each CPT_Base
59
-     *
60
-     * @param string $timezone
61
-     * @throws \EE_Error
62
-     */
63
-    protected function __construct($timezone = null)
64
-    {
65
-        EE_Registry::instance()->load_model('Registration');
66
-        $this->singular_item = esc_html__('Event', 'event_espresso');
67
-        $this->plural_item = esc_html__('Events', 'event_espresso');
68
-        // to remove Cancelled events from the frontend, copy the following filter to your functions.php file
69
-        // add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' );
70
-        // to remove Postponed events from the frontend, copy the following filter to your functions.php file
71
-        // add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' );
72
-        // to remove Sold Out events from the frontend, copy the following filter to your functions.php file
73
-        //  add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' );
74
-        $this->_custom_stati = apply_filters(
75
-            'AFEE__EEM_Event__construct___custom_stati',
76
-            array(
77
-                EEM_Event::cancelled => array(
78
-                    'label'  => esc_html__('Cancelled', 'event_espresso'),
79
-                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true),
80
-                ),
81
-                EEM_Event::postponed => array(
82
-                    'label'  => esc_html__('Postponed', 'event_espresso'),
83
-                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true),
84
-                ),
85
-                EEM_Event::sold_out  => array(
86
-                    'label'  => esc_html__('Sold Out', 'event_espresso'),
87
-                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true),
88
-                ),
89
-            )
90
-        );
91
-        self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment
92
-            : self::$_default_reg_status;
93
-        $this->_tables = array(
94
-            'Event_CPT'  => new EE_Primary_Table('posts', 'ID'),
95
-            'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID'),
96
-        );
97
-        $this->_fields = array(
98
-            'Event_CPT'  => array(
99
-                'EVT_ID'         => new EE_Primary_Key_Int_Field(
100
-                    'ID',
101
-                    esc_html__('Post ID for Event', 'event_espresso')
102
-                ),
103
-                'EVT_name'       => new EE_Plain_Text_Field(
104
-                    'post_title',
105
-                    esc_html__('Event Name', 'event_espresso'),
106
-                    false,
107
-                    ''
108
-                ),
109
-                'EVT_desc'       => new EE_Post_Content_Field(
110
-                    'post_content',
111
-                    esc_html__('Event Description', 'event_espresso'),
112
-                    false,
113
-                    ''
114
-                ),
115
-                'EVT_slug'       => new EE_Slug_Field(
116
-                    'post_name',
117
-                    esc_html__('Event Slug', 'event_espresso'),
118
-                    false,
119
-                    ''
120
-                ),
121
-                'EVT_created'    => new EE_Datetime_Field(
122
-                    'post_date',
123
-                    esc_html__('Date/Time Event Created', 'event_espresso'),
124
-                    false,
125
-                    EE_Datetime_Field::now
126
-                ),
127
-                'EVT_short_desc' => new EE_Simple_HTML_Field(
128
-                    'post_excerpt',
129
-                    esc_html__('Event Short Description', 'event_espresso'),
130
-                    false,
131
-                    ''
132
-                ),
133
-                'EVT_modified'   => new EE_Datetime_Field(
134
-                    'post_modified',
135
-                    esc_html__('Date/Time Event Modified', 'event_espresso'),
136
-                    false,
137
-                    EE_Datetime_Field::now
138
-                ),
139
-                'EVT_wp_user'    => new EE_WP_User_Field(
140
-                    'post_author',
141
-                    esc_html__('Event Creator ID', 'event_espresso'),
142
-                    false
143
-                ),
144
-                'parent'         => new EE_Integer_Field(
145
-                    'post_parent',
146
-                    esc_html__('Event Parent ID', 'event_espresso'),
147
-                    false,
148
-                    0
149
-                ),
150
-                'EVT_order'      => new EE_Integer_Field(
151
-                    'menu_order',
152
-                    esc_html__('Event Menu Order', 'event_espresso'),
153
-                    false,
154
-                    1
155
-                ),
156
-                'post_type'      => new EE_WP_Post_Type_Field('espresso_events'),
157
-                // EE_Plain_Text_Field( 'post_type', esc_html__( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ),
158
-                'status'         => new EE_WP_Post_Status_Field(
159
-                    'post_status',
160
-                    esc_html__('Event Status', 'event_espresso'),
161
-                    false,
162
-                    'draft',
163
-                    $this->_custom_stati
164
-                ),
165
-            ),
166
-            'Event_Meta' => array(
167
-                'EVTM_ID'                         => new EE_DB_Only_Float_Field(
168
-                    'EVTM_ID',
169
-                    esc_html__('Event Meta Row ID', 'event_espresso'),
170
-                    false
171
-                ),
172
-                'EVT_ID_fk'                       => new EE_DB_Only_Int_Field(
173
-                    'EVT_ID',
174
-                    esc_html__('Foreign key to Event ID from Event Meta table', 'event_espresso'),
175
-                    false
176
-                ),
177
-                'EVT_display_desc'                => new EE_Boolean_Field(
178
-                    'EVT_display_desc',
179
-                    esc_html__('Display Description Flag', 'event_espresso'),
180
-                    false,
181
-                    1
182
-                ),
183
-                'EVT_display_ticket_selector'     => new EE_Boolean_Field(
184
-                    'EVT_display_ticket_selector',
185
-                    esc_html__('Display Ticket Selector Flag', 'event_espresso'),
186
-                    false,
187
-                    1
188
-                ),
189
-                'EVT_visible_on'                  => new EE_Datetime_Field(
190
-                    'EVT_visible_on',
191
-                    esc_html__('Event Visible Date', 'event_espresso'),
192
-                    true,
193
-                    EE_Datetime_Field::now
194
-                ),
195
-                'EVT_additional_limit'            => new EE_Integer_Field(
196
-                    'EVT_additional_limit',
197
-                    esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
198
-                    true,
199
-                    self::$_default_additional_limit
200
-                ),
201
-                'EVT_default_registration_status' => new EE_Enum_Text_Field(
202
-                    'EVT_default_registration_status',
203
-                    esc_html__('Default Registration Status on this Event', 'event_espresso'),
204
-                    false,
205
-                    EEM_Event::$_default_reg_status,
206
-                    EEM_Registration::reg_status_array()
207
-                ),
208
-                'EVT_member_only'                 => new EE_Boolean_Field(
209
-                    'EVT_member_only',
210
-                    esc_html__('Member-Only Event Flag', 'event_espresso'),
211
-                    false,
212
-                    false
213
-                ),
214
-                'EVT_phone'                       => new EE_Plain_Text_Field(
215
-                    'EVT_phone',
216
-                    esc_html__('Event Phone Number', 'event_espresso'),
217
-                    false,
218
-                    ''
219
-                ),
220
-                'EVT_allow_overflow'              => new EE_Boolean_Field(
221
-                    'EVT_allow_overflow',
222
-                    esc_html__('Allow Overflow on Event', 'event_espresso'),
223
-                    false,
224
-                    false
225
-                ),
226
-                'EVT_timezone_string'             => new EE_Plain_Text_Field(
227
-                    'EVT_timezone_string',
228
-                    esc_html__('Timezone (name) for Event times', 'event_espresso'),
229
-                    false,
230
-                    ''
231
-                ),
232
-                'EVT_external_URL'                => new EE_Plain_Text_Field(
233
-                    'EVT_external_URL',
234
-                    esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso'),
235
-                    true
236
-                ),
237
-                'EVT_donations'                   => new EE_Boolean_Field(
238
-                    'EVT_donations',
239
-                    esc_html__('Accept Donations?', 'event_espresso'),
240
-                    false,
241
-                    false
242
-                ),
243
-            ),
244
-        );
245
-        $this->_model_relations = array(
246
-            'Registration'           => new EE_Has_Many_Relation(),
247
-            'Datetime'               => new EE_Has_Many_Relation(),
248
-            'Question_Group'         => new EE_HABTM_Relation('Event_Question_Group'),
249
-            'Venue'                  => new EE_HABTM_Relation('Event_Venue'),
250
-            'Term_Relationship'      => new EE_Has_Many_Relation(),
251
-            'Term_Taxonomy'          => new EE_HABTM_Relation('Term_Relationship'),
252
-            'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'),
253
-            'Attendee'               => new EE_HABTM_Relation('Registration'),
254
-            'WP_User'                => new EE_Belongs_To_Relation(),
255
-        );
256
-        // this model is generally available for reading
257
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public();
258
-        parent::__construct($timezone);
259
-    }
260
-
261
-
262
-
263
-    /**
264
-     * @param string $default_reg_status
265
-     */
266
-    public static function set_default_reg_status($default_reg_status)
267
-    {
268
-        self::$_default_reg_status = $default_reg_status;
269
-        // if EEM_Event has already been instantiated,
270
-        // then we need to reset the `EVT_default_reg_status` field to use the new default.
271
-        if (self::$_instance instanceof EEM_Event) {
272
-            $default_reg_status = new EE_Enum_Text_Field(
273
-                'EVT_default_registration_status',
274
-                esc_html__('Default Registration Status on this Event', 'event_espresso'),
275
-                false,
276
-                $default_reg_status,
277
-                EEM_Registration::reg_status_array()
278
-            );
279
-            $default_reg_status->_construct_finalize(
280
-                'Event_Meta',
281
-                'EVT_default_registration_status',
282
-                'EEM_Event'
283
-            );
284
-            self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = $default_reg_status;
285
-        }
286
-    }
287
-
288
-
289
-    /**
290
-     * Used to override the default for the additional limit field.
291
-     * @param $additional_limit
292
-     */
293
-    public static function set_default_additional_limit($additional_limit)
294
-    {
295
-        self::$_default_additional_limit = (int) $additional_limit;
296
-        if (self::$_instance instanceof EEM_Event) {
297
-            self::$_instance->_fields['Event_Meta']['EVT_additional_limit'] = new EE_Integer_Field(
298
-                'EVT_additional_limit',
299
-                __('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
300
-                true,
301
-                self::$_default_additional_limit
302
-            );
303
-            self::$_instance->_fields['Event_Meta']['EVT_additional_limit']->_construct_finalize(
304
-                'Event_Meta',
305
-                'EVT_additional_limit',
306
-                'EEM_Event'
307
-            );
308
-        }
309
-    }
310
-
311
-
312
-    /**
313
-     * Return what is currently set as the default additional limit for the event.
314
-     * @return int
315
-     */
316
-    public static function get_default_additional_limit()
317
-    {
318
-        return apply_filters('FHEE__EEM_Event__get_default_additional_limit', self::$_default_additional_limit);
319
-    }
320
-
321
-
322
-    /**
323
-     * get_question_groups
324
-     *
325
-     * @return array
326
-     * @throws \EE_Error
327
-     */
328
-    public function get_all_question_groups()
329
-    {
330
-        return EE_Registry::instance()->load_model('Question_Group')->get_all(
331
-            array(
332
-                array('QSG_deleted' => false),
333
-                'order_by' => array('QSG_order' => 'ASC'),
334
-            )
335
-        );
336
-    }
337
-
338
-
339
-
340
-    /**
341
-     * get_question_groups
342
-     *
343
-     * @param int $EVT_ID
344
-     * @return array|bool
345
-     * @throws \EE_Error
346
-     */
347
-    public function get_all_event_question_groups($EVT_ID = 0)
348
-    {
349
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
350
-            EE_Error::add_error(
351
-                esc_html__(
352
-                    'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
353
-                    'event_espresso'
354
-                ),
355
-                __FILE__,
356
-                __FUNCTION__,
357
-                __LINE__
358
-            );
359
-            return false;
360
-        }
361
-        return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(
362
-            array(
363
-                array('EVT_ID' => $EVT_ID),
364
-            )
365
-        );
366
-    }
367
-
368
-
369
-
370
-    /**
371
-     * get_question_groups
372
-     *
373
-     * @param int     $EVT_ID
374
-     * @param boolean $for_primary_attendee
375
-     * @return array|bool
376
-     * @throws \EE_Error
377
-     */
378
-    public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true)
379
-    {
380
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
381
-            EE_Error::add_error(
382
-                esc_html__(
383
-                    'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
384
-                    'event_espresso'
385
-                ),
386
-                __FILE__,
387
-                __FUNCTION__,
388
-                __LINE__
389
-            );
390
-            return false;
391
-        }
392
-        return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(
393
-            array(
394
-                array(
395
-                    'EVT_ID'      => $EVT_ID,
396
-                    'EQG_primary' => $for_primary_attendee,
397
-                ),
398
-            )
399
-        );
400
-    }
401
-
402
-
403
-
404
-    /**
405
-     * get_question_groups
406
-     *
407
-     * @param int             $EVT_ID
408
-     * @param EE_Registration $registration
409
-     * @return array|bool
410
-     * @throws \EE_Error
411
-     */
412
-    public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration)
413
-    {
414
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
415
-            EE_Error::add_error(
416
-                esc_html__(
417
-                    'An error occurred. No Question Groups could be retrieved because an Event ID was not received.',
418
-                    'event_espresso'
419
-                ),
420
-                __FILE__,
421
-                __FUNCTION__,
422
-                __LINE__
423
-            );
424
-            return false;
425
-        }
426
-        $where_params = array(
427
-            'Event_Question_Group.EVT_ID'      => $EVT_ID,
428
-            'Event_Question_Group.EQG_primary' => $registration->count() === 1 ? true : false,
429
-            'QSG_deleted'                      => false,
430
-        );
431
-        return EE_Registry::instance()->load_model('Question_Group')->get_all(
432
-            array(
433
-                $where_params,
434
-                'order_by' => array('QSG_order' => 'ASC'),
435
-            )
436
-        );
437
-    }
438
-
439
-
440
-
441
-    /**
442
-     * get_question_target_db_column
443
-     *
444
-     * @param string $QSG_IDs csv list of $QSG IDs
445
-     * @return array|bool
446
-     * @throws \EE_Error
447
-     */
448
-    public function get_questions_in_groups($QSG_IDs = '')
449
-    {
450
-        if (empty($QSG_IDs)) {
451
-            EE_Error::add_error(
452
-                esc_html__('An error occurred. No Question Group IDs were received.', 'event_espresso'),
453
-                __FILE__,
454
-                __FUNCTION__,
455
-                __LINE__
456
-            );
457
-            return false;
458
-        }
459
-        return EE_Registry::instance()->load_model('Question')->get_all(
460
-            array(
461
-                array(
462
-                    'Question_Group.QSG_ID' => array('IN', $QSG_IDs),
463
-                    'QST_deleted'           => false,
464
-                    'QST_admin_only'        => is_admin(),
465
-                ),
466
-                'order_by' => 'QST_order',
467
-            )
468
-        );
469
-    }
470
-
471
-
472
-
473
-    /**
474
-     * get_options_for_question
475
-     *
476
-     * @param string $QST_IDs csv list of $QST IDs
477
-     * @return array|bool
478
-     * @throws \EE_Error
479
-     */
480
-    public function get_options_for_question($QST_IDs)
481
-    {
482
-        if (empty($QST_IDs)) {
483
-            EE_Error::add_error(
484
-                esc_html__('An error occurred. No Question IDs were received.', 'event_espresso'),
485
-                __FILE__,
486
-                __FUNCTION__,
487
-                __LINE__
488
-            );
489
-            return false;
490
-        }
491
-        return EE_Registry::instance()->load_model('Question_Option')->get_all(
492
-            array(
493
-                array(
494
-                    'Question.QST_ID' => array('IN', $QST_IDs),
495
-                    'QSO_deleted'     => false,
496
-                ),
497
-                'order_by' => 'QSO_ID',
498
-            )
499
-        );
500
-    }
501
-
502
-
503
-
504
-
505
-
506
-
507
-
508
-    /**
509
-     * Gets all events that are published
510
-     * and have event start time earlier than now and an event end time later than now
511
-     *
512
-     * @param  array $query_params An array of query params to further filter on
513
-     *                             (note that status and DTT_EVT_start and DTT_EVT_end will be overridden)
514
-     * @param bool   $count        whether to return the count or not (default FALSE)
515
-     * @return EE_Event[]|int
516
-     * @throws \EE_Error
517
-     */
518
-    public function get_active_events($query_params, $count = false)
519
-    {
520
-        if (array_key_exists(0, $query_params)) {
521
-            $where_params = $query_params[0];
522
-            unset($query_params[0]);
523
-        } else {
524
-            $where_params = array();
525
-        }
526
-        // if we have count make sure we don't include group by
527
-        if ($count && isset($query_params['group_by'])) {
528
-            unset($query_params['group_by']);
529
-        }
530
-        // let's add specific query_params for active_events
531
-        // keep in mind this will override any sent status in the query AND any date queries.
532
-        $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
533
-        // if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions
534
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
535
-            $where_params['Datetime.DTT_EVT_start******'] = array(
536
-                '<',
537
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
538
-            );
539
-        } else {
540
-            $where_params['Datetime.DTT_EVT_start'] = array(
541
-                '<',
542
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
543
-            );
544
-        }
545
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
546
-            $where_params['Datetime.DTT_EVT_end*****'] = array(
547
-                '>',
548
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
549
-            );
550
-        } else {
551
-            $where_params['Datetime.DTT_EVT_end'] = array(
552
-                '>',
553
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
554
-            );
555
-        }
556
-        $query_params[0] = $where_params;
557
-        // don't use $query_params with count()
558
-        // because we don't want to include additional query clauses like "GROUP BY"
559
-        return $count
560
-            ? $this->count(array($where_params), 'EVT_ID', true)
561
-            : $this->get_all($query_params);
562
-    }
563
-
564
-
565
-
566
-    /**
567
-     * get all events that are published and have an event start time later than now
568
-     *
569
-     * @param  array $query_params An array of query params to further filter on
570
-     *                             (Note that status and DTT_EVT_start will be overridden)
571
-     * @param bool   $count        whether to return the count or not (default FALSE)
572
-     * @return EE_Event[]|int
573
-     * @throws \EE_Error
574
-     */
575
-    public function get_upcoming_events($query_params, $count = false)
576
-    {
577
-        if (array_key_exists(0, $query_params)) {
578
-            $where_params = $query_params[0];
579
-            unset($query_params[0]);
580
-        } else {
581
-            $where_params = array();
582
-        }
583
-        // if we have count make sure we don't include group by
584
-        if ($count && isset($query_params['group_by'])) {
585
-            unset($query_params['group_by']);
586
-        }
587
-        // let's add specific query_params for active_events
588
-        // keep in mind this will override any sent status in the query AND any date queries.
589
-        $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
590
-        // if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
591
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
592
-            $where_params['Datetime.DTT_EVT_start*****'] = array(
593
-                '>',
594
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
595
-            );
596
-        } else {
597
-            $where_params['Datetime.DTT_EVT_start'] = array(
598
-                '>',
599
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
600
-            );
601
-        }
602
-        $query_params[0] = $where_params;
603
-        // don't use $query_params with count()
604
-        // because we don't want to include additional query clauses like "GROUP BY"
605
-        return $count
606
-            ? $this->count(array($where_params), 'EVT_ID', true)
607
-            : $this->get_all($query_params);
608
-    }
609
-
610
-
611
-
612
-    /**
613
-     * Gets all events that are published
614
-     * and have an event end time later than now
615
-     *
616
-     * @param  array $query_params An array of query params to further filter on
617
-     *                             (note that status and DTT_EVT_end will be overridden)
618
-     * @param bool   $count        whether to return the count or not (default FALSE)
619
-     * @return EE_Event[]|int
620
-     * @throws \EE_Error
621
-     */
622
-    public function get_active_and_upcoming_events($query_params, $count = false)
623
-    {
624
-        if (array_key_exists(0, $query_params)) {
625
-            $where_params = $query_params[0];
626
-            unset($query_params[0]);
627
-        } else {
628
-            $where_params = array();
629
-        }
630
-        // if we have count make sure we don't include group by
631
-        if ($count && isset($query_params['group_by'])) {
632
-            unset($query_params['group_by']);
633
-        }
634
-        // let's add specific query_params for active_events
635
-        // keep in mind this will override any sent status in the query AND any date queries.
636
-        $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
637
-        // add where params for DTT_EVT_end
638
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
639
-            $where_params['Datetime.DTT_EVT_end*****'] = array(
640
-                '>',
641
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
642
-            );
643
-        } else {
644
-            $where_params['Datetime.DTT_EVT_end'] = array(
645
-                '>',
646
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
647
-            );
648
-        }
649
-        $query_params[0] = $where_params;
650
-        // don't use $query_params with count()
651
-        // because we don't want to include additional query clauses like "GROUP BY"
652
-        return $count
653
-            ? $this->count(array($where_params), 'EVT_ID', true)
654
-            : $this->get_all($query_params);
655
-    }
656
-
657
-
658
-
659
-    /**
660
-     * This only returns events that are expired.
661
-     * They may still be published but all their datetimes have expired.
662
-     *
663
-     * @param  array $query_params An array of query params to further filter on
664
-     *                             (note that status and DTT_EVT_end will be overridden)
665
-     * @param bool   $count        whether to return the count or not (default FALSE)
666
-     * @return EE_Event[]|int
667
-     * @throws \EE_Error
668
-     */
669
-    public function get_expired_events($query_params, $count = false)
670
-    {
671
-        $where_params = isset($query_params[0]) ? $query_params[0] : array();
672
-        // if we have count make sure we don't include group by
673
-        if ($count && isset($query_params['group_by'])) {
674
-            unset($query_params['group_by']);
675
-        }
676
-        // let's add specific query_params for active_events
677
-        // keep in mind this will override any sent status in the query AND any date queries.
678
-        if (isset($where_params['status'])) {
679
-            unset($where_params['status']);
680
-        }
681
-        $exclude_query = $query_params;
682
-        if (isset($exclude_query[0])) {
683
-            unset($exclude_query[0]);
684
-        }
685
-        $exclude_query[0] = array(
686
-            'Datetime.DTT_EVT_end' => array(
687
-                '>',
688
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
689
-            ),
690
-        );
691
-        // first get all events that have datetimes where its not expired.
692
-        $event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID');
693
-        $event_ids = array_keys($event_ids);
694
-        // if we have any additional query_params, let's add them to the 'AND' condition
695
-        $and_condition = array(
696
-            'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')),
697
-            'EVT_ID'               => array('NOT IN', $event_ids),
698
-        );
699
-        if (isset($where_params['OR'])) {
700
-            $and_condition['OR'] = $where_params['OR'];
701
-            unset($where_params['OR']);
702
-        }
703
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
704
-            $and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
705
-            unset($where_params['Datetime.DTT_EVT_end']);
706
-        }
707
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
708
-            $and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
709
-            unset($where_params['Datetime.DTT_EVT_start']);
710
-        }
711
-        // merge remaining $where params with the and conditions.
712
-        $where_params['AND'] = array_merge($and_condition, $where_params);
713
-        $query_params[0] = $where_params;
714
-        // don't use $query_params with count()
715
-        // because we don't want to include additional query clauses like "GROUP BY"
716
-        return $count
717
-            ? $this->count(array($where_params), 'EVT_ID', true)
718
-            : $this->get_all($query_params);
719
-    }
720
-
721
-
722
-
723
-    /**
724
-     * This basically just returns the events that do not have the publish status.
725
-     *
726
-     * @param  array   $query_params An array of query params to further filter on
727
-     *                               (note that status will be overwritten)
728
-     * @param  boolean $count        whether to return the count or not (default FALSE)
729
-     * @return EE_Event[]|int
730
-     * @throws \EE_Error
731
-     */
732
-    public function get_inactive_events($query_params, $count = false)
733
-    {
734
-        $where_params = isset($query_params[0]) ? $query_params[0] : array();
735
-        // let's add in specific query_params for inactive events.
736
-        if (isset($where_params['status'])) {
737
-            unset($where_params['status']);
738
-        }
739
-        // if we have count make sure we don't include group by
740
-        if ($count && isset($query_params['group_by'])) {
741
-            unset($query_params['group_by']);
742
-        }
743
-        // if we have any additional query_params, let's add them to the 'AND' condition
744
-        $where_params['AND']['status'] = array('!=', 'publish');
745
-        if (isset($where_params['OR'])) {
746
-            $where_params['AND']['OR'] = $where_params['OR'];
747
-            unset($where_params['OR']);
748
-        }
749
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
750
-            $where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
751
-            unset($where_params['Datetime.DTT_EVT_end']);
752
-        }
753
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
754
-            $where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
755
-            unset($where_params['Datetime.DTT_EVT_start']);
756
-        }
757
-        $query_params[0] = $where_params;
758
-        // don't use $query_params with count()
759
-        // because we don't want to include additional query clauses like "GROUP BY"
760
-        return $count
761
-            ? $this->count(array($where_params), 'EVT_ID', true)
762
-            : $this->get_all($query_params);
763
-    }
764
-
765
-
766
-
767
-    /**
768
-     * This is just injecting into the parent add_relationship_to so we do special handling on price relationships
769
-     * because we don't want to override any existing global default prices but instead insert NEW prices that get
770
-     * attached to the event. See parent for param descriptions
771
-     *
772
-     * @param        $id_or_obj
773
-     * @param        $other_model_id_or_obj
774
-     * @param string $relationName
775
-     * @param array  $where_query
776
-     * @return EE_Base_Class
777
-     * @throws EE_Error
778
-     */
779
-    public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array())
780
-    {
781
-        if ($relationName === 'Price') {
782
-            // let's get the PRC object for the given ID to make sure that we aren't dealing with a default
783
-            $prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj);
784
-            // if EVT_ID = 0, then this is a default
785
-            if ((int) $prc_chk->get('EVT_ID') === 0) {
786
-                // let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation
787
-                $prc_chk->set('PRC_ID', 0);
788
-            }
789
-            // run parent
790
-            return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query);
791
-        }
792
-        // otherwise carry on as normal
793
-        return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query);
794
-    }
795
-
796
-
797
-
798
-    /******************** DEPRECATED METHODS ********************/
799
-
800
-
801
-
802
-    /**
803
-     * _get_question_target_db_column
804
-     *
805
-     * @deprecated as of 4.8.32.rc.001. Instead consider using
806
-     *             EE_Registration_Custom_Questions_Form located in
807
-     *             admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php
808
-     * @access     public
809
-     * @param    EE_Registration $registration (so existing answers for registration are included)
810
-     * @param    int             $EVT_ID       so all question groups are included for event (not just answers from
811
-     *                                         registration).
812
-     * @throws EE_Error
813
-     * @return    array
814
-     */
815
-    public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0)
816
-    {
817
-        if (empty($EVT_ID)) {
818
-            throw new EE_Error(__(
819
-                'An error occurred. No EVT_ID is included.  Needed to know which question groups to retrieve.',
820
-                'event_espresso'
821
-            ));
822
-        }
823
-        $questions = array();
824
-        // get all question groups for event
825
-        $qgs = $this->get_question_groups_for_event($EVT_ID, $registration);
826
-        if (! empty($qgs)) {
827
-            foreach ($qgs as $qg) {
828
-                $qsts = $qg->questions();
829
-                $questions[ $qg->ID() ] = $qg->model_field_array();
830
-                $questions[ $qg->ID() ]['QSG_questions'] = array();
831
-                foreach ($qsts as $qst) {
832
-                    if ($qst->is_system_question()) {
833
-                        continue;
834
-                    }
835
-                    $answer = EEM_Answer::instance()->get_one(array(
836
-                        array(
837
-                            'QST_ID' => $qst->ID(),
838
-                            'REG_ID' => $registration->ID(),
839
-                        ),
840
-                    ));
841
-                    $answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object();
842
-                    $qst_name = $qstn_id = $qst->ID();
843
-                    $ans_id = $answer->ID();
844
-                    $qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']';
845
-                    $input_name = '';
846
-                    $input_id = sanitize_key($qst->display_text());
847
-                    $input_class = '';
848
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array();
849
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn'
850
-                                                                                           . $input_name
851
-                                                                                           . $qst_name;
852
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id;
853
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class;
854
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array();
855
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst;
856
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer;
857
-                    // leave responses as-is, don't convert stuff into html entities please!
858
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false;
859
-                    if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') {
860
-                        $QSOs = $qst->options(true, $answer->value());
861
-                        if (is_array($QSOs)) {
862
-                            foreach ($QSOs as $QSO_ID => $QSO) {
863
-                                $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array();
864
-                            }
865
-                        }
866
-                    }
867
-                }
868
-            }
869
-        }
870
-        return $questions;
871
-    }
872
-
873
-
874
-    /**
875
-     * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value
876
-     *                             or an stdClass where each property is the name of a column,
877
-     * @return EE_Base_Class
878
-     * @throws \EE_Error
879
-     */
880
-    public function instantiate_class_from_array_or_object($cols_n_values)
881
-    {
882
-        $classInstance = parent::instantiate_class_from_array_or_object($cols_n_values);
883
-        if ($classInstance instanceof EE_Event) {
884
-            // events have their timezone defined in the DB, so use it immediately
885
-            $this->set_timezone($classInstance->get_timezone());
886
-        }
887
-        return $classInstance;
888
-    }
16
+	/**
17
+	 * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the
18
+	 * event
19
+	 */
20
+	const sold_out = 'sold_out';
21
+
22
+	/**
23
+	 * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later
24
+	 * date)
25
+	 */
26
+	const postponed = 'postponed';
27
+
28
+	/**
29
+	 * constant used by status(), indicating that the event will no longer occur
30
+	 */
31
+	const cancelled = 'cancelled';
32
+
33
+
34
+	/**
35
+	 * @var string
36
+	 */
37
+	protected static $_default_reg_status;
38
+
39
+
40
+	/**
41
+	 * This is the default for the additional limit field.
42
+	 * @var int
43
+	 */
44
+	protected static $_default_additional_limit = 10;
45
+
46
+
47
+	/**
48
+	 * private instance of the Event object
49
+	 *
50
+	 * @var EEM_Event
51
+	 */
52
+	protected static $_instance;
53
+
54
+
55
+
56
+
57
+	/**
58
+	 * Adds a relationship to Term_Taxonomy for each CPT_Base
59
+	 *
60
+	 * @param string $timezone
61
+	 * @throws \EE_Error
62
+	 */
63
+	protected function __construct($timezone = null)
64
+	{
65
+		EE_Registry::instance()->load_model('Registration');
66
+		$this->singular_item = esc_html__('Event', 'event_espresso');
67
+		$this->plural_item = esc_html__('Events', 'event_espresso');
68
+		// to remove Cancelled events from the frontend, copy the following filter to your functions.php file
69
+		// add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' );
70
+		// to remove Postponed events from the frontend, copy the following filter to your functions.php file
71
+		// add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' );
72
+		// to remove Sold Out events from the frontend, copy the following filter to your functions.php file
73
+		//  add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' );
74
+		$this->_custom_stati = apply_filters(
75
+			'AFEE__EEM_Event__construct___custom_stati',
76
+			array(
77
+				EEM_Event::cancelled => array(
78
+					'label'  => esc_html__('Cancelled', 'event_espresso'),
79
+					'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true),
80
+				),
81
+				EEM_Event::postponed => array(
82
+					'label'  => esc_html__('Postponed', 'event_espresso'),
83
+					'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true),
84
+				),
85
+				EEM_Event::sold_out  => array(
86
+					'label'  => esc_html__('Sold Out', 'event_espresso'),
87
+					'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true),
88
+				),
89
+			)
90
+		);
91
+		self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment
92
+			: self::$_default_reg_status;
93
+		$this->_tables = array(
94
+			'Event_CPT'  => new EE_Primary_Table('posts', 'ID'),
95
+			'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID'),
96
+		);
97
+		$this->_fields = array(
98
+			'Event_CPT'  => array(
99
+				'EVT_ID'         => new EE_Primary_Key_Int_Field(
100
+					'ID',
101
+					esc_html__('Post ID for Event', 'event_espresso')
102
+				),
103
+				'EVT_name'       => new EE_Plain_Text_Field(
104
+					'post_title',
105
+					esc_html__('Event Name', 'event_espresso'),
106
+					false,
107
+					''
108
+				),
109
+				'EVT_desc'       => new EE_Post_Content_Field(
110
+					'post_content',
111
+					esc_html__('Event Description', 'event_espresso'),
112
+					false,
113
+					''
114
+				),
115
+				'EVT_slug'       => new EE_Slug_Field(
116
+					'post_name',
117
+					esc_html__('Event Slug', 'event_espresso'),
118
+					false,
119
+					''
120
+				),
121
+				'EVT_created'    => new EE_Datetime_Field(
122
+					'post_date',
123
+					esc_html__('Date/Time Event Created', 'event_espresso'),
124
+					false,
125
+					EE_Datetime_Field::now
126
+				),
127
+				'EVT_short_desc' => new EE_Simple_HTML_Field(
128
+					'post_excerpt',
129
+					esc_html__('Event Short Description', 'event_espresso'),
130
+					false,
131
+					''
132
+				),
133
+				'EVT_modified'   => new EE_Datetime_Field(
134
+					'post_modified',
135
+					esc_html__('Date/Time Event Modified', 'event_espresso'),
136
+					false,
137
+					EE_Datetime_Field::now
138
+				),
139
+				'EVT_wp_user'    => new EE_WP_User_Field(
140
+					'post_author',
141
+					esc_html__('Event Creator ID', 'event_espresso'),
142
+					false
143
+				),
144
+				'parent'         => new EE_Integer_Field(
145
+					'post_parent',
146
+					esc_html__('Event Parent ID', 'event_espresso'),
147
+					false,
148
+					0
149
+				),
150
+				'EVT_order'      => new EE_Integer_Field(
151
+					'menu_order',
152
+					esc_html__('Event Menu Order', 'event_espresso'),
153
+					false,
154
+					1
155
+				),
156
+				'post_type'      => new EE_WP_Post_Type_Field('espresso_events'),
157
+				// EE_Plain_Text_Field( 'post_type', esc_html__( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ),
158
+				'status'         => new EE_WP_Post_Status_Field(
159
+					'post_status',
160
+					esc_html__('Event Status', 'event_espresso'),
161
+					false,
162
+					'draft',
163
+					$this->_custom_stati
164
+				),
165
+			),
166
+			'Event_Meta' => array(
167
+				'EVTM_ID'                         => new EE_DB_Only_Float_Field(
168
+					'EVTM_ID',
169
+					esc_html__('Event Meta Row ID', 'event_espresso'),
170
+					false
171
+				),
172
+				'EVT_ID_fk'                       => new EE_DB_Only_Int_Field(
173
+					'EVT_ID',
174
+					esc_html__('Foreign key to Event ID from Event Meta table', 'event_espresso'),
175
+					false
176
+				),
177
+				'EVT_display_desc'                => new EE_Boolean_Field(
178
+					'EVT_display_desc',
179
+					esc_html__('Display Description Flag', 'event_espresso'),
180
+					false,
181
+					1
182
+				),
183
+				'EVT_display_ticket_selector'     => new EE_Boolean_Field(
184
+					'EVT_display_ticket_selector',
185
+					esc_html__('Display Ticket Selector Flag', 'event_espresso'),
186
+					false,
187
+					1
188
+				),
189
+				'EVT_visible_on'                  => new EE_Datetime_Field(
190
+					'EVT_visible_on',
191
+					esc_html__('Event Visible Date', 'event_espresso'),
192
+					true,
193
+					EE_Datetime_Field::now
194
+				),
195
+				'EVT_additional_limit'            => new EE_Integer_Field(
196
+					'EVT_additional_limit',
197
+					esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
198
+					true,
199
+					self::$_default_additional_limit
200
+				),
201
+				'EVT_default_registration_status' => new EE_Enum_Text_Field(
202
+					'EVT_default_registration_status',
203
+					esc_html__('Default Registration Status on this Event', 'event_espresso'),
204
+					false,
205
+					EEM_Event::$_default_reg_status,
206
+					EEM_Registration::reg_status_array()
207
+				),
208
+				'EVT_member_only'                 => new EE_Boolean_Field(
209
+					'EVT_member_only',
210
+					esc_html__('Member-Only Event Flag', 'event_espresso'),
211
+					false,
212
+					false
213
+				),
214
+				'EVT_phone'                       => new EE_Plain_Text_Field(
215
+					'EVT_phone',
216
+					esc_html__('Event Phone Number', 'event_espresso'),
217
+					false,
218
+					''
219
+				),
220
+				'EVT_allow_overflow'              => new EE_Boolean_Field(
221
+					'EVT_allow_overflow',
222
+					esc_html__('Allow Overflow on Event', 'event_espresso'),
223
+					false,
224
+					false
225
+				),
226
+				'EVT_timezone_string'             => new EE_Plain_Text_Field(
227
+					'EVT_timezone_string',
228
+					esc_html__('Timezone (name) for Event times', 'event_espresso'),
229
+					false,
230
+					''
231
+				),
232
+				'EVT_external_URL'                => new EE_Plain_Text_Field(
233
+					'EVT_external_URL',
234
+					esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso'),
235
+					true
236
+				),
237
+				'EVT_donations'                   => new EE_Boolean_Field(
238
+					'EVT_donations',
239
+					esc_html__('Accept Donations?', 'event_espresso'),
240
+					false,
241
+					false
242
+				),
243
+			),
244
+		);
245
+		$this->_model_relations = array(
246
+			'Registration'           => new EE_Has_Many_Relation(),
247
+			'Datetime'               => new EE_Has_Many_Relation(),
248
+			'Question_Group'         => new EE_HABTM_Relation('Event_Question_Group'),
249
+			'Venue'                  => new EE_HABTM_Relation('Event_Venue'),
250
+			'Term_Relationship'      => new EE_Has_Many_Relation(),
251
+			'Term_Taxonomy'          => new EE_HABTM_Relation('Term_Relationship'),
252
+			'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'),
253
+			'Attendee'               => new EE_HABTM_Relation('Registration'),
254
+			'WP_User'                => new EE_Belongs_To_Relation(),
255
+		);
256
+		// this model is generally available for reading
257
+		$this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public();
258
+		parent::__construct($timezone);
259
+	}
260
+
261
+
262
+
263
+	/**
264
+	 * @param string $default_reg_status
265
+	 */
266
+	public static function set_default_reg_status($default_reg_status)
267
+	{
268
+		self::$_default_reg_status = $default_reg_status;
269
+		// if EEM_Event has already been instantiated,
270
+		// then we need to reset the `EVT_default_reg_status` field to use the new default.
271
+		if (self::$_instance instanceof EEM_Event) {
272
+			$default_reg_status = new EE_Enum_Text_Field(
273
+				'EVT_default_registration_status',
274
+				esc_html__('Default Registration Status on this Event', 'event_espresso'),
275
+				false,
276
+				$default_reg_status,
277
+				EEM_Registration::reg_status_array()
278
+			);
279
+			$default_reg_status->_construct_finalize(
280
+				'Event_Meta',
281
+				'EVT_default_registration_status',
282
+				'EEM_Event'
283
+			);
284
+			self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = $default_reg_status;
285
+		}
286
+	}
287
+
288
+
289
+	/**
290
+	 * Used to override the default for the additional limit field.
291
+	 * @param $additional_limit
292
+	 */
293
+	public static function set_default_additional_limit($additional_limit)
294
+	{
295
+		self::$_default_additional_limit = (int) $additional_limit;
296
+		if (self::$_instance instanceof EEM_Event) {
297
+			self::$_instance->_fields['Event_Meta']['EVT_additional_limit'] = new EE_Integer_Field(
298
+				'EVT_additional_limit',
299
+				__('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
300
+				true,
301
+				self::$_default_additional_limit
302
+			);
303
+			self::$_instance->_fields['Event_Meta']['EVT_additional_limit']->_construct_finalize(
304
+				'Event_Meta',
305
+				'EVT_additional_limit',
306
+				'EEM_Event'
307
+			);
308
+		}
309
+	}
310
+
311
+
312
+	/**
313
+	 * Return what is currently set as the default additional limit for the event.
314
+	 * @return int
315
+	 */
316
+	public static function get_default_additional_limit()
317
+	{
318
+		return apply_filters('FHEE__EEM_Event__get_default_additional_limit', self::$_default_additional_limit);
319
+	}
320
+
321
+
322
+	/**
323
+	 * get_question_groups
324
+	 *
325
+	 * @return array
326
+	 * @throws \EE_Error
327
+	 */
328
+	public function get_all_question_groups()
329
+	{
330
+		return EE_Registry::instance()->load_model('Question_Group')->get_all(
331
+			array(
332
+				array('QSG_deleted' => false),
333
+				'order_by' => array('QSG_order' => 'ASC'),
334
+			)
335
+		);
336
+	}
337
+
338
+
339
+
340
+	/**
341
+	 * get_question_groups
342
+	 *
343
+	 * @param int $EVT_ID
344
+	 * @return array|bool
345
+	 * @throws \EE_Error
346
+	 */
347
+	public function get_all_event_question_groups($EVT_ID = 0)
348
+	{
349
+		if (! isset($EVT_ID) || ! absint($EVT_ID)) {
350
+			EE_Error::add_error(
351
+				esc_html__(
352
+					'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
353
+					'event_espresso'
354
+				),
355
+				__FILE__,
356
+				__FUNCTION__,
357
+				__LINE__
358
+			);
359
+			return false;
360
+		}
361
+		return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(
362
+			array(
363
+				array('EVT_ID' => $EVT_ID),
364
+			)
365
+		);
366
+	}
367
+
368
+
369
+
370
+	/**
371
+	 * get_question_groups
372
+	 *
373
+	 * @param int     $EVT_ID
374
+	 * @param boolean $for_primary_attendee
375
+	 * @return array|bool
376
+	 * @throws \EE_Error
377
+	 */
378
+	public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true)
379
+	{
380
+		if (! isset($EVT_ID) || ! absint($EVT_ID)) {
381
+			EE_Error::add_error(
382
+				esc_html__(
383
+					'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
384
+					'event_espresso'
385
+				),
386
+				__FILE__,
387
+				__FUNCTION__,
388
+				__LINE__
389
+			);
390
+			return false;
391
+		}
392
+		return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(
393
+			array(
394
+				array(
395
+					'EVT_ID'      => $EVT_ID,
396
+					'EQG_primary' => $for_primary_attendee,
397
+				),
398
+			)
399
+		);
400
+	}
401
+
402
+
403
+
404
+	/**
405
+	 * get_question_groups
406
+	 *
407
+	 * @param int             $EVT_ID
408
+	 * @param EE_Registration $registration
409
+	 * @return array|bool
410
+	 * @throws \EE_Error
411
+	 */
412
+	public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration)
413
+	{
414
+		if (! isset($EVT_ID) || ! absint($EVT_ID)) {
415
+			EE_Error::add_error(
416
+				esc_html__(
417
+					'An error occurred. No Question Groups could be retrieved because an Event ID was not received.',
418
+					'event_espresso'
419
+				),
420
+				__FILE__,
421
+				__FUNCTION__,
422
+				__LINE__
423
+			);
424
+			return false;
425
+		}
426
+		$where_params = array(
427
+			'Event_Question_Group.EVT_ID'      => $EVT_ID,
428
+			'Event_Question_Group.EQG_primary' => $registration->count() === 1 ? true : false,
429
+			'QSG_deleted'                      => false,
430
+		);
431
+		return EE_Registry::instance()->load_model('Question_Group')->get_all(
432
+			array(
433
+				$where_params,
434
+				'order_by' => array('QSG_order' => 'ASC'),
435
+			)
436
+		);
437
+	}
438
+
439
+
440
+
441
+	/**
442
+	 * get_question_target_db_column
443
+	 *
444
+	 * @param string $QSG_IDs csv list of $QSG IDs
445
+	 * @return array|bool
446
+	 * @throws \EE_Error
447
+	 */
448
+	public function get_questions_in_groups($QSG_IDs = '')
449
+	{
450
+		if (empty($QSG_IDs)) {
451
+			EE_Error::add_error(
452
+				esc_html__('An error occurred. No Question Group IDs were received.', 'event_espresso'),
453
+				__FILE__,
454
+				__FUNCTION__,
455
+				__LINE__
456
+			);
457
+			return false;
458
+		}
459
+		return EE_Registry::instance()->load_model('Question')->get_all(
460
+			array(
461
+				array(
462
+					'Question_Group.QSG_ID' => array('IN', $QSG_IDs),
463
+					'QST_deleted'           => false,
464
+					'QST_admin_only'        => is_admin(),
465
+				),
466
+				'order_by' => 'QST_order',
467
+			)
468
+		);
469
+	}
470
+
471
+
472
+
473
+	/**
474
+	 * get_options_for_question
475
+	 *
476
+	 * @param string $QST_IDs csv list of $QST IDs
477
+	 * @return array|bool
478
+	 * @throws \EE_Error
479
+	 */
480
+	public function get_options_for_question($QST_IDs)
481
+	{
482
+		if (empty($QST_IDs)) {
483
+			EE_Error::add_error(
484
+				esc_html__('An error occurred. No Question IDs were received.', 'event_espresso'),
485
+				__FILE__,
486
+				__FUNCTION__,
487
+				__LINE__
488
+			);
489
+			return false;
490
+		}
491
+		return EE_Registry::instance()->load_model('Question_Option')->get_all(
492
+			array(
493
+				array(
494
+					'Question.QST_ID' => array('IN', $QST_IDs),
495
+					'QSO_deleted'     => false,
496
+				),
497
+				'order_by' => 'QSO_ID',
498
+			)
499
+		);
500
+	}
501
+
502
+
503
+
504
+
505
+
506
+
507
+
508
+	/**
509
+	 * Gets all events that are published
510
+	 * and have event start time earlier than now and an event end time later than now
511
+	 *
512
+	 * @param  array $query_params An array of query params to further filter on
513
+	 *                             (note that status and DTT_EVT_start and DTT_EVT_end will be overridden)
514
+	 * @param bool   $count        whether to return the count or not (default FALSE)
515
+	 * @return EE_Event[]|int
516
+	 * @throws \EE_Error
517
+	 */
518
+	public function get_active_events($query_params, $count = false)
519
+	{
520
+		if (array_key_exists(0, $query_params)) {
521
+			$where_params = $query_params[0];
522
+			unset($query_params[0]);
523
+		} else {
524
+			$where_params = array();
525
+		}
526
+		// if we have count make sure we don't include group by
527
+		if ($count && isset($query_params['group_by'])) {
528
+			unset($query_params['group_by']);
529
+		}
530
+		// let's add specific query_params for active_events
531
+		// keep in mind this will override any sent status in the query AND any date queries.
532
+		$where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
533
+		// if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions
534
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
535
+			$where_params['Datetime.DTT_EVT_start******'] = array(
536
+				'<',
537
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
538
+			);
539
+		} else {
540
+			$where_params['Datetime.DTT_EVT_start'] = array(
541
+				'<',
542
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
543
+			);
544
+		}
545
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
546
+			$where_params['Datetime.DTT_EVT_end*****'] = array(
547
+				'>',
548
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
549
+			);
550
+		} else {
551
+			$where_params['Datetime.DTT_EVT_end'] = array(
552
+				'>',
553
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
554
+			);
555
+		}
556
+		$query_params[0] = $where_params;
557
+		// don't use $query_params with count()
558
+		// because we don't want to include additional query clauses like "GROUP BY"
559
+		return $count
560
+			? $this->count(array($where_params), 'EVT_ID', true)
561
+			: $this->get_all($query_params);
562
+	}
563
+
564
+
565
+
566
+	/**
567
+	 * get all events that are published and have an event start time later than now
568
+	 *
569
+	 * @param  array $query_params An array of query params to further filter on
570
+	 *                             (Note that status and DTT_EVT_start will be overridden)
571
+	 * @param bool   $count        whether to return the count or not (default FALSE)
572
+	 * @return EE_Event[]|int
573
+	 * @throws \EE_Error
574
+	 */
575
+	public function get_upcoming_events($query_params, $count = false)
576
+	{
577
+		if (array_key_exists(0, $query_params)) {
578
+			$where_params = $query_params[0];
579
+			unset($query_params[0]);
580
+		} else {
581
+			$where_params = array();
582
+		}
583
+		// if we have count make sure we don't include group by
584
+		if ($count && isset($query_params['group_by'])) {
585
+			unset($query_params['group_by']);
586
+		}
587
+		// let's add specific query_params for active_events
588
+		// keep in mind this will override any sent status in the query AND any date queries.
589
+		$where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
590
+		// if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
591
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
592
+			$where_params['Datetime.DTT_EVT_start*****'] = array(
593
+				'>',
594
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
595
+			);
596
+		} else {
597
+			$where_params['Datetime.DTT_EVT_start'] = array(
598
+				'>',
599
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
600
+			);
601
+		}
602
+		$query_params[0] = $where_params;
603
+		// don't use $query_params with count()
604
+		// because we don't want to include additional query clauses like "GROUP BY"
605
+		return $count
606
+			? $this->count(array($where_params), 'EVT_ID', true)
607
+			: $this->get_all($query_params);
608
+	}
609
+
610
+
611
+
612
+	/**
613
+	 * Gets all events that are published
614
+	 * and have an event end time later than now
615
+	 *
616
+	 * @param  array $query_params An array of query params to further filter on
617
+	 *                             (note that status and DTT_EVT_end will be overridden)
618
+	 * @param bool   $count        whether to return the count or not (default FALSE)
619
+	 * @return EE_Event[]|int
620
+	 * @throws \EE_Error
621
+	 */
622
+	public function get_active_and_upcoming_events($query_params, $count = false)
623
+	{
624
+		if (array_key_exists(0, $query_params)) {
625
+			$where_params = $query_params[0];
626
+			unset($query_params[0]);
627
+		} else {
628
+			$where_params = array();
629
+		}
630
+		// if we have count make sure we don't include group by
631
+		if ($count && isset($query_params['group_by'])) {
632
+			unset($query_params['group_by']);
633
+		}
634
+		// let's add specific query_params for active_events
635
+		// keep in mind this will override any sent status in the query AND any date queries.
636
+		$where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
637
+		// add where params for DTT_EVT_end
638
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
639
+			$where_params['Datetime.DTT_EVT_end*****'] = array(
640
+				'>',
641
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
642
+			);
643
+		} else {
644
+			$where_params['Datetime.DTT_EVT_end'] = array(
645
+				'>',
646
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
647
+			);
648
+		}
649
+		$query_params[0] = $where_params;
650
+		// don't use $query_params with count()
651
+		// because we don't want to include additional query clauses like "GROUP BY"
652
+		return $count
653
+			? $this->count(array($where_params), 'EVT_ID', true)
654
+			: $this->get_all($query_params);
655
+	}
656
+
657
+
658
+
659
+	/**
660
+	 * This only returns events that are expired.
661
+	 * They may still be published but all their datetimes have expired.
662
+	 *
663
+	 * @param  array $query_params An array of query params to further filter on
664
+	 *                             (note that status and DTT_EVT_end will be overridden)
665
+	 * @param bool   $count        whether to return the count or not (default FALSE)
666
+	 * @return EE_Event[]|int
667
+	 * @throws \EE_Error
668
+	 */
669
+	public function get_expired_events($query_params, $count = false)
670
+	{
671
+		$where_params = isset($query_params[0]) ? $query_params[0] : array();
672
+		// if we have count make sure we don't include group by
673
+		if ($count && isset($query_params['group_by'])) {
674
+			unset($query_params['group_by']);
675
+		}
676
+		// let's add specific query_params for active_events
677
+		// keep in mind this will override any sent status in the query AND any date queries.
678
+		if (isset($where_params['status'])) {
679
+			unset($where_params['status']);
680
+		}
681
+		$exclude_query = $query_params;
682
+		if (isset($exclude_query[0])) {
683
+			unset($exclude_query[0]);
684
+		}
685
+		$exclude_query[0] = array(
686
+			'Datetime.DTT_EVT_end' => array(
687
+				'>',
688
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
689
+			),
690
+		);
691
+		// first get all events that have datetimes where its not expired.
692
+		$event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID');
693
+		$event_ids = array_keys($event_ids);
694
+		// if we have any additional query_params, let's add them to the 'AND' condition
695
+		$and_condition = array(
696
+			'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')),
697
+			'EVT_ID'               => array('NOT IN', $event_ids),
698
+		);
699
+		if (isset($where_params['OR'])) {
700
+			$and_condition['OR'] = $where_params['OR'];
701
+			unset($where_params['OR']);
702
+		}
703
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
704
+			$and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
705
+			unset($where_params['Datetime.DTT_EVT_end']);
706
+		}
707
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
708
+			$and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
709
+			unset($where_params['Datetime.DTT_EVT_start']);
710
+		}
711
+		// merge remaining $where params with the and conditions.
712
+		$where_params['AND'] = array_merge($and_condition, $where_params);
713
+		$query_params[0] = $where_params;
714
+		// don't use $query_params with count()
715
+		// because we don't want to include additional query clauses like "GROUP BY"
716
+		return $count
717
+			? $this->count(array($where_params), 'EVT_ID', true)
718
+			: $this->get_all($query_params);
719
+	}
720
+
721
+
722
+
723
+	/**
724
+	 * This basically just returns the events that do not have the publish status.
725
+	 *
726
+	 * @param  array   $query_params An array of query params to further filter on
727
+	 *                               (note that status will be overwritten)
728
+	 * @param  boolean $count        whether to return the count or not (default FALSE)
729
+	 * @return EE_Event[]|int
730
+	 * @throws \EE_Error
731
+	 */
732
+	public function get_inactive_events($query_params, $count = false)
733
+	{
734
+		$where_params = isset($query_params[0]) ? $query_params[0] : array();
735
+		// let's add in specific query_params for inactive events.
736
+		if (isset($where_params['status'])) {
737
+			unset($where_params['status']);
738
+		}
739
+		// if we have count make sure we don't include group by
740
+		if ($count && isset($query_params['group_by'])) {
741
+			unset($query_params['group_by']);
742
+		}
743
+		// if we have any additional query_params, let's add them to the 'AND' condition
744
+		$where_params['AND']['status'] = array('!=', 'publish');
745
+		if (isset($where_params['OR'])) {
746
+			$where_params['AND']['OR'] = $where_params['OR'];
747
+			unset($where_params['OR']);
748
+		}
749
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
750
+			$where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
751
+			unset($where_params['Datetime.DTT_EVT_end']);
752
+		}
753
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
754
+			$where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
755
+			unset($where_params['Datetime.DTT_EVT_start']);
756
+		}
757
+		$query_params[0] = $where_params;
758
+		// don't use $query_params with count()
759
+		// because we don't want to include additional query clauses like "GROUP BY"
760
+		return $count
761
+			? $this->count(array($where_params), 'EVT_ID', true)
762
+			: $this->get_all($query_params);
763
+	}
764
+
765
+
766
+
767
+	/**
768
+	 * This is just injecting into the parent add_relationship_to so we do special handling on price relationships
769
+	 * because we don't want to override any existing global default prices but instead insert NEW prices that get
770
+	 * attached to the event. See parent for param descriptions
771
+	 *
772
+	 * @param        $id_or_obj
773
+	 * @param        $other_model_id_or_obj
774
+	 * @param string $relationName
775
+	 * @param array  $where_query
776
+	 * @return EE_Base_Class
777
+	 * @throws EE_Error
778
+	 */
779
+	public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array())
780
+	{
781
+		if ($relationName === 'Price') {
782
+			// let's get the PRC object for the given ID to make sure that we aren't dealing with a default
783
+			$prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj);
784
+			// if EVT_ID = 0, then this is a default
785
+			if ((int) $prc_chk->get('EVT_ID') === 0) {
786
+				// let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation
787
+				$prc_chk->set('PRC_ID', 0);
788
+			}
789
+			// run parent
790
+			return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query);
791
+		}
792
+		// otherwise carry on as normal
793
+		return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query);
794
+	}
795
+
796
+
797
+
798
+	/******************** DEPRECATED METHODS ********************/
799
+
800
+
801
+
802
+	/**
803
+	 * _get_question_target_db_column
804
+	 *
805
+	 * @deprecated as of 4.8.32.rc.001. Instead consider using
806
+	 *             EE_Registration_Custom_Questions_Form located in
807
+	 *             admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php
808
+	 * @access     public
809
+	 * @param    EE_Registration $registration (so existing answers for registration are included)
810
+	 * @param    int             $EVT_ID       so all question groups are included for event (not just answers from
811
+	 *                                         registration).
812
+	 * @throws EE_Error
813
+	 * @return    array
814
+	 */
815
+	public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0)
816
+	{
817
+		if (empty($EVT_ID)) {
818
+			throw new EE_Error(__(
819
+				'An error occurred. No EVT_ID is included.  Needed to know which question groups to retrieve.',
820
+				'event_espresso'
821
+			));
822
+		}
823
+		$questions = array();
824
+		// get all question groups for event
825
+		$qgs = $this->get_question_groups_for_event($EVT_ID, $registration);
826
+		if (! empty($qgs)) {
827
+			foreach ($qgs as $qg) {
828
+				$qsts = $qg->questions();
829
+				$questions[ $qg->ID() ] = $qg->model_field_array();
830
+				$questions[ $qg->ID() ]['QSG_questions'] = array();
831
+				foreach ($qsts as $qst) {
832
+					if ($qst->is_system_question()) {
833
+						continue;
834
+					}
835
+					$answer = EEM_Answer::instance()->get_one(array(
836
+						array(
837
+							'QST_ID' => $qst->ID(),
838
+							'REG_ID' => $registration->ID(),
839
+						),
840
+					));
841
+					$answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object();
842
+					$qst_name = $qstn_id = $qst->ID();
843
+					$ans_id = $answer->ID();
844
+					$qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']';
845
+					$input_name = '';
846
+					$input_id = sanitize_key($qst->display_text());
847
+					$input_class = '';
848
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array();
849
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn'
850
+																						   . $input_name
851
+																						   . $qst_name;
852
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id;
853
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class;
854
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array();
855
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst;
856
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer;
857
+					// leave responses as-is, don't convert stuff into html entities please!
858
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false;
859
+					if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') {
860
+						$QSOs = $qst->options(true, $answer->value());
861
+						if (is_array($QSOs)) {
862
+							foreach ($QSOs as $QSO_ID => $QSO) {
863
+								$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array();
864
+							}
865
+						}
866
+					}
867
+				}
868
+			}
869
+		}
870
+		return $questions;
871
+	}
872
+
873
+
874
+	/**
875
+	 * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value
876
+	 *                             or an stdClass where each property is the name of a column,
877
+	 * @return EE_Base_Class
878
+	 * @throws \EE_Error
879
+	 */
880
+	public function instantiate_class_from_array_or_object($cols_n_values)
881
+	{
882
+		$classInstance = parent::instantiate_class_from_array_or_object($cols_n_values);
883
+		if ($classInstance instanceof EE_Event) {
884
+			// events have their timezone defined in the DB, so use it immediately
885
+			$this->set_timezone($classInstance->get_timezone());
886
+		}
887
+		return $classInstance;
888
+	}
889 889
 }
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -254,7 +254,7 @@  discard block
 block discarded – undo
254 254
             'WP_User'                => new EE_Belongs_To_Relation(),
255 255
         );
256 256
         // this model is generally available for reading
257
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public();
257
+        $this->_cap_restriction_generators[EEM_Base::caps_read] = new EE_Restriction_Generator_Public();
258 258
         parent::__construct($timezone);
259 259
     }
260 260
 
@@ -346,7 +346,7 @@  discard block
 block discarded – undo
346 346
      */
347 347
     public function get_all_event_question_groups($EVT_ID = 0)
348 348
     {
349
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
349
+        if ( ! isset($EVT_ID) || ! absint($EVT_ID)) {
350 350
             EE_Error::add_error(
351 351
                 esc_html__(
352 352
                     'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
@@ -377,7 +377,7 @@  discard block
 block discarded – undo
377 377
      */
378 378
     public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true)
379 379
     {
380
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
380
+        if ( ! isset($EVT_ID) || ! absint($EVT_ID)) {
381 381
             EE_Error::add_error(
382 382
                 esc_html__(
383 383
                     'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
@@ -411,7 +411,7 @@  discard block
 block discarded – undo
411 411
      */
412 412
     public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration)
413 413
     {
414
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
414
+        if ( ! isset($EVT_ID) || ! absint($EVT_ID)) {
415 415
             EE_Error::add_error(
416 416
                 esc_html__(
417 417
                     'An error occurred. No Question Groups could be retrieved because an Event ID was not received.',
@@ -823,11 +823,11 @@  discard block
 block discarded – undo
823 823
         $questions = array();
824 824
         // get all question groups for event
825 825
         $qgs = $this->get_question_groups_for_event($EVT_ID, $registration);
826
-        if (! empty($qgs)) {
826
+        if ( ! empty($qgs)) {
827 827
             foreach ($qgs as $qg) {
828 828
                 $qsts = $qg->questions();
829
-                $questions[ $qg->ID() ] = $qg->model_field_array();
830
-                $questions[ $qg->ID() ]['QSG_questions'] = array();
829
+                $questions[$qg->ID()] = $qg->model_field_array();
830
+                $questions[$qg->ID()]['QSG_questions'] = array();
831 831
                 foreach ($qsts as $qst) {
832 832
                     if ($qst->is_system_question()) {
833 833
                         continue;
@@ -841,26 +841,26 @@  discard block
 block discarded – undo
841 841
                     $answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object();
842 842
                     $qst_name = $qstn_id = $qst->ID();
843 843
                     $ans_id = $answer->ID();
844
-                    $qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']';
844
+                    $qst_name = ! empty($ans_id) ? '['.$qst_name.']['.$ans_id.']' : '['.$qst_name.']';
845 845
                     $input_name = '';
846 846
                     $input_id = sanitize_key($qst->display_text());
847 847
                     $input_class = '';
848
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array();
849
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn'
848
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()] = $qst->model_field_array();
849
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_input_name'] = 'qstn'
850 850
                                                                                            . $input_name
851 851
                                                                                            . $qst_name;
852
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id;
853
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class;
854
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array();
855
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst;
856
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer;
852
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_input_id'] = $input_id.'-'.$qstn_id;
853
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_input_class'] = $input_class;
854
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_options'] = array();
855
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['qst_obj'] = $qst;
856
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['ans_obj'] = $answer;
857 857
                     // leave responses as-is, don't convert stuff into html entities please!
858
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false;
858
+                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['htmlentities'] = false;
859 859
                     if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') {
860 860
                         $QSOs = $qst->options(true, $answer->value());
861 861
                         if (is_array($QSOs)) {
862 862
                             foreach ($QSOs as $QSO_ID => $QSO) {
863
-                                $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array();
863
+                                $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_options'][$QSO_ID] = $QSO->model_field_array();
864 864
                             }
865 865
                         }
866 866
                     }
Please login to merge, or discard this patch.
events/help_tabs/events_default_settings_max_tickets.help_tab.php 1 patch
Indentation   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <p>
2 2
     <?php esc_html_e(
3
-        'Use this to control what the default will be for maximum tickets on an order when creating a new event.',
4
-        'event_espresso'
5
-    ); ?>
3
+		'Use this to control what the default will be for maximum tickets on an order when creating a new event.',
4
+		'event_espresso'
5
+	); ?>
6 6
 </p>
7 7
\ No newline at end of file
Please login to merge, or discard this patch.
core/services/notices/ConvertNoticesToEeErrors.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -43,7 +43,7 @@
 block discarded – undo
43 43
             $error_string = esc_html__('The following errors occurred:', 'event_espresso');
44 44
             foreach ($notices->getError() as $notice) {
45 45
                 if ($this->getThrowExceptions()) {
46
-                    $error_string .= '<br />' . $notice->message();
46
+                    $error_string .= '<br />'.$notice->message();
47 47
                 } else {
48 48
                     EE_Error::add_error(
49 49
                         $notice->message(),
Please login to merge, or discard this patch.
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -19,56 +19,56 @@
 block discarded – undo
19 19
 class ConvertNoticesToEeErrors extends NoticeConverter
20 20
 {
21 21
 
22
-    /**
23
-     * Converts Notice objects into EE_Error notifications
24
-     *
25
-     * @param NoticesContainerInterface $notices
26
-     * @throws EE_Error
27
-     */
28
-    public function process(NoticesContainerInterface $notices)
29
-    {
30
-        $this->setNotices($notices);
31
-        $notices = $this->getNotices();
32
-        if ($notices->hasAttention()) {
33
-            foreach ($notices->getAttention() as $notice) {
34
-                EE_Error::add_attention(
35
-                    $notice->message(),
36
-                    $notice->file(),
37
-                    $notice->func(),
38
-                    $notice->line()
39
-                );
40
-            }
41
-        }
42
-        if ($notices->hasError()) {
43
-            $error_string = esc_html__('The following errors occurred:', 'event_espresso');
44
-            foreach ($notices->getError() as $notice) {
45
-                if ($this->getThrowExceptions()) {
46
-                    $error_string .= '<br />' . $notice->message();
47
-                } else {
48
-                    EE_Error::add_error(
49
-                        $notice->message(),
50
-                        $notice->file(),
51
-                        $notice->func(),
52
-                        $notice->line()
53
-                    );
54
-                }
55
-            }
56
-            if ($this->getThrowExceptions()) {
57
-                throw new EE_Error($error_string);
58
-            }
59
-        }
60
-        if ($notices->hasSuccess()) {
61
-            foreach ($notices->getSuccess() as $notice) {
62
-                EE_Error::add_success(
63
-                    $notice->message(),
64
-                    $notice->file(),
65
-                    $notice->func(),
66
-                    $notice->line()
67
-                );
68
-            }
69
-        }
70
-        $this->clearNotices();
71
-    }
22
+	/**
23
+	 * Converts Notice objects into EE_Error notifications
24
+	 *
25
+	 * @param NoticesContainerInterface $notices
26
+	 * @throws EE_Error
27
+	 */
28
+	public function process(NoticesContainerInterface $notices)
29
+	{
30
+		$this->setNotices($notices);
31
+		$notices = $this->getNotices();
32
+		if ($notices->hasAttention()) {
33
+			foreach ($notices->getAttention() as $notice) {
34
+				EE_Error::add_attention(
35
+					$notice->message(),
36
+					$notice->file(),
37
+					$notice->func(),
38
+					$notice->line()
39
+				);
40
+			}
41
+		}
42
+		if ($notices->hasError()) {
43
+			$error_string = esc_html__('The following errors occurred:', 'event_espresso');
44
+			foreach ($notices->getError() as $notice) {
45
+				if ($this->getThrowExceptions()) {
46
+					$error_string .= '<br />' . $notice->message();
47
+				} else {
48
+					EE_Error::add_error(
49
+						$notice->message(),
50
+						$notice->file(),
51
+						$notice->func(),
52
+						$notice->line()
53
+					);
54
+				}
55
+			}
56
+			if ($this->getThrowExceptions()) {
57
+				throw new EE_Error($error_string);
58
+			}
59
+		}
60
+		if ($notices->hasSuccess()) {
61
+			foreach ($notices->getSuccess() as $notice) {
62
+				EE_Error::add_success(
63
+					$notice->message(),
64
+					$notice->file(),
65
+					$notice->func(),
66
+					$notice->line()
67
+				);
68
+			}
69
+		}
70
+		$this->clearNotices();
71
+	}
72 72
 
73 73
 
74 74
 }
Please login to merge, or discard this patch.
public/Espresso_Arabica_2014/loop-espresso_events.php 2 patches
Indentation   +34 added lines, -34 removed lines patch added patch discarded remove patch
@@ -11,48 +11,48 @@
 block discarded – undo
11 11
  * @version     4+
12 12
  */
13 13
 if (have_posts()) :
14
-    if (apply_filters('FHEE__archive_espresso_events_template__show_header', true)) : ?>
14
+	if (apply_filters('FHEE__archive_espresso_events_template__show_header', true)) : ?>
15 15
         <header class="page-header">
16 16
             <h1 class="page-title">
17 17
                 <?php
18
-                if (is_day()) :
19
-                    printf(__('Today\'s Events: %s', 'event_espresso'), get_the_date());
20
-                elseif (is_month()) :
21
-                    printf(
22
-                        __('Events This Month: %s', 'event_espresso'),
23
-                        get_the_date(_x('F Y', 'monthly archives date format', 'event_espresso'))
24
-                    );
25
-                elseif (is_year()) :
26
-                    printf(
27
-                        __('Events This Year: %s', 'event_espresso'),
28
-                        get_the_date(_x('Y', 'yearly archives date format', 'event_espresso'))
29
-                    );
30
-                else :
31
-                    echo apply_filters(
32
-                        'FHEE__archive_espresso_events_template__upcoming_events_h1',
33
-                        __('Upcoming Events', 'event_espresso')
34
-                    );
35
-                endif;
36
-                ?>
18
+				if (is_day()) :
19
+					printf(__('Today\'s Events: %s', 'event_espresso'), get_the_date());
20
+				elseif (is_month()) :
21
+					printf(
22
+						__('Events This Month: %s', 'event_espresso'),
23
+						get_the_date(_x('F Y', 'monthly archives date format', 'event_espresso'))
24
+					);
25
+				elseif (is_year()) :
26
+					printf(
27
+						__('Events This Year: %s', 'event_espresso'),
28
+						get_the_date(_x('Y', 'yearly archives date format', 'event_espresso'))
29
+					);
30
+				else :
31
+					echo apply_filters(
32
+						'FHEE__archive_espresso_events_template__upcoming_events_h1',
33
+						__('Upcoming Events', 'event_espresso')
34
+					);
35
+				endif;
36
+				?>
37 37
             </h1>
38 38
 
39 39
         </header><!-- .page-header -->
40 40
 
41 41
         <?php
42
-    endif;
43
-    // allow other stuff
44
-    do_action('AHEE__archive_espresso_events_template__before_loop');
45
-    // Start the Loop.
46
-    while (have_posts()) : the_post();
47
-        // Include the post TYPE-specific template for the content.
48
-        espresso_get_template_part('content', 'espresso_events-shortcode');
49
-    endwhile;
50
-    // Previous/next page navigation.
51
-    espresso_pagination();
52
-    // allow moar other stuff
53
-    do_action('AHEE__archive_espresso_events_template__after_loop');
42
+	endif;
43
+	// allow other stuff
44
+	do_action('AHEE__archive_espresso_events_template__before_loop');
45
+	// Start the Loop.
46
+	while (have_posts()) : the_post();
47
+		// Include the post TYPE-specific template for the content.
48
+		espresso_get_template_part('content', 'espresso_events-shortcode');
49
+	endwhile;
50
+	// Previous/next page navigation.
51
+	espresso_pagination();
52
+	// allow moar other stuff
53
+	do_action('AHEE__archive_espresso_events_template__after_loop');
54 54
 else :
55
-    // If no content, include the "No posts found" template.
56
-    espresso_get_template_part('content', 'none');
55
+	// If no content, include the "No posts found" template.
56
+	espresso_get_template_part('content', 'none');
57 57
 endif;
58 58
 
Please login to merge, or discard this patch.
Braces   +6 added lines, -2 removed lines patch added patch discarded remove patch
@@ -27,11 +27,13 @@  discard block
 block discarded – undo
27 27
                         __('Events This Year: %s', 'event_espresso'),
28 28
                         get_the_date(_x('Y', 'yearly archives date format', 'event_espresso'))
29 29
                     );
30
-                else :
30
+                else {
31
+                	:
31 32
                     echo apply_filters(
32 33
                         'FHEE__archive_espresso_events_template__upcoming_events_h1',
33 34
                         __('Upcoming Events', 'event_espresso')
34 35
                     );
36
+                }
35 37
                 endif;
36 38
                 ?>
37 39
             </h1>
@@ -51,8 +53,10 @@  discard block
 block discarded – undo
51 53
     espresso_pagination();
52 54
     // allow moar other stuff
53 55
     do_action('AHEE__archive_espresso_events_template__after_loop');
54
-else :
56
+else {
57
+	:
55 58
     // If no content, include the "No posts found" template.
56 59
     espresso_get_template_part('content', 'none');
60
+}
57 61
 endif;
58 62
 
Please login to merge, or discard this patch.
caffeinated/payment_methods/Paypal_Pro/EEG_Paypal_Pro.gateway.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -450,7 +450,7 @@
 block discarded – undo
450 450
 
451 451
 
452 452
     /**
453
-     * @param $Request
453
+     * @param string $Request
454 454
      * @return mixed
455 455
      */
456 456
     private function _CURLRequest($Request)
Please login to merge, or discard this patch.
Spacing   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -77,13 +77,13 @@  discard block
 block discarded – undo
77 77
     public function do_direct_payment($payment, $billing_info = null)
78 78
     {
79 79
         $transaction = $payment->transaction();
80
-        if (! $transaction instanceof EEI_Transaction) {
80
+        if ( ! $transaction instanceof EEI_Transaction) {
81 81
             throw new EE_Error(
82 82
                 esc_html__('No transaction for payment while paying with PayPal Pro.', 'event_espresso')
83 83
             );
84 84
         }
85 85
         $primary_registrant = $transaction->primary_registration();
86
-        if (! $primary_registrant instanceof EEI_Registration) {
86
+        if ( ! $primary_registrant instanceof EEI_Registration) {
87 87
             throw new EE_Error(
88 88
                 esc_html__(
89 89
                     'No primary registration on transaction while paying with PayPal Pro.',
@@ -92,7 +92,7 @@  discard block
 block discarded – undo
92 92
             );
93 93
         }
94 94
         $attendee = $primary_registrant->attendee();
95
-        if (! $attendee instanceof EEI_Attendee) {
95
+        if ( ! $attendee instanceof EEI_Attendee) {
96 96
             throw new EE_Error(
97 97
                 esc_html__(
98 98
                     'No attendee on primary registration while paying with PayPal Pro.',
@@ -189,7 +189,7 @@  discard block
 block discarded – undo
189 189
             // Required.  Credit card number.  No spaces or punctuation.
190 190
             'acct'           => $billing_info['credit_card'],
191 191
             // Required.  Credit card expiration date.  Format is MMYYYY
192
-            'expdate'        => $billing_info['exp_month'] . $billing_info['exp_year'],
192
+            'expdate'        => $billing_info['exp_month'].$billing_info['exp_year'],
193 193
             // Requirements determined by your PayPal account settings.  Security digits for credit card.
194 194
             'cvv2'           => $billing_info['cvv'],
195 195
         );
@@ -241,7 +241,7 @@  discard block
 block discarded – undo
241 241
         $ShippingAddress = array(
242 242
             'shiptoname'     => substr($use_registration_address_info
243 243
                 ? $attendee->full_name()
244
-                : $billing_info['first_name'] . ' ' . $billing_info['last_name'], 0, 32),
244
+                : $billing_info['first_name'].' '.$billing_info['last_name'], 0, 32),
245 245
             'shiptostreet'   => substr($use_registration_address_info
246 246
                 ? $attendee->address()
247 247
                 : $billing_info['address'], 0, 100),
@@ -270,7 +270,7 @@  discard block
 block discarded – undo
270 270
             'currencycode' => $payment->currency_code(),
271 271
             // Required if you include itemized cart details. (L_AMTn, etc.)
272 272
             // Subtotal of items not including S&H, or tax.
273
-            'itemamt'      => $gateway_formatter->formatCurrency($item_amount),//
273
+            'itemamt'      => $gateway_formatter->formatCurrency($item_amount), //
274 274
             // Total shipping costs for the order.  If you specify shippingamt, you must also specify itemamt.
275 275
             'shippingamt'  => '',
276 276
             // Total handling costs for the order.  If you specify handlingamt, you must also specify itemamt.
@@ -283,10 +283,10 @@  discard block
 block discarded – undo
283 283
             // Free-form field for your own use.  256 char max.
284 284
             'custom'       => $primary_registrant ? $primary_registrant->ID() : '',
285 285
             // Your own invoice or tracking number
286
-            'invnum'       => wp_generate_password(12, false),// $transaction->ID(),
286
+            'invnum'       => wp_generate_password(12, false), // $transaction->ID(),
287 287
             // URL for receiving Instant Payment Notifications.  This overrides what your profile is set to use.
288 288
             'notifyurl'    => '',
289
-            'buttonsource' => 'EventEspresso_SP',// EE will blow up if you change this
289
+            'buttonsource' => 'EventEspresso_SP', // EE will blow up if you change this
290 290
         );
291 291
         // Wrap all data arrays into a single, "master" array which will be passed into the class function.
292 292
         $PayPalRequestData = array(
@@ -396,52 +396,52 @@  discard block
 block discarded – undo
396 396
         // DP Fields
397 397
         $DPFields = isset($DataArray['DPFields']) ? $DataArray['DPFields'] : array();
398 398
         foreach ($DPFields as $DPFieldsVar => $DPFieldsVal) {
399
-            $DPFieldsNVP .= '&' . strtoupper($DPFieldsVar) . '=' . urlencode($DPFieldsVal);
399
+            $DPFieldsNVP .= '&'.strtoupper($DPFieldsVar).'='.urlencode($DPFieldsVal);
400 400
         }
401 401
         // CC Details Fields
402 402
         $CCDetails = isset($DataArray['CCDetails']) ? $DataArray['CCDetails'] : array();
403 403
         foreach ($CCDetails as $CCDetailsVar => $CCDetailsVal) {
404
-            $CCDetailsNVP .= '&' . strtoupper($CCDetailsVar) . '=' . urlencode($CCDetailsVal);
404
+            $CCDetailsNVP .= '&'.strtoupper($CCDetailsVar).'='.urlencode($CCDetailsVal);
405 405
         }
406 406
         // PayerInfo Type Fields
407 407
         $PayerInfo = isset($DataArray['PayerInfo']) ? $DataArray['PayerInfo'] : array();
408 408
         foreach ($PayerInfo as $PayerInfoVar => $PayerInfoVal) {
409
-            $PayerInfoNVP .= '&' . strtoupper($PayerInfoVar) . '=' . urlencode($PayerInfoVal);
409
+            $PayerInfoNVP .= '&'.strtoupper($PayerInfoVar).'='.urlencode($PayerInfoVal);
410 410
         }
411 411
         // Payer Name Fields
412 412
         $PayerName = isset($DataArray['PayerName']) ? $DataArray['PayerName'] : array();
413 413
         foreach ($PayerName as $PayerNameVar => $PayerNameVal) {
414
-            $PayerNameNVP .= '&' . strtoupper($PayerNameVar) . '=' . urlencode($PayerNameVal);
414
+            $PayerNameNVP .= '&'.strtoupper($PayerNameVar).'='.urlencode($PayerNameVal);
415 415
         }
416 416
         // Address Fields (Billing)
417 417
         $BillingAddress = isset($DataArray['BillingAddress']) ? $DataArray['BillingAddress'] : array();
418 418
         foreach ($BillingAddress as $BillingAddressVar => $BillingAddressVal) {
419
-            $BillingAddressNVP .= '&' . strtoupper($BillingAddressVar) . '=' . urlencode($BillingAddressVal);
419
+            $BillingAddressNVP .= '&'.strtoupper($BillingAddressVar).'='.urlencode($BillingAddressVal);
420 420
         }
421 421
         // Payment Details Type Fields
422 422
         $PaymentDetails = isset($DataArray['PaymentDetails']) ? $DataArray['PaymentDetails'] : array();
423 423
         foreach ($PaymentDetails as $PaymentDetailsVar => $PaymentDetailsVal) {
424
-            $PaymentDetailsNVP .= '&' . strtoupper($PaymentDetailsVar) . '=' . urlencode($PaymentDetailsVal);
424
+            $PaymentDetailsNVP .= '&'.strtoupper($PaymentDetailsVar).'='.urlencode($PaymentDetailsVal);
425 425
         }
426 426
         // Payment Details Item Type Fields
427 427
         $OrderItems = isset($DataArray['OrderItems']) ? $DataArray['OrderItems'] : array();
428 428
         $n = 0;
429 429
         foreach ($OrderItems as $OrderItemsVar => $OrderItemsVal) {
430
-            $CurrentItem = $OrderItems[ $OrderItemsVar ];
430
+            $CurrentItem = $OrderItems[$OrderItemsVar];
431 431
             foreach ($CurrentItem as $CurrentItemVar => $CurrentItemVal) {
432
-                $OrderItemsNVP .= '&' . strtoupper($CurrentItemVar) . $n . '=' . urlencode($CurrentItemVal);
432
+                $OrderItemsNVP .= '&'.strtoupper($CurrentItemVar).$n.'='.urlencode($CurrentItemVal);
433 433
             }
434 434
             $n++;
435 435
         }
436 436
         // Ship To Address Fields
437 437
         $ShippingAddress = isset($DataArray['ShippingAddress']) ? $DataArray['ShippingAddress'] : array();
438 438
         foreach ($ShippingAddress as $ShippingAddressVar => $ShippingAddressVal) {
439
-            $ShippingAddressNVP .= '&' . strtoupper($ShippingAddressVar) . '=' . urlencode($ShippingAddressVal);
439
+            $ShippingAddressNVP .= '&'.strtoupper($ShippingAddressVar).'='.urlencode($ShippingAddressVal);
440 440
         }
441 441
         // 3D Secure Fields
442 442
         $Secure3D = isset($DataArray['Secure3D']) ? $DataArray['Secure3D'] : array();
443 443
         foreach ($Secure3D as $Secure3DVar => $Secure3DVal) {
444
-            $Secure3DNVP .= '&' . strtoupper($Secure3DVar) . '=' . urlencode($Secure3DVal);
444
+            $Secure3DNVP .= '&'.strtoupper($Secure3DVar).'='.urlencode($Secure3DVal);
445 445
         }
446 446
         // Now that we have each chunk we need to go ahead and append them all together for our entire NVP string
447 447
         $NVPRequest = 'USER='
@@ -512,7 +512,7 @@  discard block
 block discarded – undo
512 512
             $valuepos = strpos($NVPString, '&') ? strpos($NVPString, '&') : strlen($NVPString);
513 513
             $valval = substr($NVPString, $keypos + 1, $valuepos - $keypos - 1);
514 514
             // decoding the response
515
-            $proArray[ $keyval ] = urldecode($valval);
515
+            $proArray[$keyval] = urldecode($valval);
516 516
             $NVPString = substr($NVPString, $valuepos + 1, strlen($NVPString));
517 517
         }
518 518
         return $proArray;
@@ -545,16 +545,16 @@  discard block
 block discarded – undo
545 545
     {
546 546
         $Errors = array();
547 547
         $n = 0;
548
-        while (isset($DataArray[ 'L_ERRORCODE' . $n . '' ])) {
549
-            $LErrorCode = isset($DataArray[ 'L_ERRORCODE' . $n . '' ]) ? $DataArray[ 'L_ERRORCODE' . $n . '' ] : '';
550
-            $LShortMessage = isset($DataArray[ 'L_SHORTMESSAGE' . $n . '' ])
551
-                ? $DataArray[ 'L_SHORTMESSAGE' . $n . '' ]
548
+        while (isset($DataArray['L_ERRORCODE'.$n.''])) {
549
+            $LErrorCode = isset($DataArray['L_ERRORCODE'.$n.'']) ? $DataArray['L_ERRORCODE'.$n.''] : '';
550
+            $LShortMessage = isset($DataArray['L_SHORTMESSAGE'.$n.''])
551
+                ? $DataArray['L_SHORTMESSAGE'.$n.'']
552 552
                 : '';
553
-            $LLongMessage = isset($DataArray[ 'L_LONGMESSAGE' . $n . '' ])
554
-                ? $DataArray[ 'L_LONGMESSAGE' . $n . '' ]
553
+            $LLongMessage = isset($DataArray['L_LONGMESSAGE'.$n.''])
554
+                ? $DataArray['L_LONGMESSAGE'.$n.'']
555 555
                 : '';
556
-            $LSeverityCode = isset($DataArray[ 'L_SEVERITYCODE' . $n . '' ])
557
-                ? $DataArray[ 'L_SEVERITYCODE' . $n . '' ]
556
+            $LSeverityCode = isset($DataArray['L_SEVERITYCODE'.$n.''])
557
+                ? $DataArray['L_SEVERITYCODE'.$n.'']
558 558
                 : '';
559 559
             $CurrentItem = array(
560 560
                 'L_ERRORCODE'    => $LErrorCode,
@@ -581,7 +581,7 @@  discard block
 block discarded – undo
581 581
     {
582 582
         $error = '';
583 583
         foreach ($Errors as $ErrorVar => $ErrorVal) {
584
-            $CurrentError = $Errors[ $ErrorVar ];
584
+            $CurrentError = $Errors[$ErrorVar];
585 585
             foreach ($CurrentError as $CurrentErrorVar => $CurrentErrorVal) {
586 586
                 $CurrentVarName = '';
587 587
                 if ($CurrentErrorVar == 'L_ERRORCODE') {
@@ -593,7 +593,7 @@  discard block
 block discarded – undo
593 593
                 } elseif ($CurrentErrorVar == 'L_SEVERITYCODE') {
594 594
                     $CurrentVarName = 'Severity Code';
595 595
                 }
596
-                $error .= '<br />' . $CurrentVarName . ': ' . $CurrentErrorVal;
596
+                $error .= '<br />'.$CurrentVarName.': '.$CurrentErrorVal;
597 597
             }
598 598
         }
599 599
         return $error;
Please login to merge, or discard this patch.
Indentation   +588 added lines, -588 removed lines patch added patch discarded remove patch
@@ -11,592 +11,592 @@
 block discarded – undo
11 11
 class EEG_Paypal_Pro extends EE_Onsite_Gateway
12 12
 {
13 13
 
14
-    /**
15
-     * @var $_paypal_api_username string
16
-     */
17
-    protected $_username = null;
18
-
19
-    /**
20
-     * @var $_password string
21
-     */
22
-    protected $_password = null;
23
-
24
-    /**
25
-     * @var $_signature string
26
-     */
27
-    protected $_signature = null;
28
-
29
-    /**
30
-     * @var $_credit_card_types array with the keys for credit card types accepted on this account
31
-     */
32
-    protected $_credit_card_types    = null;
33
-
34
-    protected $_currencies_supported = array(
35
-        'USD',
36
-        'GBP',
37
-        'CAD',
38
-        'AUD',
39
-        'BRL',
40
-        'CHF',
41
-        'CZK',
42
-        'DKK',
43
-        'EUR',
44
-        'HKD',
45
-        'HUF',
46
-        'ILS',
47
-        'JPY',
48
-        'MXN',
49
-        'MYR',
50
-        'NOK',
51
-        'NZD',
52
-        'PHP',
53
-        'PLN',
54
-        'SEK',
55
-        'SGD',
56
-        'THB',
57
-        'TRY',
58
-        'TWD',
59
-        'RUB',
60
-        'INR',
61
-    );
62
-
63
-
64
-
65
-    /**
66
-     * @param EEI_Payment $payment
67
-     * @param array       $billing_info {
68
-     * @type string $credit_card
69
-     * @type string $credit_card_type
70
-     * @type string $exp_month always 2 characters
71
-     * @type string $exp_year always 4 characters
72
-     * @type string $cvv
73
-     * }
74
-     * @see      parent::do_direct_payment for more info
75
-     * @return EE_Payment|EEI_Payment
76
-     * @throws EE_Error
77
-     */
78
-    public function do_direct_payment($payment, $billing_info = null)
79
-    {
80
-        $transaction = $payment->transaction();
81
-        if (! $transaction instanceof EEI_Transaction) {
82
-            throw new EE_Error(
83
-                esc_html__('No transaction for payment while paying with PayPal Pro.', 'event_espresso')
84
-            );
85
-        }
86
-        $primary_registrant = $transaction->primary_registration();
87
-        if (! $primary_registrant instanceof EEI_Registration) {
88
-            throw new EE_Error(
89
-                esc_html__(
90
-                    'No primary registration on transaction while paying with PayPal Pro.',
91
-                    'event_espresso'
92
-                )
93
-            );
94
-        }
95
-        $attendee = $primary_registrant->attendee();
96
-        if (! $attendee instanceof EEI_Attendee) {
97
-            throw new EE_Error(
98
-                esc_html__(
99
-                    'No attendee on primary registration while paying with PayPal Pro.',
100
-                    'event_espresso'
101
-                )
102
-            );
103
-        }
104
-        $gateway_formatter = $this->_get_gateway_formatter();
105
-        $order_description = substr($gateway_formatter->formatOrderDescription($payment), 0, 127);
106
-        // charge for the full amount. Show itemized list
107
-        if ($this->_can_easily_itemize_transaction_for($payment)) {
108
-            $item_num = 1;
109
-            $total_line_item = $transaction->total_line_item();
110
-            $order_items = array();
111
-            foreach ($total_line_item->get_items() as $line_item) {
112
-                // ignore line items with a quantity of 0
113
-                if ($line_item->quantity() == 0) {
114
-                    continue;
115
-                }
116
-                $item = array(
117
-                    // Item Name.  127 char max.
118
-                    'l_name'                 => substr(
119
-                        $gateway_formatter->formatLineItemName($line_item, $payment),
120
-                        0,
121
-                        127
122
-                    ),
123
-                    // Item description.  127 char max.
124
-                    'l_desc'                 => substr(
125
-                        $gateway_formatter->formatLineItemDesc($line_item, $payment),
126
-                        0,
127
-                        127
128
-                    ),
129
-                    // Cost of individual item.
130
-                    'l_amt'                  => $line_item->unit_price(),
131
-                    // Item Number.  127 char max.
132
-                    'l_number'               => $item_num++,
133
-                    // Item quantity.  Must be any positive integer.
134
-                    'l_qty'                  => $line_item->quantity(),
135
-                    // Item's sales tax amount.
136
-                    'l_taxamt'               => '',
137
-                    // eBay auction number of item.
138
-                    'l_ebayitemnumber'       => '',
139
-                    // eBay transaction ID of purchased item.
140
-                    'l_ebayitemauctiontxnid' => '',
141
-                    // eBay order ID for the item.
142
-                    'l_ebayitemorderid'      => '',
143
-                );
144
-                // add to array of all items
145
-                array_push($order_items, $item);
146
-            }
147
-            $item_amount = $total_line_item->get_items_total();
148
-            $tax_amount = $total_line_item->get_total_tax();
149
-        } else {
150
-            $order_items = array();
151
-            $item_amount = $payment->amount();
152
-            $tax_amount = 0;
153
-            array_push($order_items, array(
154
-                // Item Name.  127 char max.
155
-                'l_name'   => substr(
156
-                    $gateway_formatter->formatPartialPaymentLineItemName($payment),
157
-                    0,
158
-                    127
159
-                ),
160
-                // Item description.  127 char max.
161
-                'l_desc'   => substr(
162
-                    $gateway_formatter->formatPartialPaymentLineItemDesc($payment),
163
-                    0,
164
-                    127
165
-                ),
166
-                // Cost of individual item.
167
-                'l_amt'    => $payment->amount(),
168
-                // Item Number.  127 char max.
169
-                'l_number' => 1,
170
-                // Item quantity.  Must be any positive integer.
171
-                'l_qty'    => 1,
172
-            ));
173
-        }
174
-        // Populate data arrays with order data.
175
-        $DPFields = array(
176
-            // How you want to obtain payment ?
177
-            // Authorization indicates the payment is a basic auth subject to settlement with Auth & Capture.
178
-            // Sale indicates that this is a final sale for which you are requesting payment.  Default is Sale.
179
-            'paymentaction'    => 'Sale',
180
-            // Required.  IP address of the payer's browser.
181
-            'ipaddress'        => $_SERVER['REMOTE_ADDR'],
182
-            // Flag to determine whether you want the results returned by FMF.  1 or 0.  Default is 0.
183
-            'returnfmfdetails' => '1',
184
-        );
185
-        $CCDetails = array(
186
-            // Required. Type of credit card.  Visa, MasterCard, Discover, Amex, Maestro, Solo.
187
-            // If Maestro or Solo, the currency code must be GBP.
188
-            //  In addition, either start date or issue number must be specified.
189
-            'creditcardtype' => $billing_info['credit_card_type'],
190
-            // Required.  Credit card number.  No spaces or punctuation.
191
-            'acct'           => $billing_info['credit_card'],
192
-            // Required.  Credit card expiration date.  Format is MMYYYY
193
-            'expdate'        => $billing_info['exp_month'] . $billing_info['exp_year'],
194
-            // Requirements determined by your PayPal account settings.  Security digits for credit card.
195
-            'cvv2'           => $billing_info['cvv'],
196
-        );
197
-        $PayerInfo = array(
198
-            // Email address of payer.
199
-            'email'       => $billing_info['email'],
200
-            // Unique PayPal customer ID for payer.
201
-            'payerid'     => '',
202
-            // Status of payer.  Values are verified or unverified
203
-            'payerstatus' => '',
204
-            // Payer's business name.
205
-            'business'    => '',
206
-        );
207
-        $PayerName = array(
208
-            // Payer's salutation.  20 char max.
209
-            'salutation' => '',
210
-            // Payer's first name.  25 char max.
211
-            'firstname'  => substr($billing_info['first_name'], 0, 25),
212
-            // Payer's middle name.  25 char max.
213
-            'middlename' => '',
214
-            // Payer's last name.  25 char max.
215
-            'lastname'   => substr($billing_info['last_name'], 0, 25),
216
-            // Payer's suffix.  12 char max.
217
-            'suffix'     => '',
218
-        );
219
-        $BillingAddress = array(
220
-            // Required.  First street address.
221
-            'street'      => $billing_info['address'],
222
-            // Second street address.
223
-            'street2'     => $billing_info['address2'],
224
-            // Required.  Name of City.
225
-            'city'        => $billing_info['city'],
226
-            // Required. Name of State or Province.
227
-            'state'       => substr($billing_info['state'], 0, 40),
228
-            // Required.  Country code.
229
-            'countrycode' => $billing_info['country'],
230
-            // Required.  Postal code of payer.
231
-            'zip'         => $billing_info['zip'],
232
-        );
233
-        // check if the registration info contains the needed fields for paypal pro
234
-        // (see https://developer.paypal.com/docs/classic/api/merchant/DoDirectPayment_API_Operation_NVP/)
235
-        if ($attendee->address() && $attendee->city() && $attendee->country_ID()) {
236
-            $use_registration_address_info = true;
237
-        } else {
238
-            $use_registration_address_info = false;
239
-        }
240
-        // so if the attendee has enough data to fill out PayPal Pro's shipping info, use it.
241
-        // If not, use the billing info again
242
-        $ShippingAddress = array(
243
-            'shiptoname'     => substr($use_registration_address_info
244
-                ? $attendee->full_name()
245
-                : $billing_info['first_name'] . ' ' . $billing_info['last_name'], 0, 32),
246
-            'shiptostreet'   => substr($use_registration_address_info
247
-                ? $attendee->address()
248
-                : $billing_info['address'], 0, 100),
249
-            'shiptostreet2'  => substr($use_registration_address_info
250
-                ? $attendee->address2() : $billing_info['address2'], 0, 100),
251
-            'shiptocity'     => substr($use_registration_address_info
252
-                ? $attendee->city()
253
-                : $billing_info['city'], 0, 40),
254
-            'state'          => substr($use_registration_address_info
255
-                ? $attendee->state_name()
256
-                : $billing_info['state'], 0, 40),
257
-            'shiptocountry'  => $use_registration_address_info
258
-                ? $attendee->country_ID()
259
-                : $billing_info['country'],
260
-            'shiptozip'      => substr($use_registration_address_info
261
-                ? $attendee->zip()
262
-                : $billing_info['zip'], 0, 20),
263
-            'shiptophonenum' => substr($use_registration_address_info
264
-                ? $attendee->phone()
265
-                : $billing_info['phone'], 0, 20),
266
-        );
267
-        $PaymentDetails = array(
268
-            // Required.  Total amount of order, including shipping, handling, and tax.
269
-            'amt'          => $gateway_formatter->formatCurrency($payment->amount()),
270
-            // Required.  Three-letter currency code.  Default is USD.
271
-            'currencycode' => $payment->currency_code(),
272
-            // Required if you include itemized cart details. (L_AMTn, etc.)
273
-            // Subtotal of items not including S&H, or tax.
274
-            'itemamt'      => $gateway_formatter->formatCurrency($item_amount),//
275
-            // Total shipping costs for the order.  If you specify shippingamt, you must also specify itemamt.
276
-            'shippingamt'  => '',
277
-            // Total handling costs for the order.  If you specify handlingamt, you must also specify itemamt.
278
-            'handlingamt'  => '',
279
-            // Required if you specify itemized cart tax details.
280
-            // Sum of tax for all items on the order.  Total sales tax.
281
-            'taxamt'       => $gateway_formatter->formatCurrency($tax_amount),
282
-            // Description of the order the customer is purchasing.  127 char max.
283
-            'desc'         => $order_description,
284
-            // Free-form field for your own use.  256 char max.
285
-            'custom'       => $primary_registrant ? $primary_registrant->ID() : '',
286
-            // Your own invoice or tracking number
287
-            'invnum'       => wp_generate_password(12, false),// $transaction->ID(),
288
-            // URL for receiving Instant Payment Notifications.  This overrides what your profile is set to use.
289
-            'notifyurl'    => '',
290
-            'buttonsource' => 'EventEspresso_SP',// EE will blow up if you change this
291
-        );
292
-        // Wrap all data arrays into a single, "master" array which will be passed into the class function.
293
-        $PayPalRequestData = array(
294
-            'DPFields'        => $DPFields,
295
-            'CCDetails'       => $CCDetails,
296
-            'PayerInfo'       => $PayerInfo,
297
-            'PayerName'       => $PayerName,
298
-            'BillingAddress'  => $BillingAddress,
299
-            'ShippingAddress' => $ShippingAddress,
300
-            'PaymentDetails'  => $PaymentDetails,
301
-            'OrderItems'      => $order_items,
302
-        );
303
-        $this->_log_clean_request($PayPalRequestData, $payment);
304
-        try {
305
-            $PayPalResult = $this->prep_and_curl_request($PayPalRequestData);
306
-            // remove PCI-sensitive data so it doesn't get stored
307
-            $PayPalResult = $this->_log_clean_response($PayPalResult, $payment);
308
-            $message = isset($PayPalResult['L_LONGMESSAGE0']) ? $PayPalResult['L_LONGMESSAGE0'] : $PayPalResult['ACK'];
309
-            if (empty($PayPalResult['RAWRESPONSE'])) {
310
-                $payment->set_status($this->_pay_model->failed_status());
311
-                $payment->set_gateway_response(__('No response received from Paypal Pro', 'event_espresso'));
312
-                $payment->set_details($PayPalResult);
313
-            } else {
314
-                if ($this->_APICallSuccessful($PayPalResult)) {
315
-                    $payment->set_status($this->_pay_model->approved_status());
316
-                } else {
317
-                    $payment->set_status($this->_pay_model->declined_status());
318
-                }
319
-                // make sure we interpret the AMT as a float, not an international string
320
-                // (where periods are thousand separators)
321
-                $payment->set_amount(isset($PayPalResult['AMT']) ? floatval($PayPalResult['AMT']) : 0);
322
-                $payment->set_gateway_response($message);
323
-                $payment->set_txn_id_chq_nmbr(isset($PayPalResult['TRANSACTIONID'])
324
-                    ? $PayPalResult['TRANSACTIONID']
325
-                    : null);
326
-                $primary_registration_code = $primary_registrant instanceof EE_Registration
327
-                    ? $primary_registrant->reg_code()
328
-                    : '';
329
-                $payment->set_extra_accntng($primary_registration_code);
330
-                $payment->set_details($PayPalResult);
331
-            }
332
-        } catch (Exception $e) {
333
-            $payment->set_status($this->_pay_model->failed_status());
334
-            $payment->set_gateway_response($e->getMessage());
335
-        }
336
-        // $payment->set_status( $this->_pay_model->declined_status() );
337
-        // $payment->set_gateway_response( '' );
338
-        return $payment;
339
-    }
340
-
341
-
342
-
343
-    /**
344
-     * CLeans out sensitive CC data and then logs it, and returns the cleaned request
345
-     *
346
-     * @param array       $request
347
-     * @param EEI_Payment $payment
348
-     * @return void
349
-     */
350
-    private function _log_clean_request($request, $payment)
351
-    {
352
-        $cleaned_request_data = $request;
353
-        unset($cleaned_request_data['CCDetails']['acct']);
354
-        unset($cleaned_request_data['CCDetails']['cvv2']);
355
-        unset($cleaned_request_data['CCDetails']['expdate']);
356
-        $this->log(array('Paypal Request' => $cleaned_request_data), $payment);
357
-    }
358
-
359
-
360
-
361
-    /**
362
-     * Cleans the response, logs it, and returns it
363
-     *
364
-     * @param array       $response
365
-     * @param EEI_Payment $payment
366
-     * @return array cleaned
367
-     */
368
-    private function _log_clean_response($response, $payment)
369
-    {
370
-        unset($response['REQUESTDATA']['CREDITCARDTYPE']);
371
-        unset($response['REQUESTDATA']['ACCT']);
372
-        unset($response['REQUESTDATA']['EXPDATE']);
373
-        unset($response['REQUESTDATA']['CVV2']);
374
-        unset($response['RAWREQUEST']);
375
-        $this->log(array('Paypal Response' => $response), $payment);
376
-        return $response;
377
-    }
378
-
379
-
380
-
381
-    /**
382
-     * @param $DataArray
383
-     * @return array
384
-     */
385
-    private function prep_and_curl_request($DataArray)
386
-    {
387
-        // Create empty holders for each portion of the NVP string
388
-        $DPFieldsNVP = '&METHOD=DoDirectPayment&BUTTONSOURCE=AngellEYE_PHP_Class_DDP';
389
-        $CCDetailsNVP = '';
390
-        $PayerInfoNVP = '';
391
-        $PayerNameNVP = '';
392
-        $BillingAddressNVP = '';
393
-        $ShippingAddressNVP = '';
394
-        $PaymentDetailsNVP = '';
395
-        $OrderItemsNVP = '';
396
-        $Secure3DNVP = '';
397
-        // DP Fields
398
-        $DPFields = isset($DataArray['DPFields']) ? $DataArray['DPFields'] : array();
399
-        foreach ($DPFields as $DPFieldsVar => $DPFieldsVal) {
400
-            $DPFieldsNVP .= '&' . strtoupper($DPFieldsVar) . '=' . urlencode($DPFieldsVal);
401
-        }
402
-        // CC Details Fields
403
-        $CCDetails = isset($DataArray['CCDetails']) ? $DataArray['CCDetails'] : array();
404
-        foreach ($CCDetails as $CCDetailsVar => $CCDetailsVal) {
405
-            $CCDetailsNVP .= '&' . strtoupper($CCDetailsVar) . '=' . urlencode($CCDetailsVal);
406
-        }
407
-        // PayerInfo Type Fields
408
-        $PayerInfo = isset($DataArray['PayerInfo']) ? $DataArray['PayerInfo'] : array();
409
-        foreach ($PayerInfo as $PayerInfoVar => $PayerInfoVal) {
410
-            $PayerInfoNVP .= '&' . strtoupper($PayerInfoVar) . '=' . urlencode($PayerInfoVal);
411
-        }
412
-        // Payer Name Fields
413
-        $PayerName = isset($DataArray['PayerName']) ? $DataArray['PayerName'] : array();
414
-        foreach ($PayerName as $PayerNameVar => $PayerNameVal) {
415
-            $PayerNameNVP .= '&' . strtoupper($PayerNameVar) . '=' . urlencode($PayerNameVal);
416
-        }
417
-        // Address Fields (Billing)
418
-        $BillingAddress = isset($DataArray['BillingAddress']) ? $DataArray['BillingAddress'] : array();
419
-        foreach ($BillingAddress as $BillingAddressVar => $BillingAddressVal) {
420
-            $BillingAddressNVP .= '&' . strtoupper($BillingAddressVar) . '=' . urlencode($BillingAddressVal);
421
-        }
422
-        // Payment Details Type Fields
423
-        $PaymentDetails = isset($DataArray['PaymentDetails']) ? $DataArray['PaymentDetails'] : array();
424
-        foreach ($PaymentDetails as $PaymentDetailsVar => $PaymentDetailsVal) {
425
-            $PaymentDetailsNVP .= '&' . strtoupper($PaymentDetailsVar) . '=' . urlencode($PaymentDetailsVal);
426
-        }
427
-        // Payment Details Item Type Fields
428
-        $OrderItems = isset($DataArray['OrderItems']) ? $DataArray['OrderItems'] : array();
429
-        $n = 0;
430
-        foreach ($OrderItems as $OrderItemsVar => $OrderItemsVal) {
431
-            $CurrentItem = $OrderItems[ $OrderItemsVar ];
432
-            foreach ($CurrentItem as $CurrentItemVar => $CurrentItemVal) {
433
-                $OrderItemsNVP .= '&' . strtoupper($CurrentItemVar) . $n . '=' . urlencode($CurrentItemVal);
434
-            }
435
-            $n++;
436
-        }
437
-        // Ship To Address Fields
438
-        $ShippingAddress = isset($DataArray['ShippingAddress']) ? $DataArray['ShippingAddress'] : array();
439
-        foreach ($ShippingAddress as $ShippingAddressVar => $ShippingAddressVal) {
440
-            $ShippingAddressNVP .= '&' . strtoupper($ShippingAddressVar) . '=' . urlencode($ShippingAddressVal);
441
-        }
442
-        // 3D Secure Fields
443
-        $Secure3D = isset($DataArray['Secure3D']) ? $DataArray['Secure3D'] : array();
444
-        foreach ($Secure3D as $Secure3DVar => $Secure3DVal) {
445
-            $Secure3DNVP .= '&' . strtoupper($Secure3DVar) . '=' . urlencode($Secure3DVal);
446
-        }
447
-        // Now that we have each chunk we need to go ahead and append them all together for our entire NVP string
448
-        $NVPRequest = 'USER='
449
-                      . $this->_username
450
-                      . '&PWD='
451
-                      . $this->_password
452
-                      . '&VERSION=64.0'
453
-                      . '&SIGNATURE='
454
-                      . $this->_signature
455
-                      . $DPFieldsNVP
456
-                      . $CCDetailsNVP
457
-                      . $PayerInfoNVP
458
-                      . $PayerNameNVP
459
-                      . $BillingAddressNVP
460
-                      . $PaymentDetailsNVP
461
-                      . $OrderItemsNVP
462
-                      . $ShippingAddressNVP
463
-                      . $Secure3DNVP;
464
-        $NVPResponse = $this->_CURLRequest($NVPRequest);
465
-        $NVPRequestArray = $this->_NVPToArray($NVPRequest);
466
-        $NVPResponseArray = $this->_NVPToArray($NVPResponse);
467
-        $Errors = $this->_GetErrors($NVPResponseArray);
468
-        $NVPResponseArray['ERRORS'] = $Errors;
469
-        $NVPResponseArray['REQUESTDATA'] = $NVPRequestArray;
470
-        $NVPResponseArray['RAWREQUEST'] = $NVPRequest;
471
-        $NVPResponseArray['RAWRESPONSE'] = $NVPResponse;
472
-        return $NVPResponseArray;
473
-    }
474
-
475
-
476
-
477
-    /**
478
-     * @param $Request
479
-     * @return mixed
480
-     */
481
-    private function _CURLRequest($Request)
482
-    {
483
-        $EndPointURL = $this->_debug_mode ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp';
484
-        $curl = curl_init();
485
-        curl_setopt($curl, CURLOPT_VERBOSE, apply_filters('FHEE__EEG_Paypal_Pro__CurlRequest__CURLOPT_VERBOSE', true));
486
-        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
487
-        curl_setopt($curl, CURLOPT_TIMEOUT, 60);
488
-        curl_setopt($curl, CURLOPT_URL, $EndPointURL);
489
-        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
490
-        curl_setopt($curl, CURLOPT_POSTFIELDS, $Request);
491
-        curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
492
-        // execute the curl POST
493
-        $Response = curl_exec($curl);
494
-        curl_close($curl);
495
-        return $Response;
496
-    }
497
-
498
-
499
-
500
-    /**
501
-     * @param $NVPString
502
-     * @return array
503
-     */
504
-    private function _NVPToArray($NVPString)
505
-    {
506
-        // prepare responses into array
507
-        $proArray = array();
508
-        while (strlen($NVPString)) {
509
-            // name
510
-            $keypos = strpos($NVPString, '=');
511
-            $keyval = substr($NVPString, 0, $keypos);
512
-            // value
513
-            $valuepos = strpos($NVPString, '&') ? strpos($NVPString, '&') : strlen($NVPString);
514
-            $valval = substr($NVPString, $keypos + 1, $valuepos - $keypos - 1);
515
-            // decoding the response
516
-            $proArray[ $keyval ] = urldecode($valval);
517
-            $NVPString = substr($NVPString, $valuepos + 1, strlen($NVPString));
518
-        }
519
-        return $proArray;
520
-    }
521
-
522
-
523
-
524
-    /**
525
-     * @param array $PayPalResult
526
-     * @return bool
527
-     */
528
-    private function _APICallSuccessful($PayPalResult)
529
-    {
530
-        $approved = false;
531
-        // check main response message from PayPal
532
-        if (isset($PayPalResult['ACK']) && ! empty($PayPalResult['ACK'])) {
533
-            $ack = strtoupper($PayPalResult['ACK']);
534
-            $approved = ($ack == 'SUCCESS' || $ack == 'SUCCESSWITHWARNING' || $ack == 'PARTIALSUCCESS') ? true : false;
535
-        }
536
-        return $approved;
537
-    }
538
-
539
-
540
-
541
-    /**
542
-     * @param $DataArray
543
-     * @return array
544
-     */
545
-    private function _GetErrors($DataArray)
546
-    {
547
-        $Errors = array();
548
-        $n = 0;
549
-        while (isset($DataArray[ 'L_ERRORCODE' . $n . '' ])) {
550
-            $LErrorCode = isset($DataArray[ 'L_ERRORCODE' . $n . '' ]) ? $DataArray[ 'L_ERRORCODE' . $n . '' ] : '';
551
-            $LShortMessage = isset($DataArray[ 'L_SHORTMESSAGE' . $n . '' ])
552
-                ? $DataArray[ 'L_SHORTMESSAGE' . $n . '' ]
553
-                : '';
554
-            $LLongMessage = isset($DataArray[ 'L_LONGMESSAGE' . $n . '' ])
555
-                ? $DataArray[ 'L_LONGMESSAGE' . $n . '' ]
556
-                : '';
557
-            $LSeverityCode = isset($DataArray[ 'L_SEVERITYCODE' . $n . '' ])
558
-                ? $DataArray[ 'L_SEVERITYCODE' . $n . '' ]
559
-                : '';
560
-            $CurrentItem = array(
561
-                'L_ERRORCODE'    => $LErrorCode,
562
-                'L_SHORTMESSAGE' => $LShortMessage,
563
-                'L_LONGMESSAGE'  => $LLongMessage,
564
-                'L_SEVERITYCODE' => $LSeverityCode,
565
-            );
566
-            array_push($Errors, $CurrentItem);
567
-            $n++;
568
-        }
569
-        return $Errors;
570
-    }
571
-
572
-
573
-
574
-    /**
575
-     *        nothing to see here...  move along....
576
-     *
577
-     * @access protected
578
-     * @param $Errors
579
-     * @return string
580
-     */
581
-    private function _DisplayErrors($Errors)
582
-    {
583
-        $error = '';
584
-        foreach ($Errors as $ErrorVar => $ErrorVal) {
585
-            $CurrentError = $Errors[ $ErrorVar ];
586
-            foreach ($CurrentError as $CurrentErrorVar => $CurrentErrorVal) {
587
-                $CurrentVarName = '';
588
-                if ($CurrentErrorVar == 'L_ERRORCODE') {
589
-                    $CurrentVarName = 'Error Code';
590
-                } elseif ($CurrentErrorVar == 'L_SHORTMESSAGE') {
591
-                    $CurrentVarName = 'Short Message';
592
-                } elseif ($CurrentErrorVar == 'L_LONGMESSAGE') {
593
-                    $CurrentVarName = 'Long Message';
594
-                } elseif ($CurrentErrorVar == 'L_SEVERITYCODE') {
595
-                    $CurrentVarName = 'Severity Code';
596
-                }
597
-                $error .= '<br />' . $CurrentVarName . ': ' . $CurrentErrorVal;
598
-            }
599
-        }
600
-        return $error;
601
-    }
14
+	/**
15
+	 * @var $_paypal_api_username string
16
+	 */
17
+	protected $_username = null;
18
+
19
+	/**
20
+	 * @var $_password string
21
+	 */
22
+	protected $_password = null;
23
+
24
+	/**
25
+	 * @var $_signature string
26
+	 */
27
+	protected $_signature = null;
28
+
29
+	/**
30
+	 * @var $_credit_card_types array with the keys for credit card types accepted on this account
31
+	 */
32
+	protected $_credit_card_types    = null;
33
+
34
+	protected $_currencies_supported = array(
35
+		'USD',
36
+		'GBP',
37
+		'CAD',
38
+		'AUD',
39
+		'BRL',
40
+		'CHF',
41
+		'CZK',
42
+		'DKK',
43
+		'EUR',
44
+		'HKD',
45
+		'HUF',
46
+		'ILS',
47
+		'JPY',
48
+		'MXN',
49
+		'MYR',
50
+		'NOK',
51
+		'NZD',
52
+		'PHP',
53
+		'PLN',
54
+		'SEK',
55
+		'SGD',
56
+		'THB',
57
+		'TRY',
58
+		'TWD',
59
+		'RUB',
60
+		'INR',
61
+	);
62
+
63
+
64
+
65
+	/**
66
+	 * @param EEI_Payment $payment
67
+	 * @param array       $billing_info {
68
+	 * @type string $credit_card
69
+	 * @type string $credit_card_type
70
+	 * @type string $exp_month always 2 characters
71
+	 * @type string $exp_year always 4 characters
72
+	 * @type string $cvv
73
+	 * }
74
+	 * @see      parent::do_direct_payment for more info
75
+	 * @return EE_Payment|EEI_Payment
76
+	 * @throws EE_Error
77
+	 */
78
+	public function do_direct_payment($payment, $billing_info = null)
79
+	{
80
+		$transaction = $payment->transaction();
81
+		if (! $transaction instanceof EEI_Transaction) {
82
+			throw new EE_Error(
83
+				esc_html__('No transaction for payment while paying with PayPal Pro.', 'event_espresso')
84
+			);
85
+		}
86
+		$primary_registrant = $transaction->primary_registration();
87
+		if (! $primary_registrant instanceof EEI_Registration) {
88
+			throw new EE_Error(
89
+				esc_html__(
90
+					'No primary registration on transaction while paying with PayPal Pro.',
91
+					'event_espresso'
92
+				)
93
+			);
94
+		}
95
+		$attendee = $primary_registrant->attendee();
96
+		if (! $attendee instanceof EEI_Attendee) {
97
+			throw new EE_Error(
98
+				esc_html__(
99
+					'No attendee on primary registration while paying with PayPal Pro.',
100
+					'event_espresso'
101
+				)
102
+			);
103
+		}
104
+		$gateway_formatter = $this->_get_gateway_formatter();
105
+		$order_description = substr($gateway_formatter->formatOrderDescription($payment), 0, 127);
106
+		// charge for the full amount. Show itemized list
107
+		if ($this->_can_easily_itemize_transaction_for($payment)) {
108
+			$item_num = 1;
109
+			$total_line_item = $transaction->total_line_item();
110
+			$order_items = array();
111
+			foreach ($total_line_item->get_items() as $line_item) {
112
+				// ignore line items with a quantity of 0
113
+				if ($line_item->quantity() == 0) {
114
+					continue;
115
+				}
116
+				$item = array(
117
+					// Item Name.  127 char max.
118
+					'l_name'                 => substr(
119
+						$gateway_formatter->formatLineItemName($line_item, $payment),
120
+						0,
121
+						127
122
+					),
123
+					// Item description.  127 char max.
124
+					'l_desc'                 => substr(
125
+						$gateway_formatter->formatLineItemDesc($line_item, $payment),
126
+						0,
127
+						127
128
+					),
129
+					// Cost of individual item.
130
+					'l_amt'                  => $line_item->unit_price(),
131
+					// Item Number.  127 char max.
132
+					'l_number'               => $item_num++,
133
+					// Item quantity.  Must be any positive integer.
134
+					'l_qty'                  => $line_item->quantity(),
135
+					// Item's sales tax amount.
136
+					'l_taxamt'               => '',
137
+					// eBay auction number of item.
138
+					'l_ebayitemnumber'       => '',
139
+					// eBay transaction ID of purchased item.
140
+					'l_ebayitemauctiontxnid' => '',
141
+					// eBay order ID for the item.
142
+					'l_ebayitemorderid'      => '',
143
+				);
144
+				// add to array of all items
145
+				array_push($order_items, $item);
146
+			}
147
+			$item_amount = $total_line_item->get_items_total();
148
+			$tax_amount = $total_line_item->get_total_tax();
149
+		} else {
150
+			$order_items = array();
151
+			$item_amount = $payment->amount();
152
+			$tax_amount = 0;
153
+			array_push($order_items, array(
154
+				// Item Name.  127 char max.
155
+				'l_name'   => substr(
156
+					$gateway_formatter->formatPartialPaymentLineItemName($payment),
157
+					0,
158
+					127
159
+				),
160
+				// Item description.  127 char max.
161
+				'l_desc'   => substr(
162
+					$gateway_formatter->formatPartialPaymentLineItemDesc($payment),
163
+					0,
164
+					127
165
+				),
166
+				// Cost of individual item.
167
+				'l_amt'    => $payment->amount(),
168
+				// Item Number.  127 char max.
169
+				'l_number' => 1,
170
+				// Item quantity.  Must be any positive integer.
171
+				'l_qty'    => 1,
172
+			));
173
+		}
174
+		// Populate data arrays with order data.
175
+		$DPFields = array(
176
+			// How you want to obtain payment ?
177
+			// Authorization indicates the payment is a basic auth subject to settlement with Auth & Capture.
178
+			// Sale indicates that this is a final sale for which you are requesting payment.  Default is Sale.
179
+			'paymentaction'    => 'Sale',
180
+			// Required.  IP address of the payer's browser.
181
+			'ipaddress'        => $_SERVER['REMOTE_ADDR'],
182
+			// Flag to determine whether you want the results returned by FMF.  1 or 0.  Default is 0.
183
+			'returnfmfdetails' => '1',
184
+		);
185
+		$CCDetails = array(
186
+			// Required. Type of credit card.  Visa, MasterCard, Discover, Amex, Maestro, Solo.
187
+			// If Maestro or Solo, the currency code must be GBP.
188
+			//  In addition, either start date or issue number must be specified.
189
+			'creditcardtype' => $billing_info['credit_card_type'],
190
+			// Required.  Credit card number.  No spaces or punctuation.
191
+			'acct'           => $billing_info['credit_card'],
192
+			// Required.  Credit card expiration date.  Format is MMYYYY
193
+			'expdate'        => $billing_info['exp_month'] . $billing_info['exp_year'],
194
+			// Requirements determined by your PayPal account settings.  Security digits for credit card.
195
+			'cvv2'           => $billing_info['cvv'],
196
+		);
197
+		$PayerInfo = array(
198
+			// Email address of payer.
199
+			'email'       => $billing_info['email'],
200
+			// Unique PayPal customer ID for payer.
201
+			'payerid'     => '',
202
+			// Status of payer.  Values are verified or unverified
203
+			'payerstatus' => '',
204
+			// Payer's business name.
205
+			'business'    => '',
206
+		);
207
+		$PayerName = array(
208
+			// Payer's salutation.  20 char max.
209
+			'salutation' => '',
210
+			// Payer's first name.  25 char max.
211
+			'firstname'  => substr($billing_info['first_name'], 0, 25),
212
+			// Payer's middle name.  25 char max.
213
+			'middlename' => '',
214
+			// Payer's last name.  25 char max.
215
+			'lastname'   => substr($billing_info['last_name'], 0, 25),
216
+			// Payer's suffix.  12 char max.
217
+			'suffix'     => '',
218
+		);
219
+		$BillingAddress = array(
220
+			// Required.  First street address.
221
+			'street'      => $billing_info['address'],
222
+			// Second street address.
223
+			'street2'     => $billing_info['address2'],
224
+			// Required.  Name of City.
225
+			'city'        => $billing_info['city'],
226
+			// Required. Name of State or Province.
227
+			'state'       => substr($billing_info['state'], 0, 40),
228
+			// Required.  Country code.
229
+			'countrycode' => $billing_info['country'],
230
+			// Required.  Postal code of payer.
231
+			'zip'         => $billing_info['zip'],
232
+		);
233
+		// check if the registration info contains the needed fields for paypal pro
234
+		// (see https://developer.paypal.com/docs/classic/api/merchant/DoDirectPayment_API_Operation_NVP/)
235
+		if ($attendee->address() && $attendee->city() && $attendee->country_ID()) {
236
+			$use_registration_address_info = true;
237
+		} else {
238
+			$use_registration_address_info = false;
239
+		}
240
+		// so if the attendee has enough data to fill out PayPal Pro's shipping info, use it.
241
+		// If not, use the billing info again
242
+		$ShippingAddress = array(
243
+			'shiptoname'     => substr($use_registration_address_info
244
+				? $attendee->full_name()
245
+				: $billing_info['first_name'] . ' ' . $billing_info['last_name'], 0, 32),
246
+			'shiptostreet'   => substr($use_registration_address_info
247
+				? $attendee->address()
248
+				: $billing_info['address'], 0, 100),
249
+			'shiptostreet2'  => substr($use_registration_address_info
250
+				? $attendee->address2() : $billing_info['address2'], 0, 100),
251
+			'shiptocity'     => substr($use_registration_address_info
252
+				? $attendee->city()
253
+				: $billing_info['city'], 0, 40),
254
+			'state'          => substr($use_registration_address_info
255
+				? $attendee->state_name()
256
+				: $billing_info['state'], 0, 40),
257
+			'shiptocountry'  => $use_registration_address_info
258
+				? $attendee->country_ID()
259
+				: $billing_info['country'],
260
+			'shiptozip'      => substr($use_registration_address_info
261
+				? $attendee->zip()
262
+				: $billing_info['zip'], 0, 20),
263
+			'shiptophonenum' => substr($use_registration_address_info
264
+				? $attendee->phone()
265
+				: $billing_info['phone'], 0, 20),
266
+		);
267
+		$PaymentDetails = array(
268
+			// Required.  Total amount of order, including shipping, handling, and tax.
269
+			'amt'          => $gateway_formatter->formatCurrency($payment->amount()),
270
+			// Required.  Three-letter currency code.  Default is USD.
271
+			'currencycode' => $payment->currency_code(),
272
+			// Required if you include itemized cart details. (L_AMTn, etc.)
273
+			// Subtotal of items not including S&H, or tax.
274
+			'itemamt'      => $gateway_formatter->formatCurrency($item_amount),//
275
+			// Total shipping costs for the order.  If you specify shippingamt, you must also specify itemamt.
276
+			'shippingamt'  => '',
277
+			// Total handling costs for the order.  If you specify handlingamt, you must also specify itemamt.
278
+			'handlingamt'  => '',
279
+			// Required if you specify itemized cart tax details.
280
+			// Sum of tax for all items on the order.  Total sales tax.
281
+			'taxamt'       => $gateway_formatter->formatCurrency($tax_amount),
282
+			// Description of the order the customer is purchasing.  127 char max.
283
+			'desc'         => $order_description,
284
+			// Free-form field for your own use.  256 char max.
285
+			'custom'       => $primary_registrant ? $primary_registrant->ID() : '',
286
+			// Your own invoice or tracking number
287
+			'invnum'       => wp_generate_password(12, false),// $transaction->ID(),
288
+			// URL for receiving Instant Payment Notifications.  This overrides what your profile is set to use.
289
+			'notifyurl'    => '',
290
+			'buttonsource' => 'EventEspresso_SP',// EE will blow up if you change this
291
+		);
292
+		// Wrap all data arrays into a single, "master" array which will be passed into the class function.
293
+		$PayPalRequestData = array(
294
+			'DPFields'        => $DPFields,
295
+			'CCDetails'       => $CCDetails,
296
+			'PayerInfo'       => $PayerInfo,
297
+			'PayerName'       => $PayerName,
298
+			'BillingAddress'  => $BillingAddress,
299
+			'ShippingAddress' => $ShippingAddress,
300
+			'PaymentDetails'  => $PaymentDetails,
301
+			'OrderItems'      => $order_items,
302
+		);
303
+		$this->_log_clean_request($PayPalRequestData, $payment);
304
+		try {
305
+			$PayPalResult = $this->prep_and_curl_request($PayPalRequestData);
306
+			// remove PCI-sensitive data so it doesn't get stored
307
+			$PayPalResult = $this->_log_clean_response($PayPalResult, $payment);
308
+			$message = isset($PayPalResult['L_LONGMESSAGE0']) ? $PayPalResult['L_LONGMESSAGE0'] : $PayPalResult['ACK'];
309
+			if (empty($PayPalResult['RAWRESPONSE'])) {
310
+				$payment->set_status($this->_pay_model->failed_status());
311
+				$payment->set_gateway_response(__('No response received from Paypal Pro', 'event_espresso'));
312
+				$payment->set_details($PayPalResult);
313
+			} else {
314
+				if ($this->_APICallSuccessful($PayPalResult)) {
315
+					$payment->set_status($this->_pay_model->approved_status());
316
+				} else {
317
+					$payment->set_status($this->_pay_model->declined_status());
318
+				}
319
+				// make sure we interpret the AMT as a float, not an international string
320
+				// (where periods are thousand separators)
321
+				$payment->set_amount(isset($PayPalResult['AMT']) ? floatval($PayPalResult['AMT']) : 0);
322
+				$payment->set_gateway_response($message);
323
+				$payment->set_txn_id_chq_nmbr(isset($PayPalResult['TRANSACTIONID'])
324
+					? $PayPalResult['TRANSACTIONID']
325
+					: null);
326
+				$primary_registration_code = $primary_registrant instanceof EE_Registration
327
+					? $primary_registrant->reg_code()
328
+					: '';
329
+				$payment->set_extra_accntng($primary_registration_code);
330
+				$payment->set_details($PayPalResult);
331
+			}
332
+		} catch (Exception $e) {
333
+			$payment->set_status($this->_pay_model->failed_status());
334
+			$payment->set_gateway_response($e->getMessage());
335
+		}
336
+		// $payment->set_status( $this->_pay_model->declined_status() );
337
+		// $payment->set_gateway_response( '' );
338
+		return $payment;
339
+	}
340
+
341
+
342
+
343
+	/**
344
+	 * CLeans out sensitive CC data and then logs it, and returns the cleaned request
345
+	 *
346
+	 * @param array       $request
347
+	 * @param EEI_Payment $payment
348
+	 * @return void
349
+	 */
350
+	private function _log_clean_request($request, $payment)
351
+	{
352
+		$cleaned_request_data = $request;
353
+		unset($cleaned_request_data['CCDetails']['acct']);
354
+		unset($cleaned_request_data['CCDetails']['cvv2']);
355
+		unset($cleaned_request_data['CCDetails']['expdate']);
356
+		$this->log(array('Paypal Request' => $cleaned_request_data), $payment);
357
+	}
358
+
359
+
360
+
361
+	/**
362
+	 * Cleans the response, logs it, and returns it
363
+	 *
364
+	 * @param array       $response
365
+	 * @param EEI_Payment $payment
366
+	 * @return array cleaned
367
+	 */
368
+	private function _log_clean_response($response, $payment)
369
+	{
370
+		unset($response['REQUESTDATA']['CREDITCARDTYPE']);
371
+		unset($response['REQUESTDATA']['ACCT']);
372
+		unset($response['REQUESTDATA']['EXPDATE']);
373
+		unset($response['REQUESTDATA']['CVV2']);
374
+		unset($response['RAWREQUEST']);
375
+		$this->log(array('Paypal Response' => $response), $payment);
376
+		return $response;
377
+	}
378
+
379
+
380
+
381
+	/**
382
+	 * @param $DataArray
383
+	 * @return array
384
+	 */
385
+	private function prep_and_curl_request($DataArray)
386
+	{
387
+		// Create empty holders for each portion of the NVP string
388
+		$DPFieldsNVP = '&METHOD=DoDirectPayment&BUTTONSOURCE=AngellEYE_PHP_Class_DDP';
389
+		$CCDetailsNVP = '';
390
+		$PayerInfoNVP = '';
391
+		$PayerNameNVP = '';
392
+		$BillingAddressNVP = '';
393
+		$ShippingAddressNVP = '';
394
+		$PaymentDetailsNVP = '';
395
+		$OrderItemsNVP = '';
396
+		$Secure3DNVP = '';
397
+		// DP Fields
398
+		$DPFields = isset($DataArray['DPFields']) ? $DataArray['DPFields'] : array();
399
+		foreach ($DPFields as $DPFieldsVar => $DPFieldsVal) {
400
+			$DPFieldsNVP .= '&' . strtoupper($DPFieldsVar) . '=' . urlencode($DPFieldsVal);
401
+		}
402
+		// CC Details Fields
403
+		$CCDetails = isset($DataArray['CCDetails']) ? $DataArray['CCDetails'] : array();
404
+		foreach ($CCDetails as $CCDetailsVar => $CCDetailsVal) {
405
+			$CCDetailsNVP .= '&' . strtoupper($CCDetailsVar) . '=' . urlencode($CCDetailsVal);
406
+		}
407
+		// PayerInfo Type Fields
408
+		$PayerInfo = isset($DataArray['PayerInfo']) ? $DataArray['PayerInfo'] : array();
409
+		foreach ($PayerInfo as $PayerInfoVar => $PayerInfoVal) {
410
+			$PayerInfoNVP .= '&' . strtoupper($PayerInfoVar) . '=' . urlencode($PayerInfoVal);
411
+		}
412
+		// Payer Name Fields
413
+		$PayerName = isset($DataArray['PayerName']) ? $DataArray['PayerName'] : array();
414
+		foreach ($PayerName as $PayerNameVar => $PayerNameVal) {
415
+			$PayerNameNVP .= '&' . strtoupper($PayerNameVar) . '=' . urlencode($PayerNameVal);
416
+		}
417
+		// Address Fields (Billing)
418
+		$BillingAddress = isset($DataArray['BillingAddress']) ? $DataArray['BillingAddress'] : array();
419
+		foreach ($BillingAddress as $BillingAddressVar => $BillingAddressVal) {
420
+			$BillingAddressNVP .= '&' . strtoupper($BillingAddressVar) . '=' . urlencode($BillingAddressVal);
421
+		}
422
+		// Payment Details Type Fields
423
+		$PaymentDetails = isset($DataArray['PaymentDetails']) ? $DataArray['PaymentDetails'] : array();
424
+		foreach ($PaymentDetails as $PaymentDetailsVar => $PaymentDetailsVal) {
425
+			$PaymentDetailsNVP .= '&' . strtoupper($PaymentDetailsVar) . '=' . urlencode($PaymentDetailsVal);
426
+		}
427
+		// Payment Details Item Type Fields
428
+		$OrderItems = isset($DataArray['OrderItems']) ? $DataArray['OrderItems'] : array();
429
+		$n = 0;
430
+		foreach ($OrderItems as $OrderItemsVar => $OrderItemsVal) {
431
+			$CurrentItem = $OrderItems[ $OrderItemsVar ];
432
+			foreach ($CurrentItem as $CurrentItemVar => $CurrentItemVal) {
433
+				$OrderItemsNVP .= '&' . strtoupper($CurrentItemVar) . $n . '=' . urlencode($CurrentItemVal);
434
+			}
435
+			$n++;
436
+		}
437
+		// Ship To Address Fields
438
+		$ShippingAddress = isset($DataArray['ShippingAddress']) ? $DataArray['ShippingAddress'] : array();
439
+		foreach ($ShippingAddress as $ShippingAddressVar => $ShippingAddressVal) {
440
+			$ShippingAddressNVP .= '&' . strtoupper($ShippingAddressVar) . '=' . urlencode($ShippingAddressVal);
441
+		}
442
+		// 3D Secure Fields
443
+		$Secure3D = isset($DataArray['Secure3D']) ? $DataArray['Secure3D'] : array();
444
+		foreach ($Secure3D as $Secure3DVar => $Secure3DVal) {
445
+			$Secure3DNVP .= '&' . strtoupper($Secure3DVar) . '=' . urlencode($Secure3DVal);
446
+		}
447
+		// Now that we have each chunk we need to go ahead and append them all together for our entire NVP string
448
+		$NVPRequest = 'USER='
449
+					  . $this->_username
450
+					  . '&PWD='
451
+					  . $this->_password
452
+					  . '&VERSION=64.0'
453
+					  . '&SIGNATURE='
454
+					  . $this->_signature
455
+					  . $DPFieldsNVP
456
+					  . $CCDetailsNVP
457
+					  . $PayerInfoNVP
458
+					  . $PayerNameNVP
459
+					  . $BillingAddressNVP
460
+					  . $PaymentDetailsNVP
461
+					  . $OrderItemsNVP
462
+					  . $ShippingAddressNVP
463
+					  . $Secure3DNVP;
464
+		$NVPResponse = $this->_CURLRequest($NVPRequest);
465
+		$NVPRequestArray = $this->_NVPToArray($NVPRequest);
466
+		$NVPResponseArray = $this->_NVPToArray($NVPResponse);
467
+		$Errors = $this->_GetErrors($NVPResponseArray);
468
+		$NVPResponseArray['ERRORS'] = $Errors;
469
+		$NVPResponseArray['REQUESTDATA'] = $NVPRequestArray;
470
+		$NVPResponseArray['RAWREQUEST'] = $NVPRequest;
471
+		$NVPResponseArray['RAWRESPONSE'] = $NVPResponse;
472
+		return $NVPResponseArray;
473
+	}
474
+
475
+
476
+
477
+	/**
478
+	 * @param $Request
479
+	 * @return mixed
480
+	 */
481
+	private function _CURLRequest($Request)
482
+	{
483
+		$EndPointURL = $this->_debug_mode ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp';
484
+		$curl = curl_init();
485
+		curl_setopt($curl, CURLOPT_VERBOSE, apply_filters('FHEE__EEG_Paypal_Pro__CurlRequest__CURLOPT_VERBOSE', true));
486
+		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
487
+		curl_setopt($curl, CURLOPT_TIMEOUT, 60);
488
+		curl_setopt($curl, CURLOPT_URL, $EndPointURL);
489
+		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
490
+		curl_setopt($curl, CURLOPT_POSTFIELDS, $Request);
491
+		curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
492
+		// execute the curl POST
493
+		$Response = curl_exec($curl);
494
+		curl_close($curl);
495
+		return $Response;
496
+	}
497
+
498
+
499
+
500
+	/**
501
+	 * @param $NVPString
502
+	 * @return array
503
+	 */
504
+	private function _NVPToArray($NVPString)
505
+	{
506
+		// prepare responses into array
507
+		$proArray = array();
508
+		while (strlen($NVPString)) {
509
+			// name
510
+			$keypos = strpos($NVPString, '=');
511
+			$keyval = substr($NVPString, 0, $keypos);
512
+			// value
513
+			$valuepos = strpos($NVPString, '&') ? strpos($NVPString, '&') : strlen($NVPString);
514
+			$valval = substr($NVPString, $keypos + 1, $valuepos - $keypos - 1);
515
+			// decoding the response
516
+			$proArray[ $keyval ] = urldecode($valval);
517
+			$NVPString = substr($NVPString, $valuepos + 1, strlen($NVPString));
518
+		}
519
+		return $proArray;
520
+	}
521
+
522
+
523
+
524
+	/**
525
+	 * @param array $PayPalResult
526
+	 * @return bool
527
+	 */
528
+	private function _APICallSuccessful($PayPalResult)
529
+	{
530
+		$approved = false;
531
+		// check main response message from PayPal
532
+		if (isset($PayPalResult['ACK']) && ! empty($PayPalResult['ACK'])) {
533
+			$ack = strtoupper($PayPalResult['ACK']);
534
+			$approved = ($ack == 'SUCCESS' || $ack == 'SUCCESSWITHWARNING' || $ack == 'PARTIALSUCCESS') ? true : false;
535
+		}
536
+		return $approved;
537
+	}
538
+
539
+
540
+
541
+	/**
542
+	 * @param $DataArray
543
+	 * @return array
544
+	 */
545
+	private function _GetErrors($DataArray)
546
+	{
547
+		$Errors = array();
548
+		$n = 0;
549
+		while (isset($DataArray[ 'L_ERRORCODE' . $n . '' ])) {
550
+			$LErrorCode = isset($DataArray[ 'L_ERRORCODE' . $n . '' ]) ? $DataArray[ 'L_ERRORCODE' . $n . '' ] : '';
551
+			$LShortMessage = isset($DataArray[ 'L_SHORTMESSAGE' . $n . '' ])
552
+				? $DataArray[ 'L_SHORTMESSAGE' . $n . '' ]
553
+				: '';
554
+			$LLongMessage = isset($DataArray[ 'L_LONGMESSAGE' . $n . '' ])
555
+				? $DataArray[ 'L_LONGMESSAGE' . $n . '' ]
556
+				: '';
557
+			$LSeverityCode = isset($DataArray[ 'L_SEVERITYCODE' . $n . '' ])
558
+				? $DataArray[ 'L_SEVERITYCODE' . $n . '' ]
559
+				: '';
560
+			$CurrentItem = array(
561
+				'L_ERRORCODE'    => $LErrorCode,
562
+				'L_SHORTMESSAGE' => $LShortMessage,
563
+				'L_LONGMESSAGE'  => $LLongMessage,
564
+				'L_SEVERITYCODE' => $LSeverityCode,
565
+			);
566
+			array_push($Errors, $CurrentItem);
567
+			$n++;
568
+		}
569
+		return $Errors;
570
+	}
571
+
572
+
573
+
574
+	/**
575
+	 *        nothing to see here...  move along....
576
+	 *
577
+	 * @access protected
578
+	 * @param $Errors
579
+	 * @return string
580
+	 */
581
+	private function _DisplayErrors($Errors)
582
+	{
583
+		$error = '';
584
+		foreach ($Errors as $ErrorVar => $ErrorVal) {
585
+			$CurrentError = $Errors[ $ErrorVar ];
586
+			foreach ($CurrentError as $CurrentErrorVar => $CurrentErrorVal) {
587
+				$CurrentVarName = '';
588
+				if ($CurrentErrorVar == 'L_ERRORCODE') {
589
+					$CurrentVarName = 'Error Code';
590
+				} elseif ($CurrentErrorVar == 'L_SHORTMESSAGE') {
591
+					$CurrentVarName = 'Short Message';
592
+				} elseif ($CurrentErrorVar == 'L_LONGMESSAGE') {
593
+					$CurrentVarName = 'Long Message';
594
+				} elseif ($CurrentErrorVar == 'L_SEVERITYCODE') {
595
+					$CurrentVarName = 'Severity Code';
596
+				}
597
+				$error .= '<br />' . $CurrentVarName . ': ' . $CurrentErrorVal;
598
+			}
599
+		}
600
+		return $error;
601
+	}
602 602
 }
Please login to merge, or discard this patch.
libraries/line_item_display/EE_SPCO_Line_Item_Display_Strategy.strategy.php 3 patches
Doc Comments   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -77,7 +77,7 @@  discard block
 block discarded – undo
77 77
      * @param EE_Line_Item $line_item
78 78
      * @param array        $options
79 79
      * @param EE_Line_Item $parent_line_item
80
-     * @return mixed
80
+     * @return string
81 81
      * @throws EE_Error
82 82
      */
83 83
     public function display_line_item(
@@ -223,7 +223,7 @@  discard block
 block discarded – undo
223 223
      * _event_row - basically a Heading row displayed once above each event's ticket rows
224 224
      *
225 225
      * @param EE_Line_Item $line_item
226
-     * @return mixed
226
+     * @return string
227 227
      */
228 228
     private function _event_row(EE_Line_Item $line_item)
229 229
     {
@@ -249,7 +249,7 @@  discard block
 block discarded – undo
249 249
      *
250 250
      * @param EE_Line_Item $line_item
251 251
      * @param array        $options
252
-     * @return mixed
252
+     * @return string
253 253
      * @throws EE_Error
254 254
      */
255 255
     private function _ticket_row(EE_Line_Item $line_item, $options = array())
@@ -303,7 +303,7 @@  discard block
 block discarded – undo
303 303
      *
304 304
      * @param EE_Line_Item $line_item
305 305
      * @param array        $options
306
-     * @return mixed
306
+     * @return string
307 307
      * @throws EE_Error
308 308
      */
309 309
     private function _item_row(EE_Line_Item $line_item, $options = array())
@@ -363,7 +363,7 @@  discard block
 block discarded – undo
363 363
      * @param EE_Line_Item $line_item
364 364
      * @param array        $options
365 365
      * @param EE_Line_Item $parent_line_item
366
-     * @return mixed
366
+     * @return string
367 367
      * @throws EE_Error
368 368
      */
369 369
     private function _sub_item_row(EE_Line_Item $line_item, $options = array(), EE_Line_Item $parent_line_item = null)
@@ -407,7 +407,7 @@  discard block
 block discarded – undo
407 407
      *
408 408
      * @param EE_Line_Item $line_item
409 409
      * @param array        $options
410
-     * @return mixed
410
+     * @return string
411 411
      * @throws EE_Error
412 412
      */
413 413
     private function _tax_row(EE_Line_Item $line_item, $options = array())
@@ -444,7 +444,7 @@  discard block
 block discarded – undo
444 444
      *
445 445
      * @param EE_Line_Item $line_item
446 446
      * @param string       $text
447
-     * @return mixed
447
+     * @return string
448 448
      * @throws EE_Error
449 449
      */
450 450
     private function _total_tax_row(EE_Line_Item $line_item, $text = '')
@@ -483,7 +483,7 @@  discard block
 block discarded – undo
483 483
      * @param EE_Line_Item $line_item
484 484
      * @param string       $text
485 485
      * @param array        $options
486
-     * @return mixed
486
+     * @return string
487 487
      * @throws EE_Error
488 488
      */
489 489
     private function _sub_total_row(EE_Line_Item $line_item, $text = '', $options = array())
@@ -519,7 +519,7 @@  discard block
 block discarded – undo
519 519
      *
520 520
      * @param EE_Line_Item $line_item
521 521
      * @param string       $text
522
-     * @return mixed
522
+     * @return string
523 523
      * @throws EE_Error
524 524
      */
525 525
     private function _total_row(EE_Line_Item $line_item, $text = '')
@@ -546,7 +546,7 @@  discard block
 block discarded – undo
546 546
      *
547 547
      * @param EE_Line_Item $line_item
548 548
      * @param array        $options
549
-     * @return mixed
549
+     * @return string
550 550
      * @throws EE_Error
551 551
      */
552 552
     private function _payments_and_amount_owing_rows(EE_Line_Item $line_item, $options = array())
Please login to merge, or discard this patch.
Indentation   +621 added lines, -621 removed lines patch added patch discarded remove patch
@@ -12,625 +12,625 @@
 block discarded – undo
12 12
 class EE_SPCO_Line_Item_Display_Strategy implements EEI_Line_Item_Display
13 13
 {
14 14
 
15
-    /**
16
-     * array of events
17
-     *
18
-     * @type EE_Line_Item[] $_events
19
-     */
20
-    private $_events = array();
21
-
22
-    /**
23
-     * whether to display the taxes row or not
24
-     *
25
-     * @type bool $_show_taxes
26
-     */
27
-    private $_show_taxes = false;
28
-
29
-    /**
30
-     * html for any tax rows
31
-     *
32
-     * @type string $_show_taxes
33
-     */
34
-    private $_taxes_html = '';
35
-
36
-    /**
37
-     * total amount including tax we can bill for at this time
38
-     *
39
-     * @type float $_grand_total
40
-     */
41
-    private $_grand_total = 0.00;
42
-
43
-    /**
44
-     * total number of items being billed for
45
-     *
46
-     * @type int $_total_items
47
-     */
48
-    private $_total_items = 0;
49
-
50
-
51
-
52
-    /**
53
-     * @return float
54
-     */
55
-    public function grand_total()
56
-    {
57
-        return $this->_grand_total;
58
-    }
59
-
60
-
61
-
62
-    /**
63
-     * @return int
64
-     */
65
-    public function total_items()
66
-    {
67
-        return $this->_total_items;
68
-    }
69
-
70
-
71
-
72
-    /**
73
-     * @param EE_Line_Item $line_item
74
-     * @param array        $options
75
-     * @param EE_Line_Item $parent_line_item
76
-     * @return mixed
77
-     * @throws EE_Error
78
-     */
79
-    public function display_line_item(
80
-        EE_Line_Item $line_item,
81
-        $options = array(),
82
-        EE_Line_Item $parent_line_item = null
83
-    ) {
84
-        $html = '';
85
-        // set some default options and merge with incoming
86
-        $default_options = array(
87
-            'show_desc' => true,  //    true        false
88
-            'odd'       => false,
89
-        );
90
-        $options = array_merge($default_options, (array) $options);
91
-        switch ($line_item->type()) {
92
-            case EEM_Line_Item::type_line_item:
93
-                $this->_show_taxes = $line_item->is_taxable() ? true : $this->_show_taxes;
94
-                if ($line_item->OBJ_type() === 'Ticket') {
95
-                    // item row
96
-                    $html .= $this->_ticket_row($line_item, $options);
97
-                } else {
98
-                    // item row
99
-                    $html .= $this->_item_row($line_item, $options);
100
-                }
101
-                if (apply_filters(
102
-                    'FHEE__EE_SPCO_Line_Item_Display_Strategy__display_line_item__display_sub_line_items',
103
-                    true
104
-                )
105
-                ) {
106
-                    // got any kids?
107
-                    foreach ($line_item->children() as $child_line_item) {
108
-                        $html .= $this->display_line_item($child_line_item, $options, $line_item);
109
-                    }
110
-                }
111
-                break;
112
-            case EEM_Line_Item::type_sub_line_item:
113
-                $html .= $this->_sub_item_row($line_item, $options, $parent_line_item);
114
-                break;
115
-            case EEM_Line_Item::type_sub_total:
116
-                static $sub_total = 0;
117
-                $event_sub_total = 0;
118
-                $text = esc_html__('Sub-Total', 'event_espresso');
119
-                if ($line_item->OBJ_type() === 'Event') {
120
-                    $options['event_id'] = $event_id = $line_item->OBJ_ID();
121
-                    if (! isset($this->_events[ $options['event_id'] ])) {
122
-                        $event = EEM_Event::instance()->get_one_by_ID($options['event_id']);
123
-                        // if event has default reg status of Not Approved, then don't display info on it
124
-                        if ($event instanceof EE_Event
125
-                            && $event->default_registration_status() === EEM_Registration::status_id_not_approved
126
-                        ) {
127
-                            $display_event = false;
128
-                            // unless there are registrations for it that are returning to pay
129
-                            if (isset($options['registrations']) && is_array($options['registrations'])) {
130
-                                foreach ($options['registrations'] as $registration) {
131
-                                    if (! $registration instanceof EE_Registration) {
132
-                                        continue;
133
-                                    }
134
-                                    $display_event = $registration->event_ID() === $options['event_id']
135
-                                                     && $registration->status_ID() !== EEM_Registration::status_id_not_approved
136
-                                        ? true
137
-                                        : $display_event;
138
-                                }
139
-                            }
140
-                            if (! $display_event) {
141
-                                return '';
142
-                            }
143
-                        }
144
-                        $this->_events[ $options['event_id'] ] = 0;
145
-                        $html .= $this->_event_row($line_item);
146
-                        $text = esc_html__('Event Sub-Total', 'event_espresso');
147
-                    }
148
-                }
149
-                $child_line_items = $line_item->children();
150
-                // loop thru children
151
-                foreach ($child_line_items as $child_line_item) {
152
-                    // recursively feed children back into this method
153
-                    $html .= $this->display_line_item($child_line_item, $options, $line_item);
154
-                }
155
-                $event_sub_total += isset($options['event_id']) ? $this->_events[ $options['event_id'] ] : 0;
156
-                $sub_total += $event_sub_total;
157
-                if ((
158
-                        // event subtotals
159
-                        $line_item->code() !== 'pre-tax-subtotal' && count($child_line_items) > 1
160
-                    )
161
-                    || (
162
-                        // pre-tax subtotals
163
-                        $line_item->code() === 'pre-tax-subtotal' && count($this->_events) > 1
164
-                    )
165
-                ) {
166
-                    $options['sub_total'] = $line_item->OBJ_type() === 'Event' ? $event_sub_total : $sub_total;
167
-                    $html .= $this->_sub_total_row($line_item, $text, $options);
168
-                }
169
-                break;
170
-            case EEM_Line_Item::type_tax:
171
-                if ($this->_show_taxes) {
172
-                    $this->_taxes_html .= $this->_tax_row($line_item, $options);
173
-                }
174
-                break;
175
-            case EEM_Line_Item::type_tax_sub_total:
176
-                if ($this->_show_taxes) {
177
-                    $child_line_items = $line_item->children();
178
-                    // loop thru children
179
-                    foreach ($child_line_items as $child_line_item) {
180
-                        // recursively feed children back into this method
181
-                        $html .= $this->display_line_item($child_line_item, $options, $line_item);
182
-                    }
183
-                    if (count($child_line_items) > 1) {
184
-                        $this->_taxes_html .= $this->_total_tax_row($line_item, esc_html__('Tax Total', 'event_espresso'));
185
-                    }
186
-                }
187
-                break;
188
-            case EEM_Line_Item::type_total:
189
-                // get all child line items
190
-                $children = $line_item->children();
191
-                // loop thru all non-tax child line items
192
-                foreach ($children as $child_line_item) {
193
-                    if ($child_line_item->type() !== EEM_Line_Item::type_tax_sub_total) {
194
-                        // recursively feed children back into this method
195
-                        $html .= $this->display_line_item($child_line_item, $options, $line_item);
196
-                    }
197
-                }
198
-                // now loop thru  tax child line items
199
-                foreach ($children as $child_line_item) {
200
-                    if ($child_line_item->type() === EEM_Line_Item::type_tax_sub_total) {
201
-                        // recursively feed children back into this method
202
-                        $html .= $this->display_line_item($child_line_item, $options, $line_item);
203
-                    }
204
-                }
205
-                $html .= $this->_taxes_html;
206
-                $html .= $this->_total_row($line_item, esc_html__('Total', 'event_espresso'));
207
-                $html .= $this->_payments_and_amount_owing_rows($line_item, $options);
208
-                break;
209
-        }
210
-        return $html;
211
-    }
212
-
213
-
214
-
215
-    /**
216
-     * _event_row - basically a Heading row displayed once above each event's ticket rows
217
-     *
218
-     * @param EE_Line_Item $line_item
219
-     * @return mixed
220
-     */
221
-    private function _event_row(EE_Line_Item $line_item)
222
-    {
223
-        // start of row
224
-        $html = EEH_HTML::tr('', 'event-cart-total-row', 'total_tr odd');
225
-        // event name td
226
-        $html .= EEH_HTML::td(
227
-            EEH_HTML::strong($line_item->name()),
228
-            '',
229
-            'event-header',
230
-            '',
231
-            ' colspan="4"'
232
-        );
233
-        // end of row
234
-        $html .= EEH_HTML::trx();
235
-        return $html;
236
-    }
237
-
238
-
239
-
240
-    /**
241
-     * _ticket_row
242
-     *
243
-     * @param EE_Line_Item $line_item
244
-     * @param array        $options
245
-     * @return mixed
246
-     * @throws EE_Error
247
-     */
248
-    private function _ticket_row(EE_Line_Item $line_item, $options = array())
249
-    {
250
-        // start of row
251
-        $row_class = $options['odd'] ? 'item odd' : 'item';
252
-        $html = EEH_HTML::tr('', '', $row_class);
253
-        // name && desc
254
-        $name_and_desc = apply_filters(
255
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__name',
256
-            $line_item->name(),
257
-            $line_item
258
-        );
259
-        $name_and_desc .= apply_filters(
260
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc',
261
-            (
262
-                $options['show_desc']
263
-                    ? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>'
264
-                    : ''
265
-            ),
266
-            $line_item,
267
-            $options
268
-        );
269
-        $name_and_desc .= $line_item->is_taxable() ? ' * ' : '';
270
-        // name td
271
-        $html .= EEH_HTML::td( /*__FUNCTION__ .*/
272
-            $name_and_desc,
273
-            '',
274
-            'item_l'
275
-        );
276
-        // price td
277
-        $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
278
-        // quantity td
279
-        $html .= EEH_HTML::td($line_item->quantity(), '', 'item_l jst-rght');
280
-        $this->_total_items += $line_item->quantity();
281
-        // determine total for line item
282
-        $total = $line_item->total();
283
-        $this->_events[ $options['event_id'] ] += $total;
284
-        // total td
285
-        $html .= EEH_HTML::td(
286
-            EEH_Template::format_currency($total, false, false),
287
-            '',
288
-            'item_r jst-rght'
289
-        );
290
-        // end of row
291
-        $html .= EEH_HTML::trx();
292
-        return $html;
293
-    }
294
-
295
-
296
-
297
-    /**
298
-     * _item_row
299
-     *
300
-     * @param EE_Line_Item $line_item
301
-     * @param array        $options
302
-     * @return mixed
303
-     * @throws EE_Error
304
-     */
305
-    private function _item_row(EE_Line_Item $line_item, $options = array())
306
-    {
307
-        // start of row
308
-        $row_class = $options['odd'] ? 'item odd' : 'item';
309
-        $html = EEH_HTML::tr('', '', $row_class);
310
-        $obj_name = $line_item->OBJ_type() ? $line_item->OBJ_type_i18n() . ': ' : '';
311
-        // name && desc
312
-        $name_and_desc = apply_filters(
313
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__name',
314
-            $obj_name . $line_item->name(),
315
-            $line_item
316
-        );
317
-        $name_and_desc .= apply_filters(
318
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc',
319
-            (
320
-                $options['show_desc']
321
-                ? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>'
322
-                : ''
323
-            ),
324
-            $line_item,
325
-            $options
326
-        );
327
-        $name_and_desc .= $line_item->is_taxable() ? ' * ' : '';
328
-        // name td
329
-        $html .= EEH_HTML::td($name_and_desc, '', 'item_l');
330
-        // price td
331
-        if ($line_item->is_percent()) {
332
-            $html .= EEH_HTML::td($line_item->percent() . '%', '', 'item_c jst-rght');
333
-        } else {
334
-            $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
335
-        }
336
-        // quantity td
337
-        $html .= EEH_HTML::td($line_item->quantity(), '', 'item_l jst-rght');
338
-        // $total = $line_item->total() * $line_item->quantity();
339
-        $total = $line_item->total();
340
-        if (isset($options['event_id'], $this->_events[ $options['event_id'] ])) {
341
-            $this->_events[ $options['event_id'] ] += $total;
342
-        }
343
-        // total td
344
-        $html .= EEH_HTML::td(
345
-            EEH_Template::format_currency($total, false, false),
346
-            '',
347
-            'item_r jst-rght'
348
-        );
349
-        // end of row
350
-        $html .= EEH_HTML::trx();
351
-        return $html;
352
-    }
353
-
354
-
355
-
356
-    /**
357
-     * _sub_item_row
358
-     *
359
-     * @param EE_Line_Item $line_item
360
-     * @param array        $options
361
-     * @param EE_Line_Item $parent_line_item
362
-     * @return mixed
363
-     * @throws EE_Error
364
-     */
365
-    private function _sub_item_row(EE_Line_Item $line_item, $options = array(), EE_Line_Item $parent_line_item = null)
366
-    {
367
-        if ($parent_line_item instanceof  EE_Line_Item
368
-            && $line_item->children() === array()
369
-            && $line_item->name() === $parent_line_item->name()
370
-        ) {
371
-            return '';
372
-        }
373
-        // start of row
374
-        $html = EEH_HTML::tr('', '', 'item sub-item-row');
375
-        // name && desc
376
-        $name_and_desc = EEH_HTML::span('', '', 'sub-item-row-bullet dashicons dashicons-arrow-right')
377
-                         . $line_item->name();
378
-        $name_and_desc .= $options['show_desc'] ? '<span class="line-sub-item-desc-spn smaller-text">: '
379
-                                                  . $line_item->desc()
380
-                                                  . '</span>' : '';
381
-        // name td
382
-        $html .= EEH_HTML::td($name_and_desc, '', 'item_l sub-item');
383
-        $qty = $parent_line_item instanceof EE_Line_Item ? $parent_line_item->quantity() : 1;
384
-        // discount/surcharge td
385
-        if ($line_item->is_percent()) {
386
-            $html .= EEH_HTML::td(
387
-                EEH_Template::format_currency(
388
-                    $line_item->total() / $qty,
389
-                    false,
390
-                    false
391
-                ),
392
-                '',
393
-                'item_c jst-rght'
394
-            );
395
-        } else {
396
-            $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
397
-        }
398
-        // no quantity td
399
-        $html .= EEH_HTML::td();
400
-        // no total td
401
-        $html .= EEH_HTML::td();
402
-        // end of row
403
-        $html .= EEH_HTML::trx();
404
-        return $html;
405
-    }
406
-
407
-
408
-
409
-    /**
410
-     * _tax_row
411
-     *
412
-     * @param EE_Line_Item $line_item
413
-     * @param array        $options
414
-     * @return mixed
415
-     * @throws EE_Error
416
-     */
417
-    private function _tax_row(EE_Line_Item $line_item, $options = array())
418
-    {
419
-        // start of row
420
-        $html = EEH_HTML::tr('', 'item sub-item tax-total');
421
-        // name && desc
422
-        $name_and_desc = $line_item->name();
423
-        $name_and_desc .= '<span class="smaller-text lt-grey-text" style="margin:0 0 0 2em;">'
424
-                          . esc_html__(' * taxable items', 'event_espresso') . '</span>';
425
-        $name_and_desc .= $options['show_desc'] ? '<br/>' . $line_item->desc() : '';
426
-        // name td
427
-        $html .= EEH_HTML::td( /*__FUNCTION__ .*/
428
-            $name_and_desc,
429
-            '',
430
-            'item_l sub-item'
431
-        );
432
-        // percent td
433
-        $html .= EEH_HTML::td($line_item->percent() . '%', '', ' jst-rght', '');
434
-        // empty td (price)
435
-        $html .= EEH_HTML::td(EEH_HTML::nbsp());
436
-        // total td
437
-        $html .= EEH_HTML::td(
438
-            EEH_Template::format_currency(
439
-                $line_item->total(),
440
-                false,
441
-                false
442
-            ),
443
-            '',
444
-            'item_r jst-rght'
445
-        );
446
-        // end of row
447
-        $html .= EEH_HTML::trx();
448
-        return $html;
449
-    }
450
-
451
-
452
-
453
-    /**
454
-     * _total_row
455
-     *
456
-     * @param EE_Line_Item $line_item
457
-     * @param string       $text
458
-     * @return mixed
459
-     * @throws EE_Error
460
-     */
461
-    private function _total_tax_row(EE_Line_Item $line_item, $text = '')
462
-    {
463
-        $html = '';
464
-        if ($line_item->total()) {
465
-            // start of row
466
-            $html = EEH_HTML::tr('', '', 'total_tr odd');
467
-            // total td
468
-            $html .= EEH_HTML::td(
469
-                $text,
470
-                '',
471
-                'total_currency total jst-rght',
472
-                '',
473
-                ' colspan="2"'
474
-            );
475
-            // empty td (price)
476
-            $html .= EEH_HTML::td(EEH_HTML::nbsp());
477
-            // total td
478
-            $html .= EEH_HTML::td(
479
-                EEH_Template::format_currency($line_item->total(), false, false),
480
-                '',
481
-                'total jst-rght'
482
-            );
483
-            // end of row
484
-            $html .= EEH_HTML::trx();
485
-        }
486
-        return $html;
487
-    }
488
-
489
-
490
-
491
-    /**
492
-     * _total_row
493
-     *
494
-     * @param EE_Line_Item $line_item
495
-     * @param string       $text
496
-     * @param array        $options
497
-     * @return mixed
498
-     * @throws EE_Error
499
-     */
500
-    private function _sub_total_row(EE_Line_Item $line_item, $text = '', $options = array())
501
-    {
502
-        $html = '';
503
-        if ($line_item->total()) {
504
-            // start of row
505
-            $html = EEH_HTML::tr('', '', 'total_tr odd');
506
-            // total td
507
-            $html .= EEH_HTML::td(
508
-                $text,
509
-                '',
510
-                'total_currency total jst-rght',
511
-                '',
512
-                ' colspan="3"'
513
-            );
514
-            // total td
515
-            $html .= EEH_HTML::td(
516
-                EEH_Template::format_currency($options['sub_total'], false, false),
517
-                '',
518
-                'total jst-rght'
519
-            );
520
-            // end of row
521
-            $html .= EEH_HTML::trx();
522
-        }
523
-        return $html;
524
-    }
525
-
526
-
527
-
528
-    /**
529
-     * _total_row
530
-     *
531
-     * @param EE_Line_Item $line_item
532
-     * @param string       $text
533
-     * @return mixed
534
-     * @throws EE_Error
535
-     */
536
-    private function _total_row(EE_Line_Item $line_item, $text = '')
537
-    {
538
-        // start of row
539
-        $html = EEH_HTML::tr('', '', 'spco-grand-total total_tr odd');
540
-        // total td
541
-        $html .= EEH_HTML::td($text, '', 'total_currency total jst-rght', '', ' colspan="3"');
542
-        // total td
543
-        $html .= EEH_HTML::td(
544
-            EEH_Template::format_currency($line_item->total(), false, false),
545
-            '',
546
-            'total jst-rght'
547
-        );
548
-        // end of row
549
-        $html .= EEH_HTML::trx();
550
-        return $html;
551
-    }
552
-
553
-
554
-
555
-    /**
556
-     * _payments_and_amount_owing_rows
557
-     *
558
-     * @param EE_Line_Item $line_item
559
-     * @param array        $options
560
-     * @return mixed
561
-     * @throws EE_Error
562
-     */
563
-    private function _payments_and_amount_owing_rows(EE_Line_Item $line_item, $options = array())
564
-    {
565
-        $html = '';
566
-        $owing = $line_item->total();
567
-        $transaction = EEM_Transaction::instance()->get_one_by_ID($line_item->TXN_ID());
568
-        if ($transaction instanceof EE_Transaction) {
569
-            $registration_payments = array();
570
-            $registrations = ! empty($options['registrations'])
571
-                ? $options['registrations']
572
-                : $transaction->registrations();
573
-            foreach ($registrations as $registration) {
574
-                if ($registration instanceof EE_Registration && $registration->owes_monies_and_can_pay()) {
575
-                    $registration_payments += $registration->registration_payments();
576
-                }
577
-            }
578
-            if (! empty($registration_payments)) {
579
-                foreach ($registration_payments as $registration_payment) {
580
-                    if ($registration_payment instanceof EE_Registration_Payment) {
581
-                        $owing -= $registration_payment->amount();
582
-                        $payment = $registration_payment->payment();
583
-                        $payment_desc = '';
584
-                        if ($payment instanceof EE_Payment) {
585
-                            $payment_desc = sprintf(
586
-                                esc_html__('Payment%1$s Received: %2$s', 'event_espresso'),
587
-                                $payment->txn_id_chq_nmbr() !== ''
588
-                                    ? ' <span class="small-text">(#' . $payment->txn_id_chq_nmbr() . ')</span> '
589
-                                    : '',
590
-                                $payment->timestamp()
591
-                            );
592
-                        }
593
-                        // start of row
594
-                        $html .= EEH_HTML::tr('', '', 'total_tr odd');
595
-                        // payment desc
596
-                        $html .= EEH_HTML::td($payment_desc, '', '', '', ' colspan="3"');
597
-                        // total td
598
-                        $html .= EEH_HTML::td(
599
-                            EEH_Template::format_currency(
600
-                                $registration_payment->amount(),
601
-                                false,
602
-                                false
603
-                            ),
604
-                            '',
605
-                            'total jst-rght'
606
-                        );
607
-                        // end of row
608
-                        $html .= EEH_HTML::trx();
609
-                    }
610
-                }
611
-                if ($line_item->total()) {
612
-                    // start of row
613
-                    $html .= EEH_HTML::tr('', '', 'total_tr odd');
614
-                    // total td
615
-                    $html .= EEH_HTML::td(
616
-                        esc_html__('Amount Owing', 'event_espresso'),
617
-                        '',
618
-                        'total_currency total jst-rght',
619
-                        '',
620
-                        ' colspan="3"'
621
-                    );
622
-                    // total td
623
-                    $html .= EEH_HTML::td(
624
-                        EEH_Template::format_currency($owing, false, false),
625
-                        '',
626
-                        'total jst-rght'
627
-                    );
628
-                    // end of row
629
-                    $html .= EEH_HTML::trx();
630
-                }
631
-            }
632
-        }
633
-        $this->_grand_total = $owing;
634
-        return $html;
635
-    }
15
+	/**
16
+	 * array of events
17
+	 *
18
+	 * @type EE_Line_Item[] $_events
19
+	 */
20
+	private $_events = array();
21
+
22
+	/**
23
+	 * whether to display the taxes row or not
24
+	 *
25
+	 * @type bool $_show_taxes
26
+	 */
27
+	private $_show_taxes = false;
28
+
29
+	/**
30
+	 * html for any tax rows
31
+	 *
32
+	 * @type string $_show_taxes
33
+	 */
34
+	private $_taxes_html = '';
35
+
36
+	/**
37
+	 * total amount including tax we can bill for at this time
38
+	 *
39
+	 * @type float $_grand_total
40
+	 */
41
+	private $_grand_total = 0.00;
42
+
43
+	/**
44
+	 * total number of items being billed for
45
+	 *
46
+	 * @type int $_total_items
47
+	 */
48
+	private $_total_items = 0;
49
+
50
+
51
+
52
+	/**
53
+	 * @return float
54
+	 */
55
+	public function grand_total()
56
+	{
57
+		return $this->_grand_total;
58
+	}
59
+
60
+
61
+
62
+	/**
63
+	 * @return int
64
+	 */
65
+	public function total_items()
66
+	{
67
+		return $this->_total_items;
68
+	}
69
+
70
+
71
+
72
+	/**
73
+	 * @param EE_Line_Item $line_item
74
+	 * @param array        $options
75
+	 * @param EE_Line_Item $parent_line_item
76
+	 * @return mixed
77
+	 * @throws EE_Error
78
+	 */
79
+	public function display_line_item(
80
+		EE_Line_Item $line_item,
81
+		$options = array(),
82
+		EE_Line_Item $parent_line_item = null
83
+	) {
84
+		$html = '';
85
+		// set some default options and merge with incoming
86
+		$default_options = array(
87
+			'show_desc' => true,  //    true        false
88
+			'odd'       => false,
89
+		);
90
+		$options = array_merge($default_options, (array) $options);
91
+		switch ($line_item->type()) {
92
+			case EEM_Line_Item::type_line_item:
93
+				$this->_show_taxes = $line_item->is_taxable() ? true : $this->_show_taxes;
94
+				if ($line_item->OBJ_type() === 'Ticket') {
95
+					// item row
96
+					$html .= $this->_ticket_row($line_item, $options);
97
+				} else {
98
+					// item row
99
+					$html .= $this->_item_row($line_item, $options);
100
+				}
101
+				if (apply_filters(
102
+					'FHEE__EE_SPCO_Line_Item_Display_Strategy__display_line_item__display_sub_line_items',
103
+					true
104
+				)
105
+				) {
106
+					// got any kids?
107
+					foreach ($line_item->children() as $child_line_item) {
108
+						$html .= $this->display_line_item($child_line_item, $options, $line_item);
109
+					}
110
+				}
111
+				break;
112
+			case EEM_Line_Item::type_sub_line_item:
113
+				$html .= $this->_sub_item_row($line_item, $options, $parent_line_item);
114
+				break;
115
+			case EEM_Line_Item::type_sub_total:
116
+				static $sub_total = 0;
117
+				$event_sub_total = 0;
118
+				$text = esc_html__('Sub-Total', 'event_espresso');
119
+				if ($line_item->OBJ_type() === 'Event') {
120
+					$options['event_id'] = $event_id = $line_item->OBJ_ID();
121
+					if (! isset($this->_events[ $options['event_id'] ])) {
122
+						$event = EEM_Event::instance()->get_one_by_ID($options['event_id']);
123
+						// if event has default reg status of Not Approved, then don't display info on it
124
+						if ($event instanceof EE_Event
125
+							&& $event->default_registration_status() === EEM_Registration::status_id_not_approved
126
+						) {
127
+							$display_event = false;
128
+							// unless there are registrations for it that are returning to pay
129
+							if (isset($options['registrations']) && is_array($options['registrations'])) {
130
+								foreach ($options['registrations'] as $registration) {
131
+									if (! $registration instanceof EE_Registration) {
132
+										continue;
133
+									}
134
+									$display_event = $registration->event_ID() === $options['event_id']
135
+													 && $registration->status_ID() !== EEM_Registration::status_id_not_approved
136
+										? true
137
+										: $display_event;
138
+								}
139
+							}
140
+							if (! $display_event) {
141
+								return '';
142
+							}
143
+						}
144
+						$this->_events[ $options['event_id'] ] = 0;
145
+						$html .= $this->_event_row($line_item);
146
+						$text = esc_html__('Event Sub-Total', 'event_espresso');
147
+					}
148
+				}
149
+				$child_line_items = $line_item->children();
150
+				// loop thru children
151
+				foreach ($child_line_items as $child_line_item) {
152
+					// recursively feed children back into this method
153
+					$html .= $this->display_line_item($child_line_item, $options, $line_item);
154
+				}
155
+				$event_sub_total += isset($options['event_id']) ? $this->_events[ $options['event_id'] ] : 0;
156
+				$sub_total += $event_sub_total;
157
+				if ((
158
+						// event subtotals
159
+						$line_item->code() !== 'pre-tax-subtotal' && count($child_line_items) > 1
160
+					)
161
+					|| (
162
+						// pre-tax subtotals
163
+						$line_item->code() === 'pre-tax-subtotal' && count($this->_events) > 1
164
+					)
165
+				) {
166
+					$options['sub_total'] = $line_item->OBJ_type() === 'Event' ? $event_sub_total : $sub_total;
167
+					$html .= $this->_sub_total_row($line_item, $text, $options);
168
+				}
169
+				break;
170
+			case EEM_Line_Item::type_tax:
171
+				if ($this->_show_taxes) {
172
+					$this->_taxes_html .= $this->_tax_row($line_item, $options);
173
+				}
174
+				break;
175
+			case EEM_Line_Item::type_tax_sub_total:
176
+				if ($this->_show_taxes) {
177
+					$child_line_items = $line_item->children();
178
+					// loop thru children
179
+					foreach ($child_line_items as $child_line_item) {
180
+						// recursively feed children back into this method
181
+						$html .= $this->display_line_item($child_line_item, $options, $line_item);
182
+					}
183
+					if (count($child_line_items) > 1) {
184
+						$this->_taxes_html .= $this->_total_tax_row($line_item, esc_html__('Tax Total', 'event_espresso'));
185
+					}
186
+				}
187
+				break;
188
+			case EEM_Line_Item::type_total:
189
+				// get all child line items
190
+				$children = $line_item->children();
191
+				// loop thru all non-tax child line items
192
+				foreach ($children as $child_line_item) {
193
+					if ($child_line_item->type() !== EEM_Line_Item::type_tax_sub_total) {
194
+						// recursively feed children back into this method
195
+						$html .= $this->display_line_item($child_line_item, $options, $line_item);
196
+					}
197
+				}
198
+				// now loop thru  tax child line items
199
+				foreach ($children as $child_line_item) {
200
+					if ($child_line_item->type() === EEM_Line_Item::type_tax_sub_total) {
201
+						// recursively feed children back into this method
202
+						$html .= $this->display_line_item($child_line_item, $options, $line_item);
203
+					}
204
+				}
205
+				$html .= $this->_taxes_html;
206
+				$html .= $this->_total_row($line_item, esc_html__('Total', 'event_espresso'));
207
+				$html .= $this->_payments_and_amount_owing_rows($line_item, $options);
208
+				break;
209
+		}
210
+		return $html;
211
+	}
212
+
213
+
214
+
215
+	/**
216
+	 * _event_row - basically a Heading row displayed once above each event's ticket rows
217
+	 *
218
+	 * @param EE_Line_Item $line_item
219
+	 * @return mixed
220
+	 */
221
+	private function _event_row(EE_Line_Item $line_item)
222
+	{
223
+		// start of row
224
+		$html = EEH_HTML::tr('', 'event-cart-total-row', 'total_tr odd');
225
+		// event name td
226
+		$html .= EEH_HTML::td(
227
+			EEH_HTML::strong($line_item->name()),
228
+			'',
229
+			'event-header',
230
+			'',
231
+			' colspan="4"'
232
+		);
233
+		// end of row
234
+		$html .= EEH_HTML::trx();
235
+		return $html;
236
+	}
237
+
238
+
239
+
240
+	/**
241
+	 * _ticket_row
242
+	 *
243
+	 * @param EE_Line_Item $line_item
244
+	 * @param array        $options
245
+	 * @return mixed
246
+	 * @throws EE_Error
247
+	 */
248
+	private function _ticket_row(EE_Line_Item $line_item, $options = array())
249
+	{
250
+		// start of row
251
+		$row_class = $options['odd'] ? 'item odd' : 'item';
252
+		$html = EEH_HTML::tr('', '', $row_class);
253
+		// name && desc
254
+		$name_and_desc = apply_filters(
255
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__name',
256
+			$line_item->name(),
257
+			$line_item
258
+		);
259
+		$name_and_desc .= apply_filters(
260
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc',
261
+			(
262
+				$options['show_desc']
263
+					? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>'
264
+					: ''
265
+			),
266
+			$line_item,
267
+			$options
268
+		);
269
+		$name_and_desc .= $line_item->is_taxable() ? ' * ' : '';
270
+		// name td
271
+		$html .= EEH_HTML::td( /*__FUNCTION__ .*/
272
+			$name_and_desc,
273
+			'',
274
+			'item_l'
275
+		);
276
+		// price td
277
+		$html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
278
+		// quantity td
279
+		$html .= EEH_HTML::td($line_item->quantity(), '', 'item_l jst-rght');
280
+		$this->_total_items += $line_item->quantity();
281
+		// determine total for line item
282
+		$total = $line_item->total();
283
+		$this->_events[ $options['event_id'] ] += $total;
284
+		// total td
285
+		$html .= EEH_HTML::td(
286
+			EEH_Template::format_currency($total, false, false),
287
+			'',
288
+			'item_r jst-rght'
289
+		);
290
+		// end of row
291
+		$html .= EEH_HTML::trx();
292
+		return $html;
293
+	}
294
+
295
+
296
+
297
+	/**
298
+	 * _item_row
299
+	 *
300
+	 * @param EE_Line_Item $line_item
301
+	 * @param array        $options
302
+	 * @return mixed
303
+	 * @throws EE_Error
304
+	 */
305
+	private function _item_row(EE_Line_Item $line_item, $options = array())
306
+	{
307
+		// start of row
308
+		$row_class = $options['odd'] ? 'item odd' : 'item';
309
+		$html = EEH_HTML::tr('', '', $row_class);
310
+		$obj_name = $line_item->OBJ_type() ? $line_item->OBJ_type_i18n() . ': ' : '';
311
+		// name && desc
312
+		$name_and_desc = apply_filters(
313
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__name',
314
+			$obj_name . $line_item->name(),
315
+			$line_item
316
+		);
317
+		$name_and_desc .= apply_filters(
318
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc',
319
+			(
320
+				$options['show_desc']
321
+				? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>'
322
+				: ''
323
+			),
324
+			$line_item,
325
+			$options
326
+		);
327
+		$name_and_desc .= $line_item->is_taxable() ? ' * ' : '';
328
+		// name td
329
+		$html .= EEH_HTML::td($name_and_desc, '', 'item_l');
330
+		// price td
331
+		if ($line_item->is_percent()) {
332
+			$html .= EEH_HTML::td($line_item->percent() . '%', '', 'item_c jst-rght');
333
+		} else {
334
+			$html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
335
+		}
336
+		// quantity td
337
+		$html .= EEH_HTML::td($line_item->quantity(), '', 'item_l jst-rght');
338
+		// $total = $line_item->total() * $line_item->quantity();
339
+		$total = $line_item->total();
340
+		if (isset($options['event_id'], $this->_events[ $options['event_id'] ])) {
341
+			$this->_events[ $options['event_id'] ] += $total;
342
+		}
343
+		// total td
344
+		$html .= EEH_HTML::td(
345
+			EEH_Template::format_currency($total, false, false),
346
+			'',
347
+			'item_r jst-rght'
348
+		);
349
+		// end of row
350
+		$html .= EEH_HTML::trx();
351
+		return $html;
352
+	}
353
+
354
+
355
+
356
+	/**
357
+	 * _sub_item_row
358
+	 *
359
+	 * @param EE_Line_Item $line_item
360
+	 * @param array        $options
361
+	 * @param EE_Line_Item $parent_line_item
362
+	 * @return mixed
363
+	 * @throws EE_Error
364
+	 */
365
+	private function _sub_item_row(EE_Line_Item $line_item, $options = array(), EE_Line_Item $parent_line_item = null)
366
+	{
367
+		if ($parent_line_item instanceof  EE_Line_Item
368
+			&& $line_item->children() === array()
369
+			&& $line_item->name() === $parent_line_item->name()
370
+		) {
371
+			return '';
372
+		}
373
+		// start of row
374
+		$html = EEH_HTML::tr('', '', 'item sub-item-row');
375
+		// name && desc
376
+		$name_and_desc = EEH_HTML::span('', '', 'sub-item-row-bullet dashicons dashicons-arrow-right')
377
+						 . $line_item->name();
378
+		$name_and_desc .= $options['show_desc'] ? '<span class="line-sub-item-desc-spn smaller-text">: '
379
+												  . $line_item->desc()
380
+												  . '</span>' : '';
381
+		// name td
382
+		$html .= EEH_HTML::td($name_and_desc, '', 'item_l sub-item');
383
+		$qty = $parent_line_item instanceof EE_Line_Item ? $parent_line_item->quantity() : 1;
384
+		// discount/surcharge td
385
+		if ($line_item->is_percent()) {
386
+			$html .= EEH_HTML::td(
387
+				EEH_Template::format_currency(
388
+					$line_item->total() / $qty,
389
+					false,
390
+					false
391
+				),
392
+				'',
393
+				'item_c jst-rght'
394
+			);
395
+		} else {
396
+			$html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
397
+		}
398
+		// no quantity td
399
+		$html .= EEH_HTML::td();
400
+		// no total td
401
+		$html .= EEH_HTML::td();
402
+		// end of row
403
+		$html .= EEH_HTML::trx();
404
+		return $html;
405
+	}
406
+
407
+
408
+
409
+	/**
410
+	 * _tax_row
411
+	 *
412
+	 * @param EE_Line_Item $line_item
413
+	 * @param array        $options
414
+	 * @return mixed
415
+	 * @throws EE_Error
416
+	 */
417
+	private function _tax_row(EE_Line_Item $line_item, $options = array())
418
+	{
419
+		// start of row
420
+		$html = EEH_HTML::tr('', 'item sub-item tax-total');
421
+		// name && desc
422
+		$name_and_desc = $line_item->name();
423
+		$name_and_desc .= '<span class="smaller-text lt-grey-text" style="margin:0 0 0 2em;">'
424
+						  . esc_html__(' * taxable items', 'event_espresso') . '</span>';
425
+		$name_and_desc .= $options['show_desc'] ? '<br/>' . $line_item->desc() : '';
426
+		// name td
427
+		$html .= EEH_HTML::td( /*__FUNCTION__ .*/
428
+			$name_and_desc,
429
+			'',
430
+			'item_l sub-item'
431
+		);
432
+		// percent td
433
+		$html .= EEH_HTML::td($line_item->percent() . '%', '', ' jst-rght', '');
434
+		// empty td (price)
435
+		$html .= EEH_HTML::td(EEH_HTML::nbsp());
436
+		// total td
437
+		$html .= EEH_HTML::td(
438
+			EEH_Template::format_currency(
439
+				$line_item->total(),
440
+				false,
441
+				false
442
+			),
443
+			'',
444
+			'item_r jst-rght'
445
+		);
446
+		// end of row
447
+		$html .= EEH_HTML::trx();
448
+		return $html;
449
+	}
450
+
451
+
452
+
453
+	/**
454
+	 * _total_row
455
+	 *
456
+	 * @param EE_Line_Item $line_item
457
+	 * @param string       $text
458
+	 * @return mixed
459
+	 * @throws EE_Error
460
+	 */
461
+	private function _total_tax_row(EE_Line_Item $line_item, $text = '')
462
+	{
463
+		$html = '';
464
+		if ($line_item->total()) {
465
+			// start of row
466
+			$html = EEH_HTML::tr('', '', 'total_tr odd');
467
+			// total td
468
+			$html .= EEH_HTML::td(
469
+				$text,
470
+				'',
471
+				'total_currency total jst-rght',
472
+				'',
473
+				' colspan="2"'
474
+			);
475
+			// empty td (price)
476
+			$html .= EEH_HTML::td(EEH_HTML::nbsp());
477
+			// total td
478
+			$html .= EEH_HTML::td(
479
+				EEH_Template::format_currency($line_item->total(), false, false),
480
+				'',
481
+				'total jst-rght'
482
+			);
483
+			// end of row
484
+			$html .= EEH_HTML::trx();
485
+		}
486
+		return $html;
487
+	}
488
+
489
+
490
+
491
+	/**
492
+	 * _total_row
493
+	 *
494
+	 * @param EE_Line_Item $line_item
495
+	 * @param string       $text
496
+	 * @param array        $options
497
+	 * @return mixed
498
+	 * @throws EE_Error
499
+	 */
500
+	private function _sub_total_row(EE_Line_Item $line_item, $text = '', $options = array())
501
+	{
502
+		$html = '';
503
+		if ($line_item->total()) {
504
+			// start of row
505
+			$html = EEH_HTML::tr('', '', 'total_tr odd');
506
+			// total td
507
+			$html .= EEH_HTML::td(
508
+				$text,
509
+				'',
510
+				'total_currency total jst-rght',
511
+				'',
512
+				' colspan="3"'
513
+			);
514
+			// total td
515
+			$html .= EEH_HTML::td(
516
+				EEH_Template::format_currency($options['sub_total'], false, false),
517
+				'',
518
+				'total jst-rght'
519
+			);
520
+			// end of row
521
+			$html .= EEH_HTML::trx();
522
+		}
523
+		return $html;
524
+	}
525
+
526
+
527
+
528
+	/**
529
+	 * _total_row
530
+	 *
531
+	 * @param EE_Line_Item $line_item
532
+	 * @param string       $text
533
+	 * @return mixed
534
+	 * @throws EE_Error
535
+	 */
536
+	private function _total_row(EE_Line_Item $line_item, $text = '')
537
+	{
538
+		// start of row
539
+		$html = EEH_HTML::tr('', '', 'spco-grand-total total_tr odd');
540
+		// total td
541
+		$html .= EEH_HTML::td($text, '', 'total_currency total jst-rght', '', ' colspan="3"');
542
+		// total td
543
+		$html .= EEH_HTML::td(
544
+			EEH_Template::format_currency($line_item->total(), false, false),
545
+			'',
546
+			'total jst-rght'
547
+		);
548
+		// end of row
549
+		$html .= EEH_HTML::trx();
550
+		return $html;
551
+	}
552
+
553
+
554
+
555
+	/**
556
+	 * _payments_and_amount_owing_rows
557
+	 *
558
+	 * @param EE_Line_Item $line_item
559
+	 * @param array        $options
560
+	 * @return mixed
561
+	 * @throws EE_Error
562
+	 */
563
+	private function _payments_and_amount_owing_rows(EE_Line_Item $line_item, $options = array())
564
+	{
565
+		$html = '';
566
+		$owing = $line_item->total();
567
+		$transaction = EEM_Transaction::instance()->get_one_by_ID($line_item->TXN_ID());
568
+		if ($transaction instanceof EE_Transaction) {
569
+			$registration_payments = array();
570
+			$registrations = ! empty($options['registrations'])
571
+				? $options['registrations']
572
+				: $transaction->registrations();
573
+			foreach ($registrations as $registration) {
574
+				if ($registration instanceof EE_Registration && $registration->owes_monies_and_can_pay()) {
575
+					$registration_payments += $registration->registration_payments();
576
+				}
577
+			}
578
+			if (! empty($registration_payments)) {
579
+				foreach ($registration_payments as $registration_payment) {
580
+					if ($registration_payment instanceof EE_Registration_Payment) {
581
+						$owing -= $registration_payment->amount();
582
+						$payment = $registration_payment->payment();
583
+						$payment_desc = '';
584
+						if ($payment instanceof EE_Payment) {
585
+							$payment_desc = sprintf(
586
+								esc_html__('Payment%1$s Received: %2$s', 'event_espresso'),
587
+								$payment->txn_id_chq_nmbr() !== ''
588
+									? ' <span class="small-text">(#' . $payment->txn_id_chq_nmbr() . ')</span> '
589
+									: '',
590
+								$payment->timestamp()
591
+							);
592
+						}
593
+						// start of row
594
+						$html .= EEH_HTML::tr('', '', 'total_tr odd');
595
+						// payment desc
596
+						$html .= EEH_HTML::td($payment_desc, '', '', '', ' colspan="3"');
597
+						// total td
598
+						$html .= EEH_HTML::td(
599
+							EEH_Template::format_currency(
600
+								$registration_payment->amount(),
601
+								false,
602
+								false
603
+							),
604
+							'',
605
+							'total jst-rght'
606
+						);
607
+						// end of row
608
+						$html .= EEH_HTML::trx();
609
+					}
610
+				}
611
+				if ($line_item->total()) {
612
+					// start of row
613
+					$html .= EEH_HTML::tr('', '', 'total_tr odd');
614
+					// total td
615
+					$html .= EEH_HTML::td(
616
+						esc_html__('Amount Owing', 'event_espresso'),
617
+						'',
618
+						'total_currency total jst-rght',
619
+						'',
620
+						' colspan="3"'
621
+					);
622
+					// total td
623
+					$html .= EEH_HTML::td(
624
+						EEH_Template::format_currency($owing, false, false),
625
+						'',
626
+						'total jst-rght'
627
+					);
628
+					// end of row
629
+					$html .= EEH_HTML::trx();
630
+				}
631
+			}
632
+		}
633
+		$this->_grand_total = $owing;
634
+		return $html;
635
+	}
636 636
 }
Please login to merge, or discard this patch.
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -84,7 +84,7 @@  discard block
 block discarded – undo
84 84
         $html = '';
85 85
         // set some default options and merge with incoming
86 86
         $default_options = array(
87
-            'show_desc' => true,  //    true        false
87
+            'show_desc' => true, //    true        false
88 88
             'odd'       => false,
89 89
         );
90 90
         $options = array_merge($default_options, (array) $options);
@@ -118,7 +118,7 @@  discard block
 block discarded – undo
118 118
                 $text = esc_html__('Sub-Total', 'event_espresso');
119 119
                 if ($line_item->OBJ_type() === 'Event') {
120 120
                     $options['event_id'] = $event_id = $line_item->OBJ_ID();
121
-                    if (! isset($this->_events[ $options['event_id'] ])) {
121
+                    if ( ! isset($this->_events[$options['event_id']])) {
122 122
                         $event = EEM_Event::instance()->get_one_by_ID($options['event_id']);
123 123
                         // if event has default reg status of Not Approved, then don't display info on it
124 124
                         if ($event instanceof EE_Event
@@ -128,7 +128,7 @@  discard block
 block discarded – undo
128 128
                             // unless there are registrations for it that are returning to pay
129 129
                             if (isset($options['registrations']) && is_array($options['registrations'])) {
130 130
                                 foreach ($options['registrations'] as $registration) {
131
-                                    if (! $registration instanceof EE_Registration) {
131
+                                    if ( ! $registration instanceof EE_Registration) {
132 132
                                         continue;
133 133
                                     }
134 134
                                     $display_event = $registration->event_ID() === $options['event_id']
@@ -137,11 +137,11 @@  discard block
 block discarded – undo
137 137
                                         : $display_event;
138 138
                                 }
139 139
                             }
140
-                            if (! $display_event) {
140
+                            if ( ! $display_event) {
141 141
                                 return '';
142 142
                             }
143 143
                         }
144
-                        $this->_events[ $options['event_id'] ] = 0;
144
+                        $this->_events[$options['event_id']] = 0;
145 145
                         $html .= $this->_event_row($line_item);
146 146
                         $text = esc_html__('Event Sub-Total', 'event_espresso');
147 147
                     }
@@ -152,7 +152,7 @@  discard block
 block discarded – undo
152 152
                     // recursively feed children back into this method
153 153
                     $html .= $this->display_line_item($child_line_item, $options, $line_item);
154 154
                 }
155
-                $event_sub_total += isset($options['event_id']) ? $this->_events[ $options['event_id'] ] : 0;
155
+                $event_sub_total += isset($options['event_id']) ? $this->_events[$options['event_id']] : 0;
156 156
                 $sub_total += $event_sub_total;
157 157
                 if ((
158 158
                         // event subtotals
@@ -260,7 +260,7 @@  discard block
 block discarded – undo
260 260
             'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc',
261 261
             (
262 262
                 $options['show_desc']
263
-                    ? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>'
263
+                    ? '<span class="line-item-desc-spn smaller-text">: '.$line_item->desc().'</span>'
264 264
                     : ''
265 265
             ),
266 266
             $line_item,
@@ -280,7 +280,7 @@  discard block
 block discarded – undo
280 280
         $this->_total_items += $line_item->quantity();
281 281
         // determine total for line item
282 282
         $total = $line_item->total();
283
-        $this->_events[ $options['event_id'] ] += $total;
283
+        $this->_events[$options['event_id']] += $total;
284 284
         // total td
285 285
         $html .= EEH_HTML::td(
286 286
             EEH_Template::format_currency($total, false, false),
@@ -307,18 +307,18 @@  discard block
 block discarded – undo
307 307
         // start of row
308 308
         $row_class = $options['odd'] ? 'item odd' : 'item';
309 309
         $html = EEH_HTML::tr('', '', $row_class);
310
-        $obj_name = $line_item->OBJ_type() ? $line_item->OBJ_type_i18n() . ': ' : '';
310
+        $obj_name = $line_item->OBJ_type() ? $line_item->OBJ_type_i18n().': ' : '';
311 311
         // name && desc
312 312
         $name_and_desc = apply_filters(
313 313
             'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__name',
314
-            $obj_name . $line_item->name(),
314
+            $obj_name.$line_item->name(),
315 315
             $line_item
316 316
         );
317 317
         $name_and_desc .= apply_filters(
318 318
             'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc',
319 319
             (
320 320
                 $options['show_desc']
321
-                ? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>'
321
+                ? '<span class="line-item-desc-spn smaller-text">: '.$line_item->desc().'</span>'
322 322
                 : ''
323 323
             ),
324 324
             $line_item,
@@ -329,7 +329,7 @@  discard block
 block discarded – undo
329 329
         $html .= EEH_HTML::td($name_and_desc, '', 'item_l');
330 330
         // price td
331 331
         if ($line_item->is_percent()) {
332
-            $html .= EEH_HTML::td($line_item->percent() . '%', '', 'item_c jst-rght');
332
+            $html .= EEH_HTML::td($line_item->percent().'%', '', 'item_c jst-rght');
333 333
         } else {
334 334
             $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
335 335
         }
@@ -337,8 +337,8 @@  discard block
 block discarded – undo
337 337
         $html .= EEH_HTML::td($line_item->quantity(), '', 'item_l jst-rght');
338 338
         // $total = $line_item->total() * $line_item->quantity();
339 339
         $total = $line_item->total();
340
-        if (isset($options['event_id'], $this->_events[ $options['event_id'] ])) {
341
-            $this->_events[ $options['event_id'] ] += $total;
340
+        if (isset($options['event_id'], $this->_events[$options['event_id']])) {
341
+            $this->_events[$options['event_id']] += $total;
342 342
         }
343 343
         // total td
344 344
         $html .= EEH_HTML::td(
@@ -421,8 +421,8 @@  discard block
 block discarded – undo
421 421
         // name && desc
422 422
         $name_and_desc = $line_item->name();
423 423
         $name_and_desc .= '<span class="smaller-text lt-grey-text" style="margin:0 0 0 2em;">'
424
-                          . esc_html__(' * taxable items', 'event_espresso') . '</span>';
425
-        $name_and_desc .= $options['show_desc'] ? '<br/>' . $line_item->desc() : '';
424
+                          . esc_html__(' * taxable items', 'event_espresso').'</span>';
425
+        $name_and_desc .= $options['show_desc'] ? '<br/>'.$line_item->desc() : '';
426 426
         // name td
427 427
         $html .= EEH_HTML::td( /*__FUNCTION__ .*/
428 428
             $name_and_desc,
@@ -430,7 +430,7 @@  discard block
 block discarded – undo
430 430
             'item_l sub-item'
431 431
         );
432 432
         // percent td
433
-        $html .= EEH_HTML::td($line_item->percent() . '%', '', ' jst-rght', '');
433
+        $html .= EEH_HTML::td($line_item->percent().'%', '', ' jst-rght', '');
434 434
         // empty td (price)
435 435
         $html .= EEH_HTML::td(EEH_HTML::nbsp());
436 436
         // total td
@@ -575,7 +575,7 @@  discard block
 block discarded – undo
575 575
                     $registration_payments += $registration->registration_payments();
576 576
                 }
577 577
             }
578
-            if (! empty($registration_payments)) {
578
+            if ( ! empty($registration_payments)) {
579 579
                 foreach ($registration_payments as $registration_payment) {
580 580
                     if ($registration_payment instanceof EE_Registration_Payment) {
581 581
                         $owing -= $registration_payment->amount();
@@ -585,7 +585,7 @@  discard block
 block discarded – undo
585 585
                             $payment_desc = sprintf(
586 586
                                 esc_html__('Payment%1$s Received: %2$s', 'event_espresso'),
587 587
                                 $payment->txn_id_chq_nmbr() !== ''
588
-                                    ? ' <span class="small-text">(#' . $payment->txn_id_chq_nmbr() . ')</span> '
588
+                                    ? ' <span class="small-text">(#'.$payment->txn_id_chq_nmbr().')</span> '
589 589
                                     : '',
590 590
                                 $payment->timestamp()
591 591
                             );
Please login to merge, or discard this patch.