Completed
Branch BUG-caching-loader-identifier (bfbdc4)
by
unknown
27:45 queued 14:30
created
core/services/container/CoffeeMaker.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
 
70 70
 
71 71
     /**
72
-     * @param $type
72
+     * @param string $type
73 73
      * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
74 74
      */
75 75
     public static function validateType($type)
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
      * Examines the constructor to determine which method should be used for instantiation
128 128
      *
129 129
      * @param \ReflectionClass $reflector
130
-     * @return mixed
130
+     * @return string
131 131
      * @throws InstantiationException
132 132
      */
133 133
     protected function resolveInstantiationMethod(\ReflectionClass $reflector)
Please login to merge, or discard this patch.
Indentation   +152 added lines, -152 removed lines patch added patch discarded remove patch
@@ -18,156 +18,156 @@
 block discarded – undo
18 18
 abstract class CoffeeMaker implements CoffeeMakerInterface
19 19
 {
20 20
 
21
-    /**
22
-     * Indicates that CoffeeMaker should construct a NEW entity instance from the provided arguments (if given)
23
-     */
24
-    const BREW_NEW = 'new';
25
-
26
-    /**
27
-     * Indicates that CoffeeMaker should always return a SHARED instance
28
-     */
29
-    const BREW_SHARED = 'shared';
30
-
31
-    /**
32
-     * Indicates that CoffeeMaker should only load the file/class/interface but NOT instantiate
33
-     */
34
-    const BREW_LOAD_ONLY = 'load_only';
35
-
36
-
37
-    /**
38
-     * @var CoffeePotInterface $coffee_pot
39
-     */
40
-    private $coffee_pot;
41
-
42
-    /**
43
-     * @var DependencyInjector $injector
44
-     */
45
-    private $injector;
46
-
47
-
48
-    /**
49
-     * @return array
50
-     */
51
-    public static function getTypes()
52
-    {
53
-        return (array) apply_filters(
54
-            'FHEE__EventEspresso\core\services\container\CoffeeMaker__getTypes',
55
-            array(
56
-                CoffeeMaker::BREW_NEW,
57
-                CoffeeMaker::BREW_SHARED,
58
-                CoffeeMaker::BREW_LOAD_ONLY,
59
-            )
60
-        );
61
-    }
62
-
63
-
64
-    /**
65
-     * @param $type
66
-     * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
67
-     */
68
-    public static function validateType($type)
69
-    {
70
-        $types = CoffeeMaker::getTypes();
71
-        if (! in_array($type, $types, true)) {
72
-            throw new InvalidIdentifierException(
73
-                is_object($type) ? get_class($type) : gettype($type),
74
-                __(
75
-                    'recipe type (one of the class constants on \EventEspresso\core\services\container\CoffeeMaker)',
76
-                    'event_espresso'
77
-                )
78
-            );
79
-        }
80
-        return $type;
81
-    }
82
-
83
-
84
-    /**
85
-     * CoffeeMaker constructor.
86
-     *
87
-     * @param CoffeePotInterface $coffee_pot
88
-     * @param InjectorInterface  $injector
89
-     */
90
-    public function __construct(CoffeePotInterface $coffee_pot, InjectorInterface $injector)
91
-    {
92
-        $this->coffee_pot = $coffee_pot;
93
-        $this->injector = $injector;
94
-    }
95
-
96
-
97
-    /**
98
-     * @return \EventEspresso\core\services\container\CoffeePotInterface
99
-     */
100
-    protected function coffeePot()
101
-    {
102
-        return $this->coffee_pot;
103
-    }
104
-
105
-
106
-    /**
107
-     * @return \EventEspresso\core\services\container\DependencyInjector
108
-     */
109
-    protected function injector()
110
-    {
111
-        return $this->injector;
112
-    }
113
-
114
-
115
-    /**
116
-     * Examines the constructor to determine which method should be used for instantiation
117
-     *
118
-     * @param \ReflectionClass $reflector
119
-     * @return mixed
120
-     * @throws InstantiationException
121
-     */
122
-    protected function resolveInstantiationMethod(\ReflectionClass $reflector)
123
-    {
124
-        if ($reflector->getConstructor() === null) {
125
-            return 'NewInstance';
126
-        }
127
-        if ($reflector->isInstantiable()) {
128
-            return 'NewInstanceArgs';
129
-        }
130
-        if (method_exists($reflector->getName(), 'instance')) {
131
-            return 'instance';
132
-        }
133
-        if (method_exists($reflector->getName(), 'new_instance')) {
134
-            return 'new_instance';
135
-        }
136
-        if (method_exists($reflector->getName(), 'new_instance_from_db')) {
137
-            return 'new_instance_from_db';
138
-        }
139
-        throw new InstantiationException($reflector->getName());
140
-    }
141
-
142
-
143
-    /**
144
-     * Ensures files for classes that are not PSR-4 compatible are loaded
145
-     * and then verifies that classes exist where applicable
146
-     *
147
-     * @param RecipeInterface $recipe
148
-     * @return bool
149
-     * @throws InvalidClassException
150
-     */
151
-    protected function resolveClassAndFilepath(RecipeInterface $recipe)
152
-    {
153
-        $paths = $recipe->paths();
154
-        if (! empty($paths)) {
155
-            foreach ($paths as $path) {
156
-                if (strpos($path, '*') === false && is_readable($path)) {
157
-                    require_once($path);
158
-                }
159
-            }
160
-        }
161
-        // re: using "false" for class_exists() second param:
162
-        // if a class name is not already known to PHP, then class_exists() will run through
163
-        // all of the registered spl_autoload functions until it either finds the class,
164
-        // or gets to the end of the registered spl_autoload functions.
165
-        // When the second parameter is true, it will also attempt to load the class file,
166
-        // but it will also trigger an error if the class can not be loaded.
167
-        // We don't want that extra error in the mix, so we have set the second param to "false"
168
-        if ($recipe->type() !== CoffeeMaker::BREW_LOAD_ONLY && ! class_exists($recipe->fqcn(), false)) {
169
-            throw new InvalidClassException($recipe->identifier());
170
-        }
171
-        return true;
172
-    }
21
+	/**
22
+	 * Indicates that CoffeeMaker should construct a NEW entity instance from the provided arguments (if given)
23
+	 */
24
+	const BREW_NEW = 'new';
25
+
26
+	/**
27
+	 * Indicates that CoffeeMaker should always return a SHARED instance
28
+	 */
29
+	const BREW_SHARED = 'shared';
30
+
31
+	/**
32
+	 * Indicates that CoffeeMaker should only load the file/class/interface but NOT instantiate
33
+	 */
34
+	const BREW_LOAD_ONLY = 'load_only';
35
+
36
+
37
+	/**
38
+	 * @var CoffeePotInterface $coffee_pot
39
+	 */
40
+	private $coffee_pot;
41
+
42
+	/**
43
+	 * @var DependencyInjector $injector
44
+	 */
45
+	private $injector;
46
+
47
+
48
+	/**
49
+	 * @return array
50
+	 */
51
+	public static function getTypes()
52
+	{
53
+		return (array) apply_filters(
54
+			'FHEE__EventEspresso\core\services\container\CoffeeMaker__getTypes',
55
+			array(
56
+				CoffeeMaker::BREW_NEW,
57
+				CoffeeMaker::BREW_SHARED,
58
+				CoffeeMaker::BREW_LOAD_ONLY,
59
+			)
60
+		);
61
+	}
62
+
63
+
64
+	/**
65
+	 * @param $type
66
+	 * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
67
+	 */
68
+	public static function validateType($type)
69
+	{
70
+		$types = CoffeeMaker::getTypes();
71
+		if (! in_array($type, $types, true)) {
72
+			throw new InvalidIdentifierException(
73
+				is_object($type) ? get_class($type) : gettype($type),
74
+				__(
75
+					'recipe type (one of the class constants on \EventEspresso\core\services\container\CoffeeMaker)',
76
+					'event_espresso'
77
+				)
78
+			);
79
+		}
80
+		return $type;
81
+	}
82
+
83
+
84
+	/**
85
+	 * CoffeeMaker constructor.
86
+	 *
87
+	 * @param CoffeePotInterface $coffee_pot
88
+	 * @param InjectorInterface  $injector
89
+	 */
90
+	public function __construct(CoffeePotInterface $coffee_pot, InjectorInterface $injector)
91
+	{
92
+		$this->coffee_pot = $coffee_pot;
93
+		$this->injector = $injector;
94
+	}
95
+
96
+
97
+	/**
98
+	 * @return \EventEspresso\core\services\container\CoffeePotInterface
99
+	 */
100
+	protected function coffeePot()
101
+	{
102
+		return $this->coffee_pot;
103
+	}
104
+
105
+
106
+	/**
107
+	 * @return \EventEspresso\core\services\container\DependencyInjector
108
+	 */
109
+	protected function injector()
110
+	{
111
+		return $this->injector;
112
+	}
113
+
114
+
115
+	/**
116
+	 * Examines the constructor to determine which method should be used for instantiation
117
+	 *
118
+	 * @param \ReflectionClass $reflector
119
+	 * @return mixed
120
+	 * @throws InstantiationException
121
+	 */
122
+	protected function resolveInstantiationMethod(\ReflectionClass $reflector)
123
+	{
124
+		if ($reflector->getConstructor() === null) {
125
+			return 'NewInstance';
126
+		}
127
+		if ($reflector->isInstantiable()) {
128
+			return 'NewInstanceArgs';
129
+		}
130
+		if (method_exists($reflector->getName(), 'instance')) {
131
+			return 'instance';
132
+		}
133
+		if (method_exists($reflector->getName(), 'new_instance')) {
134
+			return 'new_instance';
135
+		}
136
+		if (method_exists($reflector->getName(), 'new_instance_from_db')) {
137
+			return 'new_instance_from_db';
138
+		}
139
+		throw new InstantiationException($reflector->getName());
140
+	}
141
+
142
+
143
+	/**
144
+	 * Ensures files for classes that are not PSR-4 compatible are loaded
145
+	 * and then verifies that classes exist where applicable
146
+	 *
147
+	 * @param RecipeInterface $recipe
148
+	 * @return bool
149
+	 * @throws InvalidClassException
150
+	 */
151
+	protected function resolveClassAndFilepath(RecipeInterface $recipe)
152
+	{
153
+		$paths = $recipe->paths();
154
+		if (! empty($paths)) {
155
+			foreach ($paths as $path) {
156
+				if (strpos($path, '*') === false && is_readable($path)) {
157
+					require_once($path);
158
+				}
159
+			}
160
+		}
161
+		// re: using "false" for class_exists() second param:
162
+		// if a class name is not already known to PHP, then class_exists() will run through
163
+		// all of the registered spl_autoload functions until it either finds the class,
164
+		// or gets to the end of the registered spl_autoload functions.
165
+		// When the second parameter is true, it will also attempt to load the class file,
166
+		// but it will also trigger an error if the class can not be loaded.
167
+		// We don't want that extra error in the mix, so we have set the second param to "false"
168
+		if ($recipe->type() !== CoffeeMaker::BREW_LOAD_ONLY && ! class_exists($recipe->fqcn(), false)) {
169
+			throw new InvalidClassException($recipe->identifier());
170
+		}
171
+		return true;
172
+	}
173 173
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
     public static function validateType($type)
69 69
     {
70 70
         $types = CoffeeMaker::getTypes();
71
-        if (! in_array($type, $types, true)) {
71
+        if ( ! in_array($type, $types, true)) {
72 72
             throw new InvalidIdentifierException(
73 73
                 is_object($type) ? get_class($type) : gettype($type),
74 74
                 __(
@@ -151,7 +151,7 @@  discard block
 block discarded – undo
151 151
     protected function resolveClassAndFilepath(RecipeInterface $recipe)
152 152
     {
153 153
         $paths = $recipe->paths();
154
-        if (! empty($paths)) {
154
+        if ( ! empty($paths)) {
155 155
             foreach ($paths as $path) {
156 156
                 if (strpos($path, '*') === false && is_readable($path)) {
157 157
                     require_once($path);
Please login to merge, or discard this patch.
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.
Indentation   +587 added lines, -587 removed lines patch added patch discarded remove patch
@@ -11,591 +11,591 @@
 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
-    );
61
-
62
-
63
-
64
-    /**
65
-     * @param EEI_Payment $payment
66
-     * @param array       $billing_info {
67
-     * @type string $credit_card
68
-     * @type string $credit_card_type
69
-     * @type string $exp_month always 2 characters
70
-     * @type string $exp_year always 4 characters
71
-     * @type string $cvv
72
-     * }
73
-     * @see      parent::do_direct_payment for more info
74
-     * @return EE_Payment|EEI_Payment
75
-     * @throws EE_Error
76
-     */
77
-    public function do_direct_payment($payment, $billing_info = null)
78
-    {
79
-        $transaction = $payment->transaction();
80
-        if (! $transaction instanceof EEI_Transaction) {
81
-            throw new EE_Error(
82
-                esc_html__('No transaction for payment while paying with PayPal Pro.', 'event_espresso')
83
-            );
84
-        }
85
-        $primary_registrant = $transaction->primary_registration();
86
-        if (! $primary_registrant instanceof EEI_Registration) {
87
-            throw new EE_Error(
88
-                esc_html__(
89
-                    'No primary registration on transaction while paying with PayPal Pro.',
90
-                    'event_espresso'
91
-                )
92
-            );
93
-        }
94
-        $attendee = $primary_registrant->attendee();
95
-        if (! $attendee instanceof EEI_Attendee) {
96
-            throw new EE_Error(
97
-                esc_html__(
98
-                    'No attendee on primary registration while paying with PayPal Pro.',
99
-                    'event_espresso'
100
-                )
101
-            );
102
-        }
103
-        $gateway_formatter = $this->_get_gateway_formatter();
104
-        $order_description = substr($gateway_formatter->formatOrderDescription($payment), 0, 127);
105
-        // charge for the full amount. Show itemized list
106
-        if ($this->_can_easily_itemize_transaction_for($payment)) {
107
-            $item_num = 1;
108
-            $total_line_item = $transaction->total_line_item();
109
-            $order_items = array();
110
-            foreach ($total_line_item->get_items() as $line_item) {
111
-                // ignore line items with a quantity of 0
112
-                if ($line_item->quantity() == 0) {
113
-                    continue;
114
-                }
115
-                $item = array(
116
-                    // Item Name.  127 char max.
117
-                    'l_name'                 => substr(
118
-                        $gateway_formatter->formatLineItemName($line_item, $payment),
119
-                        0,
120
-                        127
121
-                    ),
122
-                    // Item description.  127 char max.
123
-                    'l_desc'                 => substr(
124
-                        $gateway_formatter->formatLineItemDesc($line_item, $payment),
125
-                        0,
126
-                        127
127
-                    ),
128
-                    // Cost of individual item.
129
-                    'l_amt'                  => $line_item->unit_price(),
130
-                    // Item Number.  127 char max.
131
-                    'l_number'               => $item_num++,
132
-                    // Item quantity.  Must be any positive integer.
133
-                    'l_qty'                  => $line_item->quantity(),
134
-                    // Item's sales tax amount.
135
-                    'l_taxamt'               => '',
136
-                    // eBay auction number of item.
137
-                    'l_ebayitemnumber'       => '',
138
-                    // eBay transaction ID of purchased item.
139
-                    'l_ebayitemauctiontxnid' => '',
140
-                    // eBay order ID for the item.
141
-                    'l_ebayitemorderid'      => '',
142
-                );
143
-                // add to array of all items
144
-                array_push($order_items, $item);
145
-            }
146
-            $item_amount = $total_line_item->get_items_total();
147
-            $tax_amount = $total_line_item->get_total_tax();
148
-        } else {
149
-            $order_items = array();
150
-            $item_amount = $payment->amount();
151
-            $tax_amount = 0;
152
-            array_push($order_items, array(
153
-                // Item Name.  127 char max.
154
-                'l_name'   => substr(
155
-                    $gateway_formatter->formatPartialPaymentLineItemName($payment),
156
-                    0,
157
-                    127
158
-                ),
159
-                // Item description.  127 char max.
160
-                'l_desc'   => substr(
161
-                    $gateway_formatter->formatPartialPaymentLineItemDesc($payment),
162
-                    0,
163
-                    127
164
-                ),
165
-                // Cost of individual item.
166
-                'l_amt'    => $payment->amount(),
167
-                // Item Number.  127 char max.
168
-                'l_number' => 1,
169
-                // Item quantity.  Must be any positive integer.
170
-                'l_qty'    => 1,
171
-            ));
172
-        }
173
-        // Populate data arrays with order data.
174
-        $DPFields = array(
175
-            // How you want to obtain payment ?
176
-            // Authorization indicates the payment is a basic auth subject to settlement with Auth & Capture.
177
-            // Sale indicates that this is a final sale for which you are requesting payment.  Default is Sale.
178
-            'paymentaction'    => 'Sale',
179
-            // Required.  IP address of the payer's browser.
180
-            'ipaddress'        => $_SERVER['REMOTE_ADDR'],
181
-            // Flag to determine whether you want the results returned by FMF.  1 or 0.  Default is 0.
182
-            'returnfmfdetails' => '1',
183
-        );
184
-        $CCDetails = array(
185
-            // Required. Type of credit card.  Visa, MasterCard, Discover, Amex, Maestro, Solo.
186
-            // If Maestro or Solo, the currency code must be GBP.
187
-            //  In addition, either start date or issue number must be specified.
188
-            'creditcardtype' => $billing_info['credit_card_type'],
189
-            // Required.  Credit card number.  No spaces or punctuation.
190
-            'acct'           => $billing_info['credit_card'],
191
-            // Required.  Credit card expiration date.  Format is MMYYYY
192
-            'expdate'        => $billing_info['exp_month'] . $billing_info['exp_year'],
193
-            // Requirements determined by your PayPal account settings.  Security digits for credit card.
194
-            'cvv2'           => $billing_info['cvv'],
195
-        );
196
-        $PayerInfo = array(
197
-            // Email address of payer.
198
-            'email'       => $billing_info['email'],
199
-            // Unique PayPal customer ID for payer.
200
-            'payerid'     => '',
201
-            // Status of payer.  Values are verified or unverified
202
-            'payerstatus' => '',
203
-            // Payer's business name.
204
-            'business'    => '',
205
-        );
206
-        $PayerName = array(
207
-            // Payer's salutation.  20 char max.
208
-            'salutation' => '',
209
-            // Payer's first name.  25 char max.
210
-            'firstname'  => substr($billing_info['first_name'], 0, 25),
211
-            // Payer's middle name.  25 char max.
212
-            'middlename' => '',
213
-            // Payer's last name.  25 char max.
214
-            'lastname'   => substr($billing_info['last_name'], 0, 25),
215
-            // Payer's suffix.  12 char max.
216
-            'suffix'     => '',
217
-        );
218
-        $BillingAddress = array(
219
-            // Required.  First street address.
220
-            'street'      => $billing_info['address'],
221
-            // Second street address.
222
-            'street2'     => $billing_info['address2'],
223
-            // Required.  Name of City.
224
-            'city'        => $billing_info['city'],
225
-            // Required. Name of State or Province.
226
-            'state'       => substr($billing_info['state'], 0, 40),
227
-            // Required.  Country code.
228
-            'countrycode' => $billing_info['country'],
229
-            // Required.  Postal code of payer.
230
-            'zip'         => $billing_info['zip'],
231
-        );
232
-        // check if the registration info contains the needed fields for paypal pro
233
-        // (see https://developer.paypal.com/docs/classic/api/merchant/DoDirectPayment_API_Operation_NVP/)
234
-        if ($attendee->address() && $attendee->city() && $attendee->country_ID()) {
235
-            $use_registration_address_info = true;
236
-        } else {
237
-            $use_registration_address_info = false;
238
-        }
239
-        // so if the attendee has enough data to fill out PayPal Pro's shipping info, use it.
240
-        // If not, use the billing info again
241
-        $ShippingAddress = array(
242
-            'shiptoname'     => substr($use_registration_address_info
243
-                ? $attendee->full_name()
244
-                : $billing_info['first_name'] . ' ' . $billing_info['last_name'], 0, 32),
245
-            'shiptostreet'   => substr($use_registration_address_info
246
-                ? $attendee->address()
247
-                : $billing_info['address'], 0, 100),
248
-            'shiptostreet2'  => substr($use_registration_address_info
249
-                ? $attendee->address2() : $billing_info['address2'], 0, 100),
250
-            'shiptocity'     => substr($use_registration_address_info
251
-                ? $attendee->city()
252
-                : $billing_info['city'], 0, 40),
253
-            'state'          => substr($use_registration_address_info
254
-                ? $attendee->state_name()
255
-                : $billing_info['state'], 0, 40),
256
-            'shiptocountry'  => $use_registration_address_info
257
-                ? $attendee->country_ID()
258
-                : $billing_info['country'],
259
-            'shiptozip'      => substr($use_registration_address_info
260
-                ? $attendee->zip()
261
-                : $billing_info['zip'], 0, 20),
262
-            'shiptophonenum' => substr($use_registration_address_info
263
-                ? $attendee->phone()
264
-                : $billing_info['phone'], 0, 20),
265
-        );
266
-        $PaymentDetails = array(
267
-            // Required.  Total amount of order, including shipping, handling, and tax.
268
-            'amt'          => $gateway_formatter->formatCurrency($payment->amount()),
269
-            // Required.  Three-letter currency code.  Default is USD.
270
-            'currencycode' => $payment->currency_code(),
271
-            // Required if you include itemized cart details. (L_AMTn, etc.)
272
-            // Subtotal of items not including S&H, or tax.
273
-            'itemamt'      => $gateway_formatter->formatCurrency($item_amount),//
274
-            // Total shipping costs for the order.  If you specify shippingamt, you must also specify itemamt.
275
-            'shippingamt'  => '',
276
-            // Total handling costs for the order.  If you specify handlingamt, you must also specify itemamt.
277
-            'handlingamt'  => '',
278
-            // Required if you specify itemized cart tax details.
279
-            // Sum of tax for all items on the order.  Total sales tax.
280
-            'taxamt'       => $gateway_formatter->formatCurrency($tax_amount),
281
-            // Description of the order the customer is purchasing.  127 char max.
282
-            'desc'         => $order_description,
283
-            // Free-form field for your own use.  256 char max.
284
-            'custom'       => $primary_registrant ? $primary_registrant->ID() : '',
285
-            // Your own invoice or tracking number
286
-            'invnum'       => wp_generate_password(12, false),// $transaction->ID(),
287
-            // URL for receiving Instant Payment Notifications.  This overrides what your profile is set to use.
288
-            'notifyurl'    => '',
289
-            'buttonsource' => 'EventEspresso_SP',// EE will blow up if you change this
290
-        );
291
-        // Wrap all data arrays into a single, "master" array which will be passed into the class function.
292
-        $PayPalRequestData = array(
293
-            'DPFields'        => $DPFields,
294
-            'CCDetails'       => $CCDetails,
295
-            'PayerInfo'       => $PayerInfo,
296
-            'PayerName'       => $PayerName,
297
-            'BillingAddress'  => $BillingAddress,
298
-            'ShippingAddress' => $ShippingAddress,
299
-            'PaymentDetails'  => $PaymentDetails,
300
-            'OrderItems'      => $order_items,
301
-        );
302
-        $this->_log_clean_request($PayPalRequestData, $payment);
303
-        try {
304
-            $PayPalResult = $this->prep_and_curl_request($PayPalRequestData);
305
-            // remove PCI-sensitive data so it doesn't get stored
306
-            $PayPalResult = $this->_log_clean_response($PayPalResult, $payment);
307
-            $message = isset($PayPalResult['L_LONGMESSAGE0']) ? $PayPalResult['L_LONGMESSAGE0'] : $PayPalResult['ACK'];
308
-            if (empty($PayPalResult['RAWRESPONSE'])) {
309
-                $payment->set_status($this->_pay_model->failed_status());
310
-                $payment->set_gateway_response(__('No response received from Paypal Pro', 'event_espresso'));
311
-                $payment->set_details($PayPalResult);
312
-            } else {
313
-                if ($this->_APICallSuccessful($PayPalResult)) {
314
-                    $payment->set_status($this->_pay_model->approved_status());
315
-                } else {
316
-                    $payment->set_status($this->_pay_model->declined_status());
317
-                }
318
-                // make sure we interpret the AMT as a float, not an international string
319
-                // (where periods are thousand separators)
320
-                $payment->set_amount(isset($PayPalResult['AMT']) ? floatval($PayPalResult['AMT']) : 0);
321
-                $payment->set_gateway_response($message);
322
-                $payment->set_txn_id_chq_nmbr(isset($PayPalResult['TRANSACTIONID'])
323
-                    ? $PayPalResult['TRANSACTIONID']
324
-                    : null);
325
-                $primary_registration_code = $primary_registrant instanceof EE_Registration
326
-                    ? $primary_registrant->reg_code()
327
-                    : '';
328
-                $payment->set_extra_accntng($primary_registration_code);
329
-                $payment->set_details($PayPalResult);
330
-            }
331
-        } catch (Exception $e) {
332
-            $payment->set_status($this->_pay_model->failed_status());
333
-            $payment->set_gateway_response($e->getMessage());
334
-        }
335
-        // $payment->set_status( $this->_pay_model->declined_status() );
336
-        // $payment->set_gateway_response( '' );
337
-        return $payment;
338
-    }
339
-
340
-
341
-
342
-    /**
343
-     * CLeans out sensitive CC data and then logs it, and returns the cleaned request
344
-     *
345
-     * @param array       $request
346
-     * @param EEI_Payment $payment
347
-     * @return void
348
-     */
349
-    private function _log_clean_request($request, $payment)
350
-    {
351
-        $cleaned_request_data = $request;
352
-        unset($cleaned_request_data['CCDetails']['acct']);
353
-        unset($cleaned_request_data['CCDetails']['cvv2']);
354
-        unset($cleaned_request_data['CCDetails']['expdate']);
355
-        $this->log(array('Paypal Request' => $cleaned_request_data), $payment);
356
-    }
357
-
358
-
359
-
360
-    /**
361
-     * Cleans the response, logs it, and returns it
362
-     *
363
-     * @param array       $response
364
-     * @param EEI_Payment $payment
365
-     * @return array cleaned
366
-     */
367
-    private function _log_clean_response($response, $payment)
368
-    {
369
-        unset($response['REQUESTDATA']['CREDITCARDTYPE']);
370
-        unset($response['REQUESTDATA']['ACCT']);
371
-        unset($response['REQUESTDATA']['EXPDATE']);
372
-        unset($response['REQUESTDATA']['CVV2']);
373
-        unset($response['RAWREQUEST']);
374
-        $this->log(array('Paypal Response' => $response), $payment);
375
-        return $response;
376
-    }
377
-
378
-
379
-
380
-    /**
381
-     * @param $DataArray
382
-     * @return array
383
-     */
384
-    private function prep_and_curl_request($DataArray)
385
-    {
386
-        // Create empty holders for each portion of the NVP string
387
-        $DPFieldsNVP = '&METHOD=DoDirectPayment&BUTTONSOURCE=AngellEYE_PHP_Class_DDP';
388
-        $CCDetailsNVP = '';
389
-        $PayerInfoNVP = '';
390
-        $PayerNameNVP = '';
391
-        $BillingAddressNVP = '';
392
-        $ShippingAddressNVP = '';
393
-        $PaymentDetailsNVP = '';
394
-        $OrderItemsNVP = '';
395
-        $Secure3DNVP = '';
396
-        // DP Fields
397
-        $DPFields = isset($DataArray['DPFields']) ? $DataArray['DPFields'] : array();
398
-        foreach ($DPFields as $DPFieldsVar => $DPFieldsVal) {
399
-            $DPFieldsNVP .= '&' . strtoupper($DPFieldsVar) . '=' . urlencode($DPFieldsVal);
400
-        }
401
-        // CC Details Fields
402
-        $CCDetails = isset($DataArray['CCDetails']) ? $DataArray['CCDetails'] : array();
403
-        foreach ($CCDetails as $CCDetailsVar => $CCDetailsVal) {
404
-            $CCDetailsNVP .= '&' . strtoupper($CCDetailsVar) . '=' . urlencode($CCDetailsVal);
405
-        }
406
-        // PayerInfo Type Fields
407
-        $PayerInfo = isset($DataArray['PayerInfo']) ? $DataArray['PayerInfo'] : array();
408
-        foreach ($PayerInfo as $PayerInfoVar => $PayerInfoVal) {
409
-            $PayerInfoNVP .= '&' . strtoupper($PayerInfoVar) . '=' . urlencode($PayerInfoVal);
410
-        }
411
-        // Payer Name Fields
412
-        $PayerName = isset($DataArray['PayerName']) ? $DataArray['PayerName'] : array();
413
-        foreach ($PayerName as $PayerNameVar => $PayerNameVal) {
414
-            $PayerNameNVP .= '&' . strtoupper($PayerNameVar) . '=' . urlencode($PayerNameVal);
415
-        }
416
-        // Address Fields (Billing)
417
-        $BillingAddress = isset($DataArray['BillingAddress']) ? $DataArray['BillingAddress'] : array();
418
-        foreach ($BillingAddress as $BillingAddressVar => $BillingAddressVal) {
419
-            $BillingAddressNVP .= '&' . strtoupper($BillingAddressVar) . '=' . urlencode($BillingAddressVal);
420
-        }
421
-        // Payment Details Type Fields
422
-        $PaymentDetails = isset($DataArray['PaymentDetails']) ? $DataArray['PaymentDetails'] : array();
423
-        foreach ($PaymentDetails as $PaymentDetailsVar => $PaymentDetailsVal) {
424
-            $PaymentDetailsNVP .= '&' . strtoupper($PaymentDetailsVar) . '=' . urlencode($PaymentDetailsVal);
425
-        }
426
-        // Payment Details Item Type Fields
427
-        $OrderItems = isset($DataArray['OrderItems']) ? $DataArray['OrderItems'] : array();
428
-        $n = 0;
429
-        foreach ($OrderItems as $OrderItemsVar => $OrderItemsVal) {
430
-            $CurrentItem = $OrderItems[ $OrderItemsVar ];
431
-            foreach ($CurrentItem as $CurrentItemVar => $CurrentItemVal) {
432
-                $OrderItemsNVP .= '&' . strtoupper($CurrentItemVar) . $n . '=' . urlencode($CurrentItemVal);
433
-            }
434
-            $n++;
435
-        }
436
-        // Ship To Address Fields
437
-        $ShippingAddress = isset($DataArray['ShippingAddress']) ? $DataArray['ShippingAddress'] : array();
438
-        foreach ($ShippingAddress as $ShippingAddressVar => $ShippingAddressVal) {
439
-            $ShippingAddressNVP .= '&' . strtoupper($ShippingAddressVar) . '=' . urlencode($ShippingAddressVal);
440
-        }
441
-        // 3D Secure Fields
442
-        $Secure3D = isset($DataArray['Secure3D']) ? $DataArray['Secure3D'] : array();
443
-        foreach ($Secure3D as $Secure3DVar => $Secure3DVal) {
444
-            $Secure3DNVP .= '&' . strtoupper($Secure3DVar) . '=' . urlencode($Secure3DVal);
445
-        }
446
-        // Now that we have each chunk we need to go ahead and append them all together for our entire NVP string
447
-        $NVPRequest = 'USER='
448
-                      . $this->_username
449
-                      . '&PWD='
450
-                      . $this->_password
451
-                      . '&VERSION=64.0'
452
-                      . '&SIGNATURE='
453
-                      . $this->_signature
454
-                      . $DPFieldsNVP
455
-                      . $CCDetailsNVP
456
-                      . $PayerInfoNVP
457
-                      . $PayerNameNVP
458
-                      . $BillingAddressNVP
459
-                      . $PaymentDetailsNVP
460
-                      . $OrderItemsNVP
461
-                      . $ShippingAddressNVP
462
-                      . $Secure3DNVP;
463
-        $NVPResponse = $this->_CURLRequest($NVPRequest);
464
-        $NVPRequestArray = $this->_NVPToArray($NVPRequest);
465
-        $NVPResponseArray = $this->_NVPToArray($NVPResponse);
466
-        $Errors = $this->_GetErrors($NVPResponseArray);
467
-        $NVPResponseArray['ERRORS'] = $Errors;
468
-        $NVPResponseArray['REQUESTDATA'] = $NVPRequestArray;
469
-        $NVPResponseArray['RAWREQUEST'] = $NVPRequest;
470
-        $NVPResponseArray['RAWRESPONSE'] = $NVPResponse;
471
-        return $NVPResponseArray;
472
-    }
473
-
474
-
475
-
476
-    /**
477
-     * @param $Request
478
-     * @return mixed
479
-     */
480
-    private function _CURLRequest($Request)
481
-    {
482
-        $EndPointURL = $this->_debug_mode ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp';
483
-        $curl = curl_init();
484
-        curl_setopt($curl, CURLOPT_VERBOSE, apply_filters('FHEE__EEG_Paypal_Pro__CurlRequest__CURLOPT_VERBOSE', true));
485
-        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
486
-        curl_setopt($curl, CURLOPT_TIMEOUT, 60);
487
-        curl_setopt($curl, CURLOPT_URL, $EndPointURL);
488
-        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
489
-        curl_setopt($curl, CURLOPT_POSTFIELDS, $Request);
490
-        curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
491
-        // execute the curl POST
492
-        $Response = curl_exec($curl);
493
-        curl_close($curl);
494
-        return $Response;
495
-    }
496
-
497
-
498
-
499
-    /**
500
-     * @param $NVPString
501
-     * @return array
502
-     */
503
-    private function _NVPToArray($NVPString)
504
-    {
505
-        // prepare responses into array
506
-        $proArray = array();
507
-        while (strlen($NVPString)) {
508
-            // name
509
-            $keypos = strpos($NVPString, '=');
510
-            $keyval = substr($NVPString, 0, $keypos);
511
-            // value
512
-            $valuepos = strpos($NVPString, '&') ? strpos($NVPString, '&') : strlen($NVPString);
513
-            $valval = substr($NVPString, $keypos + 1, $valuepos - $keypos - 1);
514
-            // decoding the response
515
-            $proArray[ $keyval ] = urldecode($valval);
516
-            $NVPString = substr($NVPString, $valuepos + 1, strlen($NVPString));
517
-        }
518
-        return $proArray;
519
-    }
520
-
521
-
522
-
523
-    /**
524
-     * @param array $PayPalResult
525
-     * @return bool
526
-     */
527
-    private function _APICallSuccessful($PayPalResult)
528
-    {
529
-        $approved = false;
530
-        // check main response message from PayPal
531
-        if (isset($PayPalResult['ACK']) && ! empty($PayPalResult['ACK'])) {
532
-            $ack = strtoupper($PayPalResult['ACK']);
533
-            $approved = ($ack == 'SUCCESS' || $ack == 'SUCCESSWITHWARNING' || $ack == 'PARTIALSUCCESS') ? true : false;
534
-        }
535
-        return $approved;
536
-    }
537
-
538
-
539
-
540
-    /**
541
-     * @param $DataArray
542
-     * @return array
543
-     */
544
-    private function _GetErrors($DataArray)
545
-    {
546
-        $Errors = array();
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 . '' ]
552
-                : '';
553
-            $LLongMessage = isset($DataArray[ 'L_LONGMESSAGE' . $n . '' ])
554
-                ? $DataArray[ 'L_LONGMESSAGE' . $n . '' ]
555
-                : '';
556
-            $LSeverityCode = isset($DataArray[ 'L_SEVERITYCODE' . $n . '' ])
557
-                ? $DataArray[ 'L_SEVERITYCODE' . $n . '' ]
558
-                : '';
559
-            $CurrentItem = array(
560
-                'L_ERRORCODE'    => $LErrorCode,
561
-                'L_SHORTMESSAGE' => $LShortMessage,
562
-                'L_LONGMESSAGE'  => $LLongMessage,
563
-                'L_SEVERITYCODE' => $LSeverityCode,
564
-            );
565
-            array_push($Errors, $CurrentItem);
566
-            $n++;
567
-        }
568
-        return $Errors;
569
-    }
570
-
571
-
572
-
573
-    /**
574
-     *        nothing to see here...  move along....
575
-     *
576
-     * @access protected
577
-     * @param $Errors
578
-     * @return string
579
-     */
580
-    private function _DisplayErrors($Errors)
581
-    {
582
-        $error = '';
583
-        foreach ($Errors as $ErrorVar => $ErrorVal) {
584
-            $CurrentError = $Errors[ $ErrorVar ];
585
-            foreach ($CurrentError as $CurrentErrorVar => $CurrentErrorVal) {
586
-                $CurrentVarName = '';
587
-                if ($CurrentErrorVar == 'L_ERRORCODE') {
588
-                    $CurrentVarName = 'Error Code';
589
-                } elseif ($CurrentErrorVar == 'L_SHORTMESSAGE') {
590
-                    $CurrentVarName = 'Short Message';
591
-                } elseif ($CurrentErrorVar == 'L_LONGMESSAGE') {
592
-                    $CurrentVarName = 'Long Message';
593
-                } elseif ($CurrentErrorVar == 'L_SEVERITYCODE') {
594
-                    $CurrentVarName = 'Severity Code';
595
-                }
596
-                $error .= '<br />' . $CurrentVarName . ': ' . $CurrentErrorVal;
597
-            }
598
-        }
599
-        return $error;
600
-    }
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
+	);
61
+
62
+
63
+
64
+	/**
65
+	 * @param EEI_Payment $payment
66
+	 * @param array       $billing_info {
67
+	 * @type string $credit_card
68
+	 * @type string $credit_card_type
69
+	 * @type string $exp_month always 2 characters
70
+	 * @type string $exp_year always 4 characters
71
+	 * @type string $cvv
72
+	 * }
73
+	 * @see      parent::do_direct_payment for more info
74
+	 * @return EE_Payment|EEI_Payment
75
+	 * @throws EE_Error
76
+	 */
77
+	public function do_direct_payment($payment, $billing_info = null)
78
+	{
79
+		$transaction = $payment->transaction();
80
+		if (! $transaction instanceof EEI_Transaction) {
81
+			throw new EE_Error(
82
+				esc_html__('No transaction for payment while paying with PayPal Pro.', 'event_espresso')
83
+			);
84
+		}
85
+		$primary_registrant = $transaction->primary_registration();
86
+		if (! $primary_registrant instanceof EEI_Registration) {
87
+			throw new EE_Error(
88
+				esc_html__(
89
+					'No primary registration on transaction while paying with PayPal Pro.',
90
+					'event_espresso'
91
+				)
92
+			);
93
+		}
94
+		$attendee = $primary_registrant->attendee();
95
+		if (! $attendee instanceof EEI_Attendee) {
96
+			throw new EE_Error(
97
+				esc_html__(
98
+					'No attendee on primary registration while paying with PayPal Pro.',
99
+					'event_espresso'
100
+				)
101
+			);
102
+		}
103
+		$gateway_formatter = $this->_get_gateway_formatter();
104
+		$order_description = substr($gateway_formatter->formatOrderDescription($payment), 0, 127);
105
+		// charge for the full amount. Show itemized list
106
+		if ($this->_can_easily_itemize_transaction_for($payment)) {
107
+			$item_num = 1;
108
+			$total_line_item = $transaction->total_line_item();
109
+			$order_items = array();
110
+			foreach ($total_line_item->get_items() as $line_item) {
111
+				// ignore line items with a quantity of 0
112
+				if ($line_item->quantity() == 0) {
113
+					continue;
114
+				}
115
+				$item = array(
116
+					// Item Name.  127 char max.
117
+					'l_name'                 => substr(
118
+						$gateway_formatter->formatLineItemName($line_item, $payment),
119
+						0,
120
+						127
121
+					),
122
+					// Item description.  127 char max.
123
+					'l_desc'                 => substr(
124
+						$gateway_formatter->formatLineItemDesc($line_item, $payment),
125
+						0,
126
+						127
127
+					),
128
+					// Cost of individual item.
129
+					'l_amt'                  => $line_item->unit_price(),
130
+					// Item Number.  127 char max.
131
+					'l_number'               => $item_num++,
132
+					// Item quantity.  Must be any positive integer.
133
+					'l_qty'                  => $line_item->quantity(),
134
+					// Item's sales tax amount.
135
+					'l_taxamt'               => '',
136
+					// eBay auction number of item.
137
+					'l_ebayitemnumber'       => '',
138
+					// eBay transaction ID of purchased item.
139
+					'l_ebayitemauctiontxnid' => '',
140
+					// eBay order ID for the item.
141
+					'l_ebayitemorderid'      => '',
142
+				);
143
+				// add to array of all items
144
+				array_push($order_items, $item);
145
+			}
146
+			$item_amount = $total_line_item->get_items_total();
147
+			$tax_amount = $total_line_item->get_total_tax();
148
+		} else {
149
+			$order_items = array();
150
+			$item_amount = $payment->amount();
151
+			$tax_amount = 0;
152
+			array_push($order_items, array(
153
+				// Item Name.  127 char max.
154
+				'l_name'   => substr(
155
+					$gateway_formatter->formatPartialPaymentLineItemName($payment),
156
+					0,
157
+					127
158
+				),
159
+				// Item description.  127 char max.
160
+				'l_desc'   => substr(
161
+					$gateway_formatter->formatPartialPaymentLineItemDesc($payment),
162
+					0,
163
+					127
164
+				),
165
+				// Cost of individual item.
166
+				'l_amt'    => $payment->amount(),
167
+				// Item Number.  127 char max.
168
+				'l_number' => 1,
169
+				// Item quantity.  Must be any positive integer.
170
+				'l_qty'    => 1,
171
+			));
172
+		}
173
+		// Populate data arrays with order data.
174
+		$DPFields = array(
175
+			// How you want to obtain payment ?
176
+			// Authorization indicates the payment is a basic auth subject to settlement with Auth & Capture.
177
+			// Sale indicates that this is a final sale for which you are requesting payment.  Default is Sale.
178
+			'paymentaction'    => 'Sale',
179
+			// Required.  IP address of the payer's browser.
180
+			'ipaddress'        => $_SERVER['REMOTE_ADDR'],
181
+			// Flag to determine whether you want the results returned by FMF.  1 or 0.  Default is 0.
182
+			'returnfmfdetails' => '1',
183
+		);
184
+		$CCDetails = array(
185
+			// Required. Type of credit card.  Visa, MasterCard, Discover, Amex, Maestro, Solo.
186
+			// If Maestro or Solo, the currency code must be GBP.
187
+			//  In addition, either start date or issue number must be specified.
188
+			'creditcardtype' => $billing_info['credit_card_type'],
189
+			// Required.  Credit card number.  No spaces or punctuation.
190
+			'acct'           => $billing_info['credit_card'],
191
+			// Required.  Credit card expiration date.  Format is MMYYYY
192
+			'expdate'        => $billing_info['exp_month'] . $billing_info['exp_year'],
193
+			// Requirements determined by your PayPal account settings.  Security digits for credit card.
194
+			'cvv2'           => $billing_info['cvv'],
195
+		);
196
+		$PayerInfo = array(
197
+			// Email address of payer.
198
+			'email'       => $billing_info['email'],
199
+			// Unique PayPal customer ID for payer.
200
+			'payerid'     => '',
201
+			// Status of payer.  Values are verified or unverified
202
+			'payerstatus' => '',
203
+			// Payer's business name.
204
+			'business'    => '',
205
+		);
206
+		$PayerName = array(
207
+			// Payer's salutation.  20 char max.
208
+			'salutation' => '',
209
+			// Payer's first name.  25 char max.
210
+			'firstname'  => substr($billing_info['first_name'], 0, 25),
211
+			// Payer's middle name.  25 char max.
212
+			'middlename' => '',
213
+			// Payer's last name.  25 char max.
214
+			'lastname'   => substr($billing_info['last_name'], 0, 25),
215
+			// Payer's suffix.  12 char max.
216
+			'suffix'     => '',
217
+		);
218
+		$BillingAddress = array(
219
+			// Required.  First street address.
220
+			'street'      => $billing_info['address'],
221
+			// Second street address.
222
+			'street2'     => $billing_info['address2'],
223
+			// Required.  Name of City.
224
+			'city'        => $billing_info['city'],
225
+			// Required. Name of State or Province.
226
+			'state'       => substr($billing_info['state'], 0, 40),
227
+			// Required.  Country code.
228
+			'countrycode' => $billing_info['country'],
229
+			// Required.  Postal code of payer.
230
+			'zip'         => $billing_info['zip'],
231
+		);
232
+		// check if the registration info contains the needed fields for paypal pro
233
+		// (see https://developer.paypal.com/docs/classic/api/merchant/DoDirectPayment_API_Operation_NVP/)
234
+		if ($attendee->address() && $attendee->city() && $attendee->country_ID()) {
235
+			$use_registration_address_info = true;
236
+		} else {
237
+			$use_registration_address_info = false;
238
+		}
239
+		// so if the attendee has enough data to fill out PayPal Pro's shipping info, use it.
240
+		// If not, use the billing info again
241
+		$ShippingAddress = array(
242
+			'shiptoname'     => substr($use_registration_address_info
243
+				? $attendee->full_name()
244
+				: $billing_info['first_name'] . ' ' . $billing_info['last_name'], 0, 32),
245
+			'shiptostreet'   => substr($use_registration_address_info
246
+				? $attendee->address()
247
+				: $billing_info['address'], 0, 100),
248
+			'shiptostreet2'  => substr($use_registration_address_info
249
+				? $attendee->address2() : $billing_info['address2'], 0, 100),
250
+			'shiptocity'     => substr($use_registration_address_info
251
+				? $attendee->city()
252
+				: $billing_info['city'], 0, 40),
253
+			'state'          => substr($use_registration_address_info
254
+				? $attendee->state_name()
255
+				: $billing_info['state'], 0, 40),
256
+			'shiptocountry'  => $use_registration_address_info
257
+				? $attendee->country_ID()
258
+				: $billing_info['country'],
259
+			'shiptozip'      => substr($use_registration_address_info
260
+				? $attendee->zip()
261
+				: $billing_info['zip'], 0, 20),
262
+			'shiptophonenum' => substr($use_registration_address_info
263
+				? $attendee->phone()
264
+				: $billing_info['phone'], 0, 20),
265
+		);
266
+		$PaymentDetails = array(
267
+			// Required.  Total amount of order, including shipping, handling, and tax.
268
+			'amt'          => $gateway_formatter->formatCurrency($payment->amount()),
269
+			// Required.  Three-letter currency code.  Default is USD.
270
+			'currencycode' => $payment->currency_code(),
271
+			// Required if you include itemized cart details. (L_AMTn, etc.)
272
+			// Subtotal of items not including S&H, or tax.
273
+			'itemamt'      => $gateway_formatter->formatCurrency($item_amount),//
274
+			// Total shipping costs for the order.  If you specify shippingamt, you must also specify itemamt.
275
+			'shippingamt'  => '',
276
+			// Total handling costs for the order.  If you specify handlingamt, you must also specify itemamt.
277
+			'handlingamt'  => '',
278
+			// Required if you specify itemized cart tax details.
279
+			// Sum of tax for all items on the order.  Total sales tax.
280
+			'taxamt'       => $gateway_formatter->formatCurrency($tax_amount),
281
+			// Description of the order the customer is purchasing.  127 char max.
282
+			'desc'         => $order_description,
283
+			// Free-form field for your own use.  256 char max.
284
+			'custom'       => $primary_registrant ? $primary_registrant->ID() : '',
285
+			// Your own invoice or tracking number
286
+			'invnum'       => wp_generate_password(12, false),// $transaction->ID(),
287
+			// URL for receiving Instant Payment Notifications.  This overrides what your profile is set to use.
288
+			'notifyurl'    => '',
289
+			'buttonsource' => 'EventEspresso_SP',// EE will blow up if you change this
290
+		);
291
+		// Wrap all data arrays into a single, "master" array which will be passed into the class function.
292
+		$PayPalRequestData = array(
293
+			'DPFields'        => $DPFields,
294
+			'CCDetails'       => $CCDetails,
295
+			'PayerInfo'       => $PayerInfo,
296
+			'PayerName'       => $PayerName,
297
+			'BillingAddress'  => $BillingAddress,
298
+			'ShippingAddress' => $ShippingAddress,
299
+			'PaymentDetails'  => $PaymentDetails,
300
+			'OrderItems'      => $order_items,
301
+		);
302
+		$this->_log_clean_request($PayPalRequestData, $payment);
303
+		try {
304
+			$PayPalResult = $this->prep_and_curl_request($PayPalRequestData);
305
+			// remove PCI-sensitive data so it doesn't get stored
306
+			$PayPalResult = $this->_log_clean_response($PayPalResult, $payment);
307
+			$message = isset($PayPalResult['L_LONGMESSAGE0']) ? $PayPalResult['L_LONGMESSAGE0'] : $PayPalResult['ACK'];
308
+			if (empty($PayPalResult['RAWRESPONSE'])) {
309
+				$payment->set_status($this->_pay_model->failed_status());
310
+				$payment->set_gateway_response(__('No response received from Paypal Pro', 'event_espresso'));
311
+				$payment->set_details($PayPalResult);
312
+			} else {
313
+				if ($this->_APICallSuccessful($PayPalResult)) {
314
+					$payment->set_status($this->_pay_model->approved_status());
315
+				} else {
316
+					$payment->set_status($this->_pay_model->declined_status());
317
+				}
318
+				// make sure we interpret the AMT as a float, not an international string
319
+				// (where periods are thousand separators)
320
+				$payment->set_amount(isset($PayPalResult['AMT']) ? floatval($PayPalResult['AMT']) : 0);
321
+				$payment->set_gateway_response($message);
322
+				$payment->set_txn_id_chq_nmbr(isset($PayPalResult['TRANSACTIONID'])
323
+					? $PayPalResult['TRANSACTIONID']
324
+					: null);
325
+				$primary_registration_code = $primary_registrant instanceof EE_Registration
326
+					? $primary_registrant->reg_code()
327
+					: '';
328
+				$payment->set_extra_accntng($primary_registration_code);
329
+				$payment->set_details($PayPalResult);
330
+			}
331
+		} catch (Exception $e) {
332
+			$payment->set_status($this->_pay_model->failed_status());
333
+			$payment->set_gateway_response($e->getMessage());
334
+		}
335
+		// $payment->set_status( $this->_pay_model->declined_status() );
336
+		// $payment->set_gateway_response( '' );
337
+		return $payment;
338
+	}
339
+
340
+
341
+
342
+	/**
343
+	 * CLeans out sensitive CC data and then logs it, and returns the cleaned request
344
+	 *
345
+	 * @param array       $request
346
+	 * @param EEI_Payment $payment
347
+	 * @return void
348
+	 */
349
+	private function _log_clean_request($request, $payment)
350
+	{
351
+		$cleaned_request_data = $request;
352
+		unset($cleaned_request_data['CCDetails']['acct']);
353
+		unset($cleaned_request_data['CCDetails']['cvv2']);
354
+		unset($cleaned_request_data['CCDetails']['expdate']);
355
+		$this->log(array('Paypal Request' => $cleaned_request_data), $payment);
356
+	}
357
+
358
+
359
+
360
+	/**
361
+	 * Cleans the response, logs it, and returns it
362
+	 *
363
+	 * @param array       $response
364
+	 * @param EEI_Payment $payment
365
+	 * @return array cleaned
366
+	 */
367
+	private function _log_clean_response($response, $payment)
368
+	{
369
+		unset($response['REQUESTDATA']['CREDITCARDTYPE']);
370
+		unset($response['REQUESTDATA']['ACCT']);
371
+		unset($response['REQUESTDATA']['EXPDATE']);
372
+		unset($response['REQUESTDATA']['CVV2']);
373
+		unset($response['RAWREQUEST']);
374
+		$this->log(array('Paypal Response' => $response), $payment);
375
+		return $response;
376
+	}
377
+
378
+
379
+
380
+	/**
381
+	 * @param $DataArray
382
+	 * @return array
383
+	 */
384
+	private function prep_and_curl_request($DataArray)
385
+	{
386
+		// Create empty holders for each portion of the NVP string
387
+		$DPFieldsNVP = '&METHOD=DoDirectPayment&BUTTONSOURCE=AngellEYE_PHP_Class_DDP';
388
+		$CCDetailsNVP = '';
389
+		$PayerInfoNVP = '';
390
+		$PayerNameNVP = '';
391
+		$BillingAddressNVP = '';
392
+		$ShippingAddressNVP = '';
393
+		$PaymentDetailsNVP = '';
394
+		$OrderItemsNVP = '';
395
+		$Secure3DNVP = '';
396
+		// DP Fields
397
+		$DPFields = isset($DataArray['DPFields']) ? $DataArray['DPFields'] : array();
398
+		foreach ($DPFields as $DPFieldsVar => $DPFieldsVal) {
399
+			$DPFieldsNVP .= '&' . strtoupper($DPFieldsVar) . '=' . urlencode($DPFieldsVal);
400
+		}
401
+		// CC Details Fields
402
+		$CCDetails = isset($DataArray['CCDetails']) ? $DataArray['CCDetails'] : array();
403
+		foreach ($CCDetails as $CCDetailsVar => $CCDetailsVal) {
404
+			$CCDetailsNVP .= '&' . strtoupper($CCDetailsVar) . '=' . urlencode($CCDetailsVal);
405
+		}
406
+		// PayerInfo Type Fields
407
+		$PayerInfo = isset($DataArray['PayerInfo']) ? $DataArray['PayerInfo'] : array();
408
+		foreach ($PayerInfo as $PayerInfoVar => $PayerInfoVal) {
409
+			$PayerInfoNVP .= '&' . strtoupper($PayerInfoVar) . '=' . urlencode($PayerInfoVal);
410
+		}
411
+		// Payer Name Fields
412
+		$PayerName = isset($DataArray['PayerName']) ? $DataArray['PayerName'] : array();
413
+		foreach ($PayerName as $PayerNameVar => $PayerNameVal) {
414
+			$PayerNameNVP .= '&' . strtoupper($PayerNameVar) . '=' . urlencode($PayerNameVal);
415
+		}
416
+		// Address Fields (Billing)
417
+		$BillingAddress = isset($DataArray['BillingAddress']) ? $DataArray['BillingAddress'] : array();
418
+		foreach ($BillingAddress as $BillingAddressVar => $BillingAddressVal) {
419
+			$BillingAddressNVP .= '&' . strtoupper($BillingAddressVar) . '=' . urlencode($BillingAddressVal);
420
+		}
421
+		// Payment Details Type Fields
422
+		$PaymentDetails = isset($DataArray['PaymentDetails']) ? $DataArray['PaymentDetails'] : array();
423
+		foreach ($PaymentDetails as $PaymentDetailsVar => $PaymentDetailsVal) {
424
+			$PaymentDetailsNVP .= '&' . strtoupper($PaymentDetailsVar) . '=' . urlencode($PaymentDetailsVal);
425
+		}
426
+		// Payment Details Item Type Fields
427
+		$OrderItems = isset($DataArray['OrderItems']) ? $DataArray['OrderItems'] : array();
428
+		$n = 0;
429
+		foreach ($OrderItems as $OrderItemsVar => $OrderItemsVal) {
430
+			$CurrentItem = $OrderItems[ $OrderItemsVar ];
431
+			foreach ($CurrentItem as $CurrentItemVar => $CurrentItemVal) {
432
+				$OrderItemsNVP .= '&' . strtoupper($CurrentItemVar) . $n . '=' . urlencode($CurrentItemVal);
433
+			}
434
+			$n++;
435
+		}
436
+		// Ship To Address Fields
437
+		$ShippingAddress = isset($DataArray['ShippingAddress']) ? $DataArray['ShippingAddress'] : array();
438
+		foreach ($ShippingAddress as $ShippingAddressVar => $ShippingAddressVal) {
439
+			$ShippingAddressNVP .= '&' . strtoupper($ShippingAddressVar) . '=' . urlencode($ShippingAddressVal);
440
+		}
441
+		// 3D Secure Fields
442
+		$Secure3D = isset($DataArray['Secure3D']) ? $DataArray['Secure3D'] : array();
443
+		foreach ($Secure3D as $Secure3DVar => $Secure3DVal) {
444
+			$Secure3DNVP .= '&' . strtoupper($Secure3DVar) . '=' . urlencode($Secure3DVal);
445
+		}
446
+		// Now that we have each chunk we need to go ahead and append them all together for our entire NVP string
447
+		$NVPRequest = 'USER='
448
+					  . $this->_username
449
+					  . '&PWD='
450
+					  . $this->_password
451
+					  . '&VERSION=64.0'
452
+					  . '&SIGNATURE='
453
+					  . $this->_signature
454
+					  . $DPFieldsNVP
455
+					  . $CCDetailsNVP
456
+					  . $PayerInfoNVP
457
+					  . $PayerNameNVP
458
+					  . $BillingAddressNVP
459
+					  . $PaymentDetailsNVP
460
+					  . $OrderItemsNVP
461
+					  . $ShippingAddressNVP
462
+					  . $Secure3DNVP;
463
+		$NVPResponse = $this->_CURLRequest($NVPRequest);
464
+		$NVPRequestArray = $this->_NVPToArray($NVPRequest);
465
+		$NVPResponseArray = $this->_NVPToArray($NVPResponse);
466
+		$Errors = $this->_GetErrors($NVPResponseArray);
467
+		$NVPResponseArray['ERRORS'] = $Errors;
468
+		$NVPResponseArray['REQUESTDATA'] = $NVPRequestArray;
469
+		$NVPResponseArray['RAWREQUEST'] = $NVPRequest;
470
+		$NVPResponseArray['RAWRESPONSE'] = $NVPResponse;
471
+		return $NVPResponseArray;
472
+	}
473
+
474
+
475
+
476
+	/**
477
+	 * @param $Request
478
+	 * @return mixed
479
+	 */
480
+	private function _CURLRequest($Request)
481
+	{
482
+		$EndPointURL = $this->_debug_mode ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp';
483
+		$curl = curl_init();
484
+		curl_setopt($curl, CURLOPT_VERBOSE, apply_filters('FHEE__EEG_Paypal_Pro__CurlRequest__CURLOPT_VERBOSE', true));
485
+		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
486
+		curl_setopt($curl, CURLOPT_TIMEOUT, 60);
487
+		curl_setopt($curl, CURLOPT_URL, $EndPointURL);
488
+		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
489
+		curl_setopt($curl, CURLOPT_POSTFIELDS, $Request);
490
+		curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
491
+		// execute the curl POST
492
+		$Response = curl_exec($curl);
493
+		curl_close($curl);
494
+		return $Response;
495
+	}
496
+
497
+
498
+
499
+	/**
500
+	 * @param $NVPString
501
+	 * @return array
502
+	 */
503
+	private function _NVPToArray($NVPString)
504
+	{
505
+		// prepare responses into array
506
+		$proArray = array();
507
+		while (strlen($NVPString)) {
508
+			// name
509
+			$keypos = strpos($NVPString, '=');
510
+			$keyval = substr($NVPString, 0, $keypos);
511
+			// value
512
+			$valuepos = strpos($NVPString, '&') ? strpos($NVPString, '&') : strlen($NVPString);
513
+			$valval = substr($NVPString, $keypos + 1, $valuepos - $keypos - 1);
514
+			// decoding the response
515
+			$proArray[ $keyval ] = urldecode($valval);
516
+			$NVPString = substr($NVPString, $valuepos + 1, strlen($NVPString));
517
+		}
518
+		return $proArray;
519
+	}
520
+
521
+
522
+
523
+	/**
524
+	 * @param array $PayPalResult
525
+	 * @return bool
526
+	 */
527
+	private function _APICallSuccessful($PayPalResult)
528
+	{
529
+		$approved = false;
530
+		// check main response message from PayPal
531
+		if (isset($PayPalResult['ACK']) && ! empty($PayPalResult['ACK'])) {
532
+			$ack = strtoupper($PayPalResult['ACK']);
533
+			$approved = ($ack == 'SUCCESS' || $ack == 'SUCCESSWITHWARNING' || $ack == 'PARTIALSUCCESS') ? true : false;
534
+		}
535
+		return $approved;
536
+	}
537
+
538
+
539
+
540
+	/**
541
+	 * @param $DataArray
542
+	 * @return array
543
+	 */
544
+	private function _GetErrors($DataArray)
545
+	{
546
+		$Errors = array();
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 . '' ]
552
+				: '';
553
+			$LLongMessage = isset($DataArray[ 'L_LONGMESSAGE' . $n . '' ])
554
+				? $DataArray[ 'L_LONGMESSAGE' . $n . '' ]
555
+				: '';
556
+			$LSeverityCode = isset($DataArray[ 'L_SEVERITYCODE' . $n . '' ])
557
+				? $DataArray[ 'L_SEVERITYCODE' . $n . '' ]
558
+				: '';
559
+			$CurrentItem = array(
560
+				'L_ERRORCODE'    => $LErrorCode,
561
+				'L_SHORTMESSAGE' => $LShortMessage,
562
+				'L_LONGMESSAGE'  => $LLongMessage,
563
+				'L_SEVERITYCODE' => $LSeverityCode,
564
+			);
565
+			array_push($Errors, $CurrentItem);
566
+			$n++;
567
+		}
568
+		return $Errors;
569
+	}
570
+
571
+
572
+
573
+	/**
574
+	 *        nothing to see here...  move along....
575
+	 *
576
+	 * @access protected
577
+	 * @param $Errors
578
+	 * @return string
579
+	 */
580
+	private function _DisplayErrors($Errors)
581
+	{
582
+		$error = '';
583
+		foreach ($Errors as $ErrorVar => $ErrorVal) {
584
+			$CurrentError = $Errors[ $ErrorVar ];
585
+			foreach ($CurrentError as $CurrentErrorVar => $CurrentErrorVal) {
586
+				$CurrentVarName = '';
587
+				if ($CurrentErrorVar == 'L_ERRORCODE') {
588
+					$CurrentVarName = 'Error Code';
589
+				} elseif ($CurrentErrorVar == 'L_SHORTMESSAGE') {
590
+					$CurrentVarName = 'Short Message';
591
+				} elseif ($CurrentErrorVar == 'L_LONGMESSAGE') {
592
+					$CurrentVarName = 'Long Message';
593
+				} elseif ($CurrentErrorVar == 'L_SEVERITYCODE') {
594
+					$CurrentVarName = 'Severity Code';
595
+				}
596
+				$error .= '<br />' . $CurrentVarName . ': ' . $CurrentErrorVal;
597
+			}
598
+		}
599
+		return $error;
600
+	}
601 601
 }
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.