Completed
Pull Request — master (#331)
by Darren
15:56
created
core/services/editor/EditorBlockManager.php 1 patch
Indentation   +90 added lines, -90 removed lines patch added patch discarded remove patch
@@ -24,96 +24,96 @@
 block discarded – undo
24 24
 abstract class EditorBlockManager
25 25
 {
26 26
 
27
-    /**
28
-     * @var CollectionInterface|EditorBlockInterface[] $blocks
29
-     */
30
-    protected $blocks;
31
-
32
-    /**
33
-     * @var RequestInterface $request
34
-     */
35
-    protected $request;
36
-
37
-    /**
38
-     * @var DomainInterface $domain
39
-     */
40
-    protected $domain;
41
-
42
-    /**
43
-     * the post type that the current request applies to
44
-     *
45
-     * @var string $request_post_type
46
-     */
47
-    protected $request_post_type;
48
-
49
-    /**
50
-     * value of the 'page' $_GET param
51
-     *
52
-     * @var string $page
53
-     */
54
-    protected $page;
55
-
56
-    /**
57
-     * value of the 'action' $_GET param
58
-     *
59
-     * @var string $action
60
-     */
61
-    protected $action;
62
-
63
-
64
-    /**
65
-     * @var Registry
66
-     */
67
-    protected $assets_registry;
68
-
69
-    /**
70
-     * EditorBlockManager constructor.
71
-     *
72
-     * @param EditorBlockCollection $blocks
73
-     * @param RequestInterface      $request
74
-     * @param DomainInterface       $domain
75
-     * @param Registry              $assets_registry
76
-     */
77
-    public function __construct(
78
-        EditorBlockCollection $blocks,
79
-        RequestInterface $request,
80
-        DomainInterface $domain,
81
-        Registry $assets_registry
82
-    ) {
83
-        $this->blocks  = $blocks;
84
-        $this->request = $request;
85
-        $this->domain  = $domain;
86
-        $this->assets_registry = $assets_registry;
87
-        $this->request_post_type = $this->request->getRequestParam('post_type', '');
88
-        $this->page = $this->request->getRequestParam('page', '');
89
-        $this->action = $this->request->getRequestParam('action', '');
90
-        add_action($this->init_hook(), array($this, 'initialize'));
91
-    }
92
-
93
-
94
-    /**
95
-     *  Returns the name of a hookpoint to be used to call initialize()
96
-     *
97
-     * @return string
98
-     */
99
-    abstract public function init_hook();
100
-
101
-
102
-    /**
103
-     * Perform any early setup required for block editors to functions
104
-     *
105
-     * @return void
106
-     */
107
-    abstract public function initialize();
108
-
109
-
110
-    /**
111
-     * @return string
112
-     */
113
-    public function currentRequestPostType()
114
-    {
115
-        return $this->request_post_type;
116
-    }
27
+	/**
28
+	 * @var CollectionInterface|EditorBlockInterface[] $blocks
29
+	 */
30
+	protected $blocks;
31
+
32
+	/**
33
+	 * @var RequestInterface $request
34
+	 */
35
+	protected $request;
36
+
37
+	/**
38
+	 * @var DomainInterface $domain
39
+	 */
40
+	protected $domain;
41
+
42
+	/**
43
+	 * the post type that the current request applies to
44
+	 *
45
+	 * @var string $request_post_type
46
+	 */
47
+	protected $request_post_type;
48
+
49
+	/**
50
+	 * value of the 'page' $_GET param
51
+	 *
52
+	 * @var string $page
53
+	 */
54
+	protected $page;
55
+
56
+	/**
57
+	 * value of the 'action' $_GET param
58
+	 *
59
+	 * @var string $action
60
+	 */
61
+	protected $action;
62
+
63
+
64
+	/**
65
+	 * @var Registry
66
+	 */
67
+	protected $assets_registry;
68
+
69
+	/**
70
+	 * EditorBlockManager constructor.
71
+	 *
72
+	 * @param EditorBlockCollection $blocks
73
+	 * @param RequestInterface      $request
74
+	 * @param DomainInterface       $domain
75
+	 * @param Registry              $assets_registry
76
+	 */
77
+	public function __construct(
78
+		EditorBlockCollection $blocks,
79
+		RequestInterface $request,
80
+		DomainInterface $domain,
81
+		Registry $assets_registry
82
+	) {
83
+		$this->blocks  = $blocks;
84
+		$this->request = $request;
85
+		$this->domain  = $domain;
86
+		$this->assets_registry = $assets_registry;
87
+		$this->request_post_type = $this->request->getRequestParam('post_type', '');
88
+		$this->page = $this->request->getRequestParam('page', '');
89
+		$this->action = $this->request->getRequestParam('action', '');
90
+		add_action($this->init_hook(), array($this, 'initialize'));
91
+	}
92
+
93
+
94
+	/**
95
+	 *  Returns the name of a hookpoint to be used to call initialize()
96
+	 *
97
+	 * @return string
98
+	 */
99
+	abstract public function init_hook();
100
+
101
+
102
+	/**
103
+	 * Perform any early setup required for block editors to functions
104
+	 *
105
+	 * @return void
106
+	 */
107
+	abstract public function initialize();
108
+
109
+
110
+	/**
111
+	 * @return string
112
+	 */
113
+	public function currentRequestPostType()
114
+	{
115
+		return $this->request_post_type;
116
+	}
117 117
 
118 118
 
119 119
 }
Please login to merge, or discard this patch.
core/services/editor/EditorBlockRegistrationManager.php 2 patches
Indentation   +149 added lines, -149 removed lines patch added patch discarded remove patch
@@ -38,154 +38,154 @@
 block discarded – undo
38 38
 class EditorBlockRegistrationManager extends EditorBlockManager
39 39
 {
40 40
 
41
-    /**
42
-     *  Returns the name of a hookpoint to be used to call initialize()
43
-     *
44
-     * @return string
45
-     */
46
-    public function init_hook()
47
-    {
48
-        return 'AHEE__EE_System__set_hooks_for_core';
49
-    }
50
-
51
-
52
-    /**
53
-     * Perform any early setup required for block editors to functions
54
-     *
55
-     * @return void
56
-     * @throws Exception
57
-     */
58
-    public function initialize()
59
-    {
60
-        $this->loadEditorBlocks();
61
-        add_action('AHEE__EE_System__initialize', array($this, 'registerEditorBlocks'));
62
-    }
63
-
64
-
65
-    /**
66
-     * @return CollectionInterface|EditorBlockInterface[]
67
-     * @throws ReflectionException
68
-     * @throws InvalidArgumentException
69
-     * @throws EE_Error
70
-     * @throws InvalidClassException
71
-     * @throws InvalidDataTypeException
72
-     * @throws InvalidEntityException
73
-     * @throws InvalidFilePathException
74
-     * @throws InvalidIdentifierException
75
-     * @throws InvalidInterfaceException
76
-     */
77
-    protected function populateEditorBlockCollection()
78
-    {
79
-        $loader = new CollectionLoader(
80
-            new CollectionDetails(
81
-            // collection name
82
-                'shortcodes',
83
-                // collection interface
84
-                'EventEspresso\core\domain\entities\editor\EditorBlockInterface',
85
-                // FQCNs for classes to add (all classes within each namespace will be loaded)
86
-                apply_filters(
87
-                    'FHEE__EventEspresso_core_services_editor_EditorBlockManager__populateEditorBlockCollection__collection_FQCNs',
88
-                    array()
89
-                    // array(
90
-                    //     'EventEspresso\core\domain\entities\editor\blocks\common',
91
-                    //     'EventEspresso\core\domain\entities\editor\blocks\editor',
92
-                    //     'EventEspresso\core\domain\entities\editor\blocks\shortcodes',
93
-                    //     'EventEspresso\core\domain\entities\editor\blocks\widgets',
94
-                    // )
95
-                ),
96
-                // filepaths to classes to add
97
-                array(),
98
-                // file mask to use if parsing folder for files to add
99
-                '',
100
-                // what to use as identifier for collection entities
101
-                // using CLASS NAME prevents duplicates (works like a singleton)
102
-                CollectionDetails::ID_CLASS_NAME
103
-            ),
104
-            $this->blocks
105
-        );
106
-        return $loader->getCollection();
107
-    }
108
-
109
-
110
-    /**
111
-     * populates the EditorBlockCollection and calls initialize() on all installed blocks
112
-     *
113
-     * @return void
114
-     * @throws Exception
115
-     */
116
-    public function loadEditorBlocks()
117
-    {
118
-        try {
119
-            $this->populateEditorBlockCollection();
120
-            // cycle thru block loaders and initialize each loader
121
-            foreach ($this->blocks as $block) {
122
-                $block->initialize();
123
-            }
124
-        } catch (Exception $exception) {
125
-            new ExceptionStackTraceDisplay($exception);
126
-        }
127
-    }
128
-
129
-
130
-    /**
131
-     * calls registerBlock() and load assets for all installed blocks
132
-     *
133
-     * @return void
134
-     * @throws Exception
135
-     */
136
-    public function registerEditorBlocks()
137
-    {
138
-        try {
139
-            // register primary assets
140
-            add_action('enqueue_block_assets', array($this, 'registerStyles'));
141
-            add_action('enqueue_block_assets', array($this, 'registerScripts'));
142
-            // cycle thru block loader folders
143
-            foreach ($this->blocks as $block) {
144
-                // perform any setup required for the block
145
-                $block_type = $block->registerBlock();
146
-                if (! $block_type instanceof WP_Block_Type) {
147
-                    throw new InvalidEntityException($block_type, 'WP_Block_Type');
148
-                }
149
-                add_action('enqueue_block_assets', array($block, 'registerStyles'));
150
-                add_action('enqueue_block_assets', array($block, 'registerScripts'));
151
-                do_action(
152
-                    'FHEE__EventEspresso_core_services_editor_EditorBlockManager__registerEditorBlocks__block_type_registered',
153
-                    $block,
154
-                    $block_type
155
-                );
156
-            }
157
-        } catch (Exception $exception) {
158
-            new ExceptionStackTraceDisplay($exception);
159
-        }
160
-    }
161
-
162
-
163
-    public function registerStyles()
164
-    {
165
-        // wp_register_style(
166
-        //     'ee-block-styles',
167
-        //     $this->domain->distributionAssetsUrl() . 'style.css',
168
-        //     array(),
169
-        //     filemtime($this->domain->distributionAssetsPath() . 'style.css')
170
-        // );
171
-    }
172
-
173
-
174
-    public function registerScripts()
175
-    {
176
-        wp_register_script(
177
-            'ee-core-blocks',
178
-            $this->assets_registry->getAssetUrl(Registry::ASSET_NAMESPACE, 'core-blocks', Registry::ASSET_TYPE_JS),
179
-            array(
180
-                'eejs-core',
181
-                'wp-blocks',    // Provides useful functions and components for extending the editor
182
-                'wp-i18n',      // Provides localization functions
183
-                'wp-element',   // Provides React.Component
184
-                'wp-components' // Provides many prebuilt components and controls
185
-            ),
186
-            null,
187
-            true
188
-        );
189
-    }
41
+	/**
42
+	 *  Returns the name of a hookpoint to be used to call initialize()
43
+	 *
44
+	 * @return string
45
+	 */
46
+	public function init_hook()
47
+	{
48
+		return 'AHEE__EE_System__set_hooks_for_core';
49
+	}
50
+
51
+
52
+	/**
53
+	 * Perform any early setup required for block editors to functions
54
+	 *
55
+	 * @return void
56
+	 * @throws Exception
57
+	 */
58
+	public function initialize()
59
+	{
60
+		$this->loadEditorBlocks();
61
+		add_action('AHEE__EE_System__initialize', array($this, 'registerEditorBlocks'));
62
+	}
63
+
64
+
65
+	/**
66
+	 * @return CollectionInterface|EditorBlockInterface[]
67
+	 * @throws ReflectionException
68
+	 * @throws InvalidArgumentException
69
+	 * @throws EE_Error
70
+	 * @throws InvalidClassException
71
+	 * @throws InvalidDataTypeException
72
+	 * @throws InvalidEntityException
73
+	 * @throws InvalidFilePathException
74
+	 * @throws InvalidIdentifierException
75
+	 * @throws InvalidInterfaceException
76
+	 */
77
+	protected function populateEditorBlockCollection()
78
+	{
79
+		$loader = new CollectionLoader(
80
+			new CollectionDetails(
81
+			// collection name
82
+				'shortcodes',
83
+				// collection interface
84
+				'EventEspresso\core\domain\entities\editor\EditorBlockInterface',
85
+				// FQCNs for classes to add (all classes within each namespace will be loaded)
86
+				apply_filters(
87
+					'FHEE__EventEspresso_core_services_editor_EditorBlockManager__populateEditorBlockCollection__collection_FQCNs',
88
+					array()
89
+					// array(
90
+					//     'EventEspresso\core\domain\entities\editor\blocks\common',
91
+					//     'EventEspresso\core\domain\entities\editor\blocks\editor',
92
+					//     'EventEspresso\core\domain\entities\editor\blocks\shortcodes',
93
+					//     'EventEspresso\core\domain\entities\editor\blocks\widgets',
94
+					// )
95
+				),
96
+				// filepaths to classes to add
97
+				array(),
98
+				// file mask to use if parsing folder for files to add
99
+				'',
100
+				// what to use as identifier for collection entities
101
+				// using CLASS NAME prevents duplicates (works like a singleton)
102
+				CollectionDetails::ID_CLASS_NAME
103
+			),
104
+			$this->blocks
105
+		);
106
+		return $loader->getCollection();
107
+	}
108
+
109
+
110
+	/**
111
+	 * populates the EditorBlockCollection and calls initialize() on all installed blocks
112
+	 *
113
+	 * @return void
114
+	 * @throws Exception
115
+	 */
116
+	public function loadEditorBlocks()
117
+	{
118
+		try {
119
+			$this->populateEditorBlockCollection();
120
+			// cycle thru block loaders and initialize each loader
121
+			foreach ($this->blocks as $block) {
122
+				$block->initialize();
123
+			}
124
+		} catch (Exception $exception) {
125
+			new ExceptionStackTraceDisplay($exception);
126
+		}
127
+	}
128
+
129
+
130
+	/**
131
+	 * calls registerBlock() and load assets for all installed blocks
132
+	 *
133
+	 * @return void
134
+	 * @throws Exception
135
+	 */
136
+	public function registerEditorBlocks()
137
+	{
138
+		try {
139
+			// register primary assets
140
+			add_action('enqueue_block_assets', array($this, 'registerStyles'));
141
+			add_action('enqueue_block_assets', array($this, 'registerScripts'));
142
+			// cycle thru block loader folders
143
+			foreach ($this->blocks as $block) {
144
+				// perform any setup required for the block
145
+				$block_type = $block->registerBlock();
146
+				if (! $block_type instanceof WP_Block_Type) {
147
+					throw new InvalidEntityException($block_type, 'WP_Block_Type');
148
+				}
149
+				add_action('enqueue_block_assets', array($block, 'registerStyles'));
150
+				add_action('enqueue_block_assets', array($block, 'registerScripts'));
151
+				do_action(
152
+					'FHEE__EventEspresso_core_services_editor_EditorBlockManager__registerEditorBlocks__block_type_registered',
153
+					$block,
154
+					$block_type
155
+				);
156
+			}
157
+		} catch (Exception $exception) {
158
+			new ExceptionStackTraceDisplay($exception);
159
+		}
160
+	}
161
+
162
+
163
+	public function registerStyles()
164
+	{
165
+		// wp_register_style(
166
+		//     'ee-block-styles',
167
+		//     $this->domain->distributionAssetsUrl() . 'style.css',
168
+		//     array(),
169
+		//     filemtime($this->domain->distributionAssetsPath() . 'style.css')
170
+		// );
171
+	}
172
+
173
+
174
+	public function registerScripts()
175
+	{
176
+		wp_register_script(
177
+			'ee-core-blocks',
178
+			$this->assets_registry->getAssetUrl(Registry::ASSET_NAMESPACE, 'core-blocks', Registry::ASSET_TYPE_JS),
179
+			array(
180
+				'eejs-core',
181
+				'wp-blocks',    // Provides useful functions and components for extending the editor
182
+				'wp-i18n',      // Provides localization functions
183
+				'wp-element',   // Provides React.Component
184
+				'wp-components' // Provides many prebuilt components and controls
185
+			),
186
+			null,
187
+			true
188
+		);
189
+	}
190 190
 
191 191
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -143,7 +143,7 @@  discard block
 block discarded – undo
143 143
             foreach ($this->blocks as $block) {
144 144
                 // perform any setup required for the block
145 145
                 $block_type = $block->registerBlock();
146
-                if (! $block_type instanceof WP_Block_Type) {
146
+                if ( ! $block_type instanceof WP_Block_Type) {
147 147
                     throw new InvalidEntityException($block_type, 'WP_Block_Type');
148 148
                 }
149 149
                 add_action('enqueue_block_assets', array($block, 'registerStyles'));
@@ -178,9 +178,9 @@  discard block
 block discarded – undo
178 178
             $this->assets_registry->getAssetUrl(Registry::ASSET_NAMESPACE, 'core-blocks', Registry::ASSET_TYPE_JS),
179 179
             array(
180 180
                 'eejs-core',
181
-                'wp-blocks',    // Provides useful functions and components for extending the editor
182
-                'wp-i18n',      // Provides localization functions
183
-                'wp-element',   // Provides React.Component
181
+                'wp-blocks', // Provides useful functions and components for extending the editor
182
+                'wp-i18n', // Provides localization functions
183
+                'wp-element', // Provides React.Component
184 184
                 'wp-components' // Provides many prebuilt components and controls
185 185
             ),
186 186
             null,
Please login to merge, or discard this patch.
core/EE_System.core.php 2 patches
Spacing   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -148,7 +148,7 @@  discard block
 block discarded – undo
148 148
         EE_Maintenance_Mode $maintenance_mode = null
149 149
     ) {
150 150
         // check if class object is instantiated
151
-        if (! self::$_instance instanceof EE_System) {
151
+        if ( ! self::$_instance instanceof EE_System) {
152 152
             self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
153 153
         }
154 154
         return self::$_instance;
@@ -267,7 +267,7 @@  discard block
 block discarded – undo
267 267
         $this->capabilities = $this->loader->getShared('EE_Capabilities');
268 268
         add_action(
269 269
             'AHEE__EE_Capabilities__init_caps__before_initialization',
270
-            function ()
270
+            function()
271 271
             {
272 272
                 LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
273 273
             }
@@ -311,7 +311,7 @@  discard block
 block discarded – undo
311 311
     {
312 312
         // set autoloaders for all of the classes implementing EEI_Plugin_API
313 313
         // which provide helpers for EE plugin authors to more easily register certain components with EE.
314
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
314
+        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'plugin_api');
315 315
         $this->loader->getShared('EE_Request_Handler');
316 316
     }
317 317
 
@@ -331,14 +331,14 @@  discard block
 block discarded – undo
331 331
         $load_callback,
332 332
         $plugin_file_constant
333 333
     ) {
334
-        if (! defined($version_constant)) {
334
+        if ( ! defined($version_constant)) {
335 335
             return;
336 336
         }
337 337
         $addon_version = constant($version_constant);
338 338
         if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
339 339
             remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
340
-            if (! function_exists('deactivate_plugins')) {
341
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
340
+            if ( ! function_exists('deactivate_plugins')) {
341
+                require_once ABSPATH.'wp-admin/includes/plugin.php';
342 342
             }
343 343
             deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
344 344
             unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
@@ -351,7 +351,7 @@  discard block
 block discarded – undo
351 351
                     $addon_name,
352 352
                     $min_version_required
353 353
                 ),
354
-                __FILE__, __FUNCTION__ . "({$addon_name})", __LINE__
354
+                __FILE__, __FUNCTION__."({$addon_name})", __LINE__
355 355
             );
356 356
             EE_Error::get_notices(false, true);
357 357
         }
@@ -401,7 +401,7 @@  discard block
 block discarded – undo
401 401
                 true
402 402
             )
403 403
         ) {
404
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
404
+            include_once EE_THIRD_PARTY.'wp-api-basic-auth'.DS.'basic-auth.php';
405 405
         }
406 406
         do_action('AHEE__EE_System__load_espresso_addons__complete');
407 407
     }
@@ -508,11 +508,11 @@  discard block
 block discarded – undo
508 508
     private function fix_espresso_db_upgrade_option($espresso_db_update = null)
509 509
     {
510 510
         do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
511
-        if (! $espresso_db_update) {
511
+        if ( ! $espresso_db_update) {
512 512
             $espresso_db_update = get_option('espresso_db_update');
513 513
         }
514 514
         // check that option is an array
515
-        if (! is_array($espresso_db_update)) {
515
+        if ( ! is_array($espresso_db_update)) {
516 516
             // if option is FALSE, then it never existed
517 517
             if ($espresso_db_update === false) {
518 518
                 // make $espresso_db_update an array and save option with autoload OFF
@@ -532,10 +532,10 @@  discard block
 block discarded – undo
532 532
                     //so it must be numerically-indexed, where values are versions installed...
533 533
                     //fix it!
534 534
                     $version_string                         = $should_be_array;
535
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
535
+                    $corrected_db_update[$version_string] = array('unknown-date');
536 536
                 } else {
537 537
                     //ok it checks out
538
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
538
+                    $corrected_db_update[$should_be_version_string] = $should_be_array;
539 539
                 }
540 540
             }
541 541
             $espresso_db_update = $corrected_db_update;
@@ -617,13 +617,13 @@  discard block
 block discarded – undo
617 617
      */
618 618
     public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
619 619
     {
620
-        if (! $version_history) {
620
+        if ( ! $version_history) {
621 621
             $version_history = $this->fix_espresso_db_upgrade_option($version_history);
622 622
         }
623 623
         if ($current_version_to_add === null) {
624 624
             $current_version_to_add = espresso_version();
625 625
         }
626
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
626
+        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
627 627
         // re-save
628 628
         return update_option('espresso_db_update', $version_history);
629 629
     }
@@ -716,7 +716,7 @@  discard block
 block discarded – undo
716 716
         if ($activation_history_for_addon) {
717 717
             //it exists, so this isn't a completely new install
718 718
             //check if this version already in that list of previously installed versions
719
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
719
+            if ( ! isset($activation_history_for_addon[$version_to_upgrade_to])) {
720 720
                 //it a version we haven't seen before
721 721
                 if ($version_is_higher === 1) {
722 722
                     $req_type = EE_System::req_type_upgrade;
@@ -796,7 +796,7 @@  discard block
 block discarded – undo
796 796
             foreach ($activation_history as $version => $times_activated) {
797 797
                 //check there is a record of when this version was activated. Otherwise,
798 798
                 //mark it as unknown
799
-                if (! $times_activated) {
799
+                if ( ! $times_activated) {
800 800
                     $times_activated = array('unknown-date');
801 801
                 }
802 802
                 if (is_string($times_activated)) {
@@ -897,7 +897,7 @@  discard block
 block discarded – undo
897 897
     private function _parse_model_names()
898 898
     {
899 899
         //get all the files in the EE_MODELS folder that end in .model.php
900
-        $models                 = glob(EE_MODELS . '*.model.php');
900
+        $models                 = glob(EE_MODELS.'*.model.php');
901 901
         $model_names            = array();
902 902
         $non_abstract_db_models = array();
903 903
         foreach ($models as $model) {
@@ -906,9 +906,9 @@  discard block
 block discarded – undo
906 906
             $short_name      = str_replace('EEM_', '', $classname);
907 907
             $reflectionClass = new ReflectionClass($classname);
908 908
             if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
909
-                $non_abstract_db_models[ $short_name ] = $classname;
909
+                $non_abstract_db_models[$short_name] = $classname;
910 910
             }
911
-            $model_names[ $short_name ] = $classname;
911
+            $model_names[$short_name] = $classname;
912 912
         }
913 913
         $this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
914 914
         $this->registry->non_abstract_db_models = apply_filters(
@@ -943,7 +943,7 @@  discard block
 block discarded – undo
943 943
             )
944 944
         );
945 945
         if ($domain->isCaffeinated()) {
946
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
946
+            require_once EE_CAFF_PATH.'brewing_regular.php';
947 947
         }
948 948
     }
949 949
 
@@ -1008,17 +1008,17 @@  discard block
 block discarded – undo
1008 1008
         $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
1009 1009
             'AHEE__EE_System__register_shortcodes_modules_and_addons'
1010 1010
         );
1011
-        if (! empty($class_names)) {
1011
+        if ( ! empty($class_names)) {
1012 1012
             $msg = __(
1013 1013
                 'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1014 1014
                 'event_espresso'
1015 1015
             );
1016 1016
             $msg .= '<ul>';
1017 1017
             foreach ($class_names as $class_name) {
1018
-                $msg .= '<li><b>Event Espresso - ' . str_replace(
1018
+                $msg .= '<li><b>Event Espresso - '.str_replace(
1019 1019
                         array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
1020 1020
                         $class_name
1021
-                    ) . '</b></li>';
1021
+                    ).'</b></li>';
1022 1022
             }
1023 1023
             $msg .= '</ul>';
1024 1024
             $msg .= __(
@@ -1090,7 +1090,7 @@  discard block
 block discarded – undo
1090 1090
     private function _deactivate_incompatible_addons()
1091 1091
     {
1092 1092
         $incompatible_addons = get_option('ee_incompatible_addons', array());
1093
-        if (! empty($incompatible_addons)) {
1093
+        if ( ! empty($incompatible_addons)) {
1094 1094
             $active_plugins = get_option('active_plugins', array());
1095 1095
             foreach ($active_plugins as $active_plugin) {
1096 1096
                 foreach ($incompatible_addons as $incompatible_addon) {
@@ -1181,7 +1181,7 @@  discard block
 block discarded – undo
1181 1181
         do_action('AHEE__EE_System__core_loaded_and_ready');
1182 1182
         // load_espresso_template_tags
1183 1183
         if (
1184
-            is_readable(EE_PUBLIC . 'template_tags.php')
1184
+            is_readable(EE_PUBLIC.'template_tags.php')
1185 1185
             && (
1186 1186
                 $this->request->isFrontend()
1187 1187
                 || $this->request->isAdmin()
@@ -1189,7 +1189,7 @@  discard block
 block discarded – undo
1189 1189
                 || $this->request->isFeed()
1190 1190
             )
1191 1191
         ) {
1192
-            require_once EE_PUBLIC . 'template_tags.php';
1192
+            require_once EE_PUBLIC.'template_tags.php';
1193 1193
         }
1194 1194
         do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1195 1195
         if ($this->request->isAdmin() || $this->request->isFrontend() || $this->request->isIframe()) {
@@ -1253,13 +1253,13 @@  discard block
 block discarded – undo
1253 1253
     public static function do_not_cache()
1254 1254
     {
1255 1255
         // set no cache constants
1256
-        if (! defined('DONOTCACHEPAGE')) {
1256
+        if ( ! defined('DONOTCACHEPAGE')) {
1257 1257
             define('DONOTCACHEPAGE', true);
1258 1258
         }
1259
-        if (! defined('DONOTCACHCEOBJECT')) {
1259
+        if ( ! defined('DONOTCACHCEOBJECT')) {
1260 1260
             define('DONOTCACHCEOBJECT', true);
1261 1261
         }
1262
-        if (! defined('DONOTCACHEDB')) {
1262
+        if ( ! defined('DONOTCACHEDB')) {
1263 1263
             define('DONOTCACHEDB', true);
1264 1264
         }
1265 1265
         // add no cache headers
Please login to merge, or discard this patch.
Indentation   +1306 added lines, -1306 removed lines patch added patch discarded remove patch
@@ -32,1312 +32,1312 @@
 block discarded – undo
32 32
 {
33 33
 
34 34
 
35
-    /**
36
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
37
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
38
-     */
39
-    const req_type_normal = 0;
40
-
41
-    /**
42
-     * Indicates this is a brand new installation of EE so we should install
43
-     * tables and default data etc
44
-     */
45
-    const req_type_new_activation = 1;
46
-
47
-    /**
48
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
49
-     * and we just exited maintenance mode). We MUST check the database is setup properly
50
-     * and that default data is setup too
51
-     */
52
-    const req_type_reactivation = 2;
53
-
54
-    /**
55
-     * indicates that EE has been upgraded since its previous request.
56
-     * We may have data migration scripts to call and will want to trigger maintenance mode
57
-     */
58
-    const req_type_upgrade = 3;
59
-
60
-    /**
61
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
62
-     */
63
-    const req_type_downgrade = 4;
64
-
65
-    /**
66
-     * @deprecated since version 4.6.0.dev.006
67
-     * Now whenever a new_activation is detected the request type is still just
68
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
69
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
70
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
71
-     * (Specifically, when the migration manager indicates migrations are finished
72
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
73
-     */
74
-    const req_type_activation_but_not_installed = 5;
75
-
76
-    /**
77
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
78
-     */
79
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
80
-
81
-
82
-    /**
83
-     * @var EE_System $_instance
84
-     */
85
-    private static $_instance;
86
-
87
-    /**
88
-     * @var EE_Registry $registry
89
-     */
90
-    private $registry;
91
-
92
-    /**
93
-     * @var LoaderInterface $loader
94
-     */
95
-    private $loader;
96
-
97
-    /**
98
-     * @var EE_Capabilities $capabilities
99
-     */
100
-    private $capabilities;
101
-
102
-    /**
103
-     * @var RequestInterface $request
104
-     */
105
-    private $request;
106
-
107
-    /**
108
-     * @var EE_Maintenance_Mode $maintenance_mode
109
-     */
110
-    private $maintenance_mode;
111
-
112
-    /**
113
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
114
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
115
-     *
116
-     * @var int $_req_type
117
-     */
118
-    private $_req_type;
119
-
120
-    /**
121
-     * Whether or not there was a non-micro version change in EE core version during this request
122
-     *
123
-     * @var boolean $_major_version_change
124
-     */
125
-    private $_major_version_change = false;
126
-
127
-    /**
128
-     * A Context DTO dedicated solely to identifying the current request type.
129
-     *
130
-     * @var RequestTypeContextCheckerInterface $request_type
131
-     */
132
-    private $request_type;
133
-
134
-
135
-
136
-    /**
137
-     * @singleton method used to instantiate class object
138
-     * @param EE_Registry|null         $registry
139
-     * @param LoaderInterface|null     $loader
140
-     * @param RequestInterface|null          $request
141
-     * @param EE_Maintenance_Mode|null $maintenance_mode
142
-     * @return EE_System
143
-     */
144
-    public static function instance(
145
-        EE_Registry $registry = null,
146
-        LoaderInterface $loader = null,
147
-        RequestInterface $request = null,
148
-        EE_Maintenance_Mode $maintenance_mode = null
149
-    ) {
150
-        // check if class object is instantiated
151
-        if (! self::$_instance instanceof EE_System) {
152
-            self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
153
-        }
154
-        return self::$_instance;
155
-    }
156
-
157
-
158
-
159
-    /**
160
-     * resets the instance and returns it
161
-     *
162
-     * @return EE_System
163
-     */
164
-    public static function reset()
165
-    {
166
-        self::$_instance->_req_type = null;
167
-        //make sure none of the old hooks are left hanging around
168
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
169
-        //we need to reset the migration manager in order for it to detect DMSs properly
170
-        EE_Data_Migration_Manager::reset();
171
-        self::instance()->detect_activations_or_upgrades();
172
-        self::instance()->perform_activations_upgrades_and_migrations();
173
-        return self::instance();
174
-    }
175
-
176
-
177
-
178
-    /**
179
-     * sets hooks for running rest of system
180
-     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
181
-     * starting EE Addons from any other point may lead to problems
182
-     *
183
-     * @param EE_Registry         $registry
184
-     * @param LoaderInterface     $loader
185
-     * @param RequestInterface          $request
186
-     * @param EE_Maintenance_Mode $maintenance_mode
187
-     */
188
-    private function __construct(
189
-        EE_Registry $registry,
190
-        LoaderInterface $loader,
191
-        RequestInterface $request,
192
-        EE_Maintenance_Mode $maintenance_mode
193
-    ) {
194
-        $this->registry         = $registry;
195
-        $this->loader           = $loader;
196
-        $this->request          = $request;
197
-        $this->maintenance_mode = $maintenance_mode;
198
-        do_action('AHEE__EE_System__construct__begin', $this);
199
-        add_action(
200
-            'AHEE__EE_Bootstrap__load_espresso_addons',
201
-            array($this, 'loadCapabilities'),
202
-            5
203
-        );
204
-        add_action(
205
-            'AHEE__EE_Bootstrap__load_espresso_addons',
206
-            array($this, 'loadCommandBus'),
207
-            7
208
-        );
209
-        add_action(
210
-            'AHEE__EE_Bootstrap__load_espresso_addons',
211
-            array($this, 'loadPluginApi'),
212
-            9
213
-        );
214
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
215
-        add_action(
216
-            'AHEE__EE_Bootstrap__load_espresso_addons',
217
-            array($this, 'load_espresso_addons')
218
-        );
219
-        // when an ee addon is activated, we want to call the core hook(s) again
220
-        // because the newly-activated addon didn't get a chance to run at all
221
-        add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
222
-        // detect whether install or upgrade
223
-        add_action(
224
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
225
-            array($this, 'detect_activations_or_upgrades'),
226
-            3
227
-        );
228
-        // load EE_Config, EE_Textdomain, etc
229
-        add_action(
230
-            'AHEE__EE_Bootstrap__load_core_configuration',
231
-            array($this, 'load_core_configuration'),
232
-            5
233
-        );
234
-        // load EE_Config, EE_Textdomain, etc
235
-        add_action(
236
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
237
-            array($this, 'register_shortcodes_modules_and_widgets'),
238
-            7
239
-        );
240
-        // you wanna get going? I wanna get going... let's get going!
241
-        add_action(
242
-            'AHEE__EE_Bootstrap__brew_espresso',
243
-            array($this, 'brew_espresso'),
244
-            9
245
-        );
246
-        //other housekeeping
247
-        //exclude EE critical pages from wp_list_pages
248
-        add_filter(
249
-            'wp_list_pages_excludes',
250
-            array($this, 'remove_pages_from_wp_list_pages'),
251
-            10
252
-        );
253
-        // ALL EE Addons should use the following hook point to attach their initial setup too
254
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
255
-        do_action('AHEE__EE_System__construct__complete', $this);
256
-    }
257
-
258
-
259
-    /**
260
-     * load and setup EE_Capabilities
261
-     *
262
-     * @return void
263
-     * @throws EE_Error
264
-     */
265
-    public function loadCapabilities()
266
-    {
267
-        $this->capabilities = $this->loader->getShared('EE_Capabilities');
268
-        add_action(
269
-            'AHEE__EE_Capabilities__init_caps__before_initialization',
270
-            function ()
271
-            {
272
-                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
273
-            }
274
-        );
275
-    }
276
-
277
-
278
-
279
-    /**
280
-     * create and cache the CommandBus, and also add middleware
281
-     * The CapChecker middleware requires the use of EE_Capabilities
282
-     * which is why we need to load the CommandBus after Caps are set up
283
-     *
284
-     * @return void
285
-     * @throws EE_Error
286
-     */
287
-    public function loadCommandBus()
288
-    {
289
-        $this->loader->getShared(
290
-            'CommandBusInterface',
291
-            array(
292
-                null,
293
-                apply_filters(
294
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
295
-                    array(
296
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
297
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
298
-                    )
299
-                ),
300
-            )
301
-        );
302
-    }
303
-
304
-
305
-
306
-    /**
307
-     * @return void
308
-     * @throws EE_Error
309
-     */
310
-    public function loadPluginApi()
311
-    {
312
-        // set autoloaders for all of the classes implementing EEI_Plugin_API
313
-        // which provide helpers for EE plugin authors to more easily register certain components with EE.
314
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
315
-        $this->loader->getShared('EE_Request_Handler');
316
-    }
317
-
318
-
319
-    /**
320
-     * @param string $addon_name
321
-     * @param string $version_constant
322
-     * @param string $min_version_required
323
-     * @param string $load_callback
324
-     * @param string $plugin_file_constant
325
-     * @return void
326
-     */
327
-    private function deactivateIncompatibleAddon(
328
-        $addon_name,
329
-        $version_constant,
330
-        $min_version_required,
331
-        $load_callback,
332
-        $plugin_file_constant
333
-    ) {
334
-        if (! defined($version_constant)) {
335
-            return;
336
-        }
337
-        $addon_version = constant($version_constant);
338
-        if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
339
-            remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
340
-            if (! function_exists('deactivate_plugins')) {
341
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
342
-            }
343
-            deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
344
-            unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
345
-            EE_Error::add_error(
346
-                sprintf(
347
-                    esc_html__(
348
-                        'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
349
-                        'event_espresso'
350
-                    ),
351
-                    $addon_name,
352
-                    $min_version_required
353
-                ),
354
-                __FILE__, __FUNCTION__ . "({$addon_name})", __LINE__
355
-            );
356
-            EE_Error::get_notices(false, true);
357
-        }
358
-    }
359
-
360
-
361
-    /**
362
-     * load_espresso_addons
363
-     * allow addons to load first so that they can set hooks for running DMS's, etc
364
-     * this is hooked into both:
365
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
366
-     *        which runs during the WP 'plugins_loaded' action at priority 5
367
-     *    and the WP 'activate_plugin' hook point
368
-     *
369
-     * @access public
370
-     * @return void
371
-     */
372
-    public function load_espresso_addons()
373
-    {
374
-        $this->deactivateIncompatibleAddon(
375
-            'Wait Lists',
376
-            'EE_WAIT_LISTS_VERSION',
377
-            '1.0.0.beta.074',
378
-            'load_espresso_wait_lists',
379
-            'EE_WAIT_LISTS_PLUGIN_FILE'
380
-        );
381
-        $this->deactivateIncompatibleAddon(
382
-            'Automated Upcoming Event Notifications',
383
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
384
-            '1.0.0.beta.091',
385
-            'load_espresso_automated_upcoming_event_notification',
386
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
387
-        );
388
-        do_action('AHEE__EE_System__load_espresso_addons');
389
-        //if the WP API basic auth plugin isn't already loaded, load it now.
390
-        //We want it for mobile apps. Just include the entire plugin
391
-        //also, don't load the basic auth when a plugin is getting activated, because
392
-        //it could be the basic auth plugin, and it doesn't check if its methods are already defined
393
-        //and causes a fatal error
394
-        if (
395
-            $this->request->getRequestParam('activate') !== 'true'
396
-            && ! function_exists('json_basic_auth_handler')
397
-            && ! function_exists('json_basic_auth_error')
398
-            && ! in_array(
399
-                $this->request->getRequestParam('action'),
400
-                array('activate', 'activate-selected'),
401
-                true
402
-            )
403
-        ) {
404
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
405
-        }
406
-        do_action('AHEE__EE_System__load_espresso_addons__complete');
407
-    }
408
-
409
-
410
-
411
-    /**
412
-     * detect_activations_or_upgrades
413
-     * Checks for activation or upgrade of core first;
414
-     * then also checks if any registered addons have been activated or upgraded
415
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
416
-     * which runs during the WP 'plugins_loaded' action at priority 3
417
-     *
418
-     * @access public
419
-     * @return void
420
-     */
421
-    public function detect_activations_or_upgrades()
422
-    {
423
-        //first off: let's make sure to handle core
424
-        $this->detect_if_activation_or_upgrade();
425
-        foreach ($this->registry->addons as $addon) {
426
-            if ($addon instanceof EE_Addon) {
427
-                //detect teh request type for that addon
428
-                $addon->detect_activation_or_upgrade();
429
-            }
430
-        }
431
-    }
432
-
433
-
434
-
435
-    /**
436
-     * detect_if_activation_or_upgrade
437
-     * Takes care of detecting whether this is a brand new install or code upgrade,
438
-     * and either setting up the DB or setting up maintenance mode etc.
439
-     *
440
-     * @access public
441
-     * @return void
442
-     */
443
-    public function detect_if_activation_or_upgrade()
444
-    {
445
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
446
-        // check if db has been updated, or if its a brand-new installation
447
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
448
-        $request_type       = $this->detect_req_type($espresso_db_update);
449
-        //EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
450
-        switch ($request_type) {
451
-            case EE_System::req_type_new_activation:
452
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
453
-                $this->_handle_core_version_change($espresso_db_update);
454
-                break;
455
-            case EE_System::req_type_reactivation:
456
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
457
-                $this->_handle_core_version_change($espresso_db_update);
458
-                break;
459
-            case EE_System::req_type_upgrade:
460
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
461
-                //migrations may be required now that we've upgraded
462
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
463
-                $this->_handle_core_version_change($espresso_db_update);
464
-                //				echo "done upgrade";die;
465
-                break;
466
-            case EE_System::req_type_downgrade:
467
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
468
-                //its possible migrations are no longer required
469
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
470
-                $this->_handle_core_version_change($espresso_db_update);
471
-                break;
472
-            case EE_System::req_type_normal:
473
-            default:
474
-                break;
475
-        }
476
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
477
-    }
478
-
479
-
480
-
481
-    /**
482
-     * Updates the list of installed versions and sets hooks for
483
-     * initializing the database later during the request
484
-     *
485
-     * @param array $espresso_db_update
486
-     */
487
-    private function _handle_core_version_change($espresso_db_update)
488
-    {
489
-        $this->update_list_of_installed_versions($espresso_db_update);
490
-        //get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
491
-        add_action(
492
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
493
-            array($this, 'initialize_db_if_no_migrations_required')
494
-        );
495
-    }
496
-
497
-
498
-
499
-    /**
500
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
501
-     * information about what versions of EE have been installed and activated,
502
-     * NOT necessarily the state of the database
503
-     *
504
-     * @param mixed $espresso_db_update           the value of the WordPress option.
505
-     *                                            If not supplied, fetches it from the options table
506
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
507
-     */
508
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null)
509
-    {
510
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
511
-        if (! $espresso_db_update) {
512
-            $espresso_db_update = get_option('espresso_db_update');
513
-        }
514
-        // check that option is an array
515
-        if (! is_array($espresso_db_update)) {
516
-            // if option is FALSE, then it never existed
517
-            if ($espresso_db_update === false) {
518
-                // make $espresso_db_update an array and save option with autoload OFF
519
-                $espresso_db_update = array();
520
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
521
-            } else {
522
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
523
-                $espresso_db_update = array($espresso_db_update => array());
524
-                update_option('espresso_db_update', $espresso_db_update);
525
-            }
526
-        } else {
527
-            $corrected_db_update = array();
528
-            //if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
529
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
530
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
531
-                    //the key is an int, and the value IS NOT an array
532
-                    //so it must be numerically-indexed, where values are versions installed...
533
-                    //fix it!
534
-                    $version_string                         = $should_be_array;
535
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
536
-                } else {
537
-                    //ok it checks out
538
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
539
-                }
540
-            }
541
-            $espresso_db_update = $corrected_db_update;
542
-            update_option('espresso_db_update', $espresso_db_update);
543
-        }
544
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
545
-        return $espresso_db_update;
546
-    }
547
-
548
-
549
-
550
-    /**
551
-     * Does the traditional work of setting up the plugin's database and adding default data.
552
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
553
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
554
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
555
-     * so that it will be done when migrations are finished
556
-     *
557
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
558
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
559
-     *                                       This is a resource-intensive job
560
-     *                                       so we prefer to only do it when necessary
561
-     * @return void
562
-     * @throws EE_Error
563
-     */
564
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
565
-    {
566
-        $request_type = $this->detect_req_type();
567
-        //only initialize system if we're not in maintenance mode.
568
-        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
569
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
570
-            $rewrite_rules = $this->loader->getShared(
571
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
572
-            );
573
-            $rewrite_rules->flush();
574
-            if ($verify_schema) {
575
-                EEH_Activation::initialize_db_and_folders();
576
-            }
577
-            EEH_Activation::initialize_db_content();
578
-            EEH_Activation::system_initialization();
579
-            if ($initialize_addons_too) {
580
-                $this->initialize_addons();
581
-            }
582
-        } else {
583
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
584
-        }
585
-        if ($request_type === EE_System::req_type_new_activation
586
-            || $request_type === EE_System::req_type_reactivation
587
-            || (
588
-                $request_type === EE_System::req_type_upgrade
589
-                && $this->is_major_version_change()
590
-            )
591
-        ) {
592
-            add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
593
-        }
594
-    }
595
-
596
-
597
-
598
-    /**
599
-     * Initializes the db for all registered addons
600
-     *
601
-     * @throws EE_Error
602
-     */
603
-    public function initialize_addons()
604
-    {
605
-        //foreach registered addon, make sure its db is up-to-date too
606
-        foreach ($this->registry->addons as $addon) {
607
-            if ($addon instanceof EE_Addon) {
608
-                $addon->initialize_db_if_no_migrations_required();
609
-            }
610
-        }
611
-    }
612
-
613
-
614
-
615
-    /**
616
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
617
-     *
618
-     * @param    array  $version_history
619
-     * @param    string $current_version_to_add version to be added to the version history
620
-     * @return    boolean success as to whether or not this option was changed
621
-     */
622
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
623
-    {
624
-        if (! $version_history) {
625
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
626
-        }
627
-        if ($current_version_to_add === null) {
628
-            $current_version_to_add = espresso_version();
629
-        }
630
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
631
-        // re-save
632
-        return update_option('espresso_db_update', $version_history);
633
-    }
634
-
635
-
636
-
637
-    /**
638
-     * Detects if the current version indicated in the has existed in the list of
639
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
640
-     *
641
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
642
-     *                                  If not supplied, fetches it from the options table.
643
-     *                                  Also, caches its result so later parts of the code can also know whether
644
-     *                                  there's been an update or not. This way we can add the current version to
645
-     *                                  espresso_db_update, but still know if this is a new install or not
646
-     * @return int one of the constants on EE_System::req_type_
647
-     */
648
-    public function detect_req_type($espresso_db_update = null)
649
-    {
650
-        if ($this->_req_type === null) {
651
-            $espresso_db_update          = ! empty($espresso_db_update)
652
-                ? $espresso_db_update
653
-                : $this->fix_espresso_db_upgrade_option();
654
-            $this->_req_type             = EE_System::detect_req_type_given_activation_history(
655
-                $espresso_db_update,
656
-                'ee_espresso_activation', espresso_version()
657
-            );
658
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
659
-            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
660
-        }
661
-        return $this->_req_type;
662
-    }
663
-
664
-
665
-
666
-    /**
667
-     * Returns whether or not there was a non-micro version change (ie, change in either
668
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
669
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
670
-     *
671
-     * @param $activation_history
672
-     * @return bool
673
-     */
674
-    private function _detect_major_version_change($activation_history)
675
-    {
676
-        $previous_version       = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
677
-        $previous_version_parts = explode('.', $previous_version);
678
-        $current_version_parts  = explode('.', espresso_version());
679
-        return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
680
-               && ($previous_version_parts[0] !== $current_version_parts[0]
681
-                   || $previous_version_parts[1] !== $current_version_parts[1]
682
-               );
683
-    }
684
-
685
-
686
-
687
-    /**
688
-     * Returns true if either the major or minor version of EE changed during this request.
689
-     * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
690
-     *
691
-     * @return bool
692
-     */
693
-    public function is_major_version_change()
694
-    {
695
-        return $this->_major_version_change;
696
-    }
697
-
698
-
699
-
700
-    /**
701
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
702
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
703
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
704
-     * just activated to (for core that will always be espresso_version())
705
-     *
706
-     * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
707
-     *                                                 ee plugin. for core that's 'espresso_db_update'
708
-     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
709
-     *                                                 indicate that this plugin was just activated
710
-     * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
711
-     *                                                 espresso_version())
712
-     * @return int one of the constants on EE_System::req_type_*
713
-     */
714
-    public static function detect_req_type_given_activation_history(
715
-        $activation_history_for_addon,
716
-        $activation_indicator_option_name,
717
-        $version_to_upgrade_to
718
-    ) {
719
-        $version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
720
-        if ($activation_history_for_addon) {
721
-            //it exists, so this isn't a completely new install
722
-            //check if this version already in that list of previously installed versions
723
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
724
-                //it a version we haven't seen before
725
-                if ($version_is_higher === 1) {
726
-                    $req_type = EE_System::req_type_upgrade;
727
-                } else {
728
-                    $req_type = EE_System::req_type_downgrade;
729
-                }
730
-                delete_option($activation_indicator_option_name);
731
-            } else {
732
-                // its not an update. maybe a reactivation?
733
-                if (get_option($activation_indicator_option_name, false)) {
734
-                    if ($version_is_higher === -1) {
735
-                        $req_type = EE_System::req_type_downgrade;
736
-                    } elseif ($version_is_higher === 0) {
737
-                        //we've seen this version before, but it's an activation. must be a reactivation
738
-                        $req_type = EE_System::req_type_reactivation;
739
-                    } else {//$version_is_higher === 1
740
-                        $req_type = EE_System::req_type_upgrade;
741
-                    }
742
-                    delete_option($activation_indicator_option_name);
743
-                } else {
744
-                    //we've seen this version before and the activation indicate doesn't show it was just activated
745
-                    if ($version_is_higher === -1) {
746
-                        $req_type = EE_System::req_type_downgrade;
747
-                    } elseif ($version_is_higher === 0) {
748
-                        //we've seen this version before and it's not an activation. its normal request
749
-                        $req_type = EE_System::req_type_normal;
750
-                    } else {//$version_is_higher === 1
751
-                        $req_type = EE_System::req_type_upgrade;
752
-                    }
753
-                }
754
-            }
755
-        } else {
756
-            //brand new install
757
-            $req_type = EE_System::req_type_new_activation;
758
-            delete_option($activation_indicator_option_name);
759
-        }
760
-        return $req_type;
761
-    }
762
-
763
-
764
-
765
-    /**
766
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
767
-     * the $activation_history_for_addon
768
-     *
769
-     * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
770
-     *                                             sometimes containing 'unknown-date'
771
-     * @param string $version_to_upgrade_to        (current version)
772
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
773
-     *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
774
-     *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
775
-     *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
776
-     */
777
-    private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
778
-    {
779
-        //find the most recently-activated version
780
-        $most_recently_active_version =
781
-            EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
782
-        return version_compare($version_to_upgrade_to, $most_recently_active_version);
783
-    }
784
-
785
-
786
-
787
-    /**
788
-     * Gets the most recently active version listed in the activation history,
789
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
790
-     *
791
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
792
-     *                                   sometimes containing 'unknown-date'
793
-     * @return string
794
-     */
795
-    private static function _get_most_recently_active_version_from_activation_history($activation_history)
796
-    {
797
-        $most_recently_active_version_activation = '1970-01-01 00:00:00';
798
-        $most_recently_active_version            = '0.0.0.dev.000';
799
-        if (is_array($activation_history)) {
800
-            foreach ($activation_history as $version => $times_activated) {
801
-                //check there is a record of when this version was activated. Otherwise,
802
-                //mark it as unknown
803
-                if (! $times_activated) {
804
-                    $times_activated = array('unknown-date');
805
-                }
806
-                if (is_string($times_activated)) {
807
-                    $times_activated = array($times_activated);
808
-                }
809
-                foreach ($times_activated as $an_activation) {
810
-                    if ($an_activation !== 'unknown-date'
811
-                        && $an_activation
812
-                           > $most_recently_active_version_activation) {
813
-                        $most_recently_active_version            = $version;
814
-                        $most_recently_active_version_activation = $an_activation === 'unknown-date'
815
-                            ? '1970-01-01 00:00:00'
816
-                            : $an_activation;
817
-                    }
818
-                }
819
-            }
820
-        }
821
-        return $most_recently_active_version;
822
-    }
823
-
824
-
825
-
826
-    /**
827
-     * This redirects to the about EE page after activation
828
-     *
829
-     * @return void
830
-     */
831
-    public function redirect_to_about_ee()
832
-    {
833
-        $notices = EE_Error::get_notices(false);
834
-        //if current user is an admin and it's not an ajax or rest request
835
-        if (
836
-            ! isset($notices['errors'])
837
-            && $this->request->isAdmin()
838
-            && apply_filters(
839
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
840
-                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
841
-            )
842
-        ) {
843
-            $query_params = array('page' => 'espresso_about');
844
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
845
-                $query_params['new_activation'] = true;
846
-            }
847
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
848
-                $query_params['reactivation'] = true;
849
-            }
850
-            $url = add_query_arg($query_params, admin_url('admin.php'));
851
-            wp_safe_redirect($url);
852
-            exit();
853
-        }
854
-    }
855
-
856
-
857
-
858
-    /**
859
-     * load_core_configuration
860
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
861
-     * which runs during the WP 'plugins_loaded' action at priority 5
862
-     *
863
-     * @return void
864
-     * @throws ReflectionException
865
-     */
866
-    public function load_core_configuration()
867
-    {
868
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
869
-        $this->loader->getShared('EE_Load_Textdomain');
870
-        //load textdomain
871
-        EE_Load_Textdomain::load_textdomain();
872
-        // load and setup EE_Config and EE_Network_Config
873
-        $config = $this->loader->getShared('EE_Config');
874
-        $this->loader->getShared('EE_Network_Config');
875
-        // setup autoloaders
876
-        // enable logging?
877
-        if ($config->admin->use_full_logging) {
878
-            $this->loader->getShared('EE_Log');
879
-        }
880
-        // check for activation errors
881
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
882
-        if ($activation_errors) {
883
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
884
-            update_option('ee_plugin_activation_errors', false);
885
-        }
886
-        // get model names
887
-        $this->_parse_model_names();
888
-        //load caf stuff a chance to play during the activation process too.
889
-        $this->_maybe_brew_regular();
890
-        // configure custom post type definitions
891
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
892
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
893
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
894
-    }
895
-
896
-
897
-
898
-    /**
899
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
900
-     *
901
-     * @return void
902
-     * @throws ReflectionException
903
-     */
904
-    private function _parse_model_names()
905
-    {
906
-        //get all the files in the EE_MODELS folder that end in .model.php
907
-        $models                 = glob(EE_MODELS . '*.model.php');
908
-        $model_names            = array();
909
-        $non_abstract_db_models = array();
910
-        foreach ($models as $model) {
911
-            // get model classname
912
-            $classname       = EEH_File::get_classname_from_filepath_with_standard_filename($model);
913
-            $short_name      = str_replace('EEM_', '', $classname);
914
-            $reflectionClass = new ReflectionClass($classname);
915
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
916
-                $non_abstract_db_models[ $short_name ] = $classname;
917
-            }
918
-            $model_names[ $short_name ] = $classname;
919
-        }
920
-        $this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
921
-        $this->registry->non_abstract_db_models = apply_filters(
922
-            'FHEE__EE_System__parse_implemented_model_names',
923
-            $non_abstract_db_models
924
-        );
925
-    }
926
-
927
-
928
-    /**
929
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
930
-     * that need to be setup before our EE_System launches.
931
-     *
932
-     * @return void
933
-     * @throws DomainException
934
-     * @throws InvalidArgumentException
935
-     * @throws InvalidDataTypeException
936
-     * @throws InvalidInterfaceException
937
-     * @throws InvalidClassException
938
-     * @throws InvalidFilePathException
939
-     */
940
-    private function _maybe_brew_regular()
941
-    {
942
-        /** @var Domain $domain */
943
-        $domain = DomainFactory::getShared(
944
-            new FullyQualifiedName(
945
-                'EventEspresso\core\domain\Domain'
946
-            ),
947
-            array(
948
-                new FilePath(EVENT_ESPRESSO_MAIN_FILE),
949
-                Version::fromString(espresso_version())
950
-            )
951
-        );
952
-        if ($domain->isCaffeinated()) {
953
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
954
-        }
955
-    }
956
-
957
-
958
-
959
-    /**
960
-     * register_shortcodes_modules_and_widgets
961
-     * generate lists of shortcodes and modules, then verify paths and classes
962
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
963
-     * which runs during the WP 'plugins_loaded' action at priority 7
964
-     *
965
-     * @access public
966
-     * @return void
967
-     * @throws Exception
968
-     */
969
-    public function register_shortcodes_modules_and_widgets()
970
-    {
971
-        try {
972
-            // load, register, and add shortcodes the new way
973
-            if ($this->request->isFrontend() || $this->request->isIframe()) {
974
-                $this->loader->getShared(
975
-                    'EventEspresso\core\services\shortcodes\ShortcodesManager',
976
-                    array(
977
-                        // and the old way, but we'll put it under control of the new system
978
-                        EE_Config::getLegacyShortcodesManager(),
979
-                    )
980
-                );
981
-            }
982
-            if (function_exists('register_block_type')) {
983
-                $editor_block_collection = $this->loader->getShared(
984
-                    'EventEspresso\core\domain\entities\editor\EditorBlockCollection'
985
-                );
986
-                // or the even newer newer new way
987
-                if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAdmin()) {
988
-                    $this->loader->getShared(
989
-                        'EventEspresso\core\services\editor\EditorBlockRegistrationManager',
990
-                        array($editor_block_collection, $this->request)
991
-                    );
992
-                }
993
-            }
994
-        } catch (Exception $exception) {
995
-            new ExceptionStackTraceDisplay($exception);
996
-        }
997
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
998
-        // check for addons using old hook point
999
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
1000
-            $this->_incompatible_addon_error();
1001
-        }
1002
-    }
1003
-
1004
-
1005
-
1006
-    /**
1007
-     * _incompatible_addon_error
1008
-     *
1009
-     * @access public
1010
-     * @return void
1011
-     */
1012
-    private function _incompatible_addon_error()
1013
-    {
1014
-        // get array of classes hooking into here
1015
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
1016
-            'AHEE__EE_System__register_shortcodes_modules_and_addons'
1017
-        );
1018
-        if (! empty($class_names)) {
1019
-            $msg = __(
1020
-                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1021
-                'event_espresso'
1022
-            );
1023
-            $msg .= '<ul>';
1024
-            foreach ($class_names as $class_name) {
1025
-                $msg .= '<li><b>Event Espresso - ' . str_replace(
1026
-                        array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
1027
-                        $class_name
1028
-                    ) . '</b></li>';
1029
-            }
1030
-            $msg .= '</ul>';
1031
-            $msg .= __(
1032
-                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1033
-                'event_espresso'
1034
-            );
1035
-            // save list of incompatible addons to wp-options for later use
1036
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
1037
-            if (is_admin()) {
1038
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1039
-            }
1040
-        }
1041
-    }
1042
-
1043
-
1044
-
1045
-    /**
1046
-     * brew_espresso
1047
-     * begins the process of setting hooks for initializing EE in the correct order
1048
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1049
-     * which runs during the WP 'plugins_loaded' action at priority 9
1050
-     *
1051
-     * @return void
1052
-     */
1053
-    public function brew_espresso()
1054
-    {
1055
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
1056
-        // load some final core systems
1057
-        add_action('init', array($this, 'set_hooks_for_core'), 1);
1058
-        add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1059
-        add_action('init', array($this, 'load_CPTs_and_session'), 5);
1060
-        add_action('init', array($this, 'load_controllers'), 7);
1061
-        add_action('init', array($this, 'core_loaded_and_ready'), 9);
1062
-        add_action('init', array($this, 'initialize'), 10);
1063
-        add_action('init', array($this, 'initialize_last'), 100);
1064
-        if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1065
-            // pew pew pew
1066
-            $this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1067
-            do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1068
-        }
1069
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
1070
-    }
1071
-
1072
-
1073
-
1074
-    /**
1075
-     *    set_hooks_for_core
1076
-     *
1077
-     * @access public
1078
-     * @return    void
1079
-     * @throws EE_Error
1080
-     */
1081
-    public function set_hooks_for_core()
1082
-    {
1083
-        $this->_deactivate_incompatible_addons();
1084
-        do_action('AHEE__EE_System__set_hooks_for_core');
1085
-        $this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1086
-        //caps need to be initialized on every request so that capability maps are set.
1087
-        //@see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1088
-        $this->registry->CAP->init_caps();
1089
-    }
1090
-
1091
-
1092
-
1093
-    /**
1094
-     * Using the information gathered in EE_System::_incompatible_addon_error,
1095
-     * deactivates any addons considered incompatible with the current version of EE
1096
-     */
1097
-    private function _deactivate_incompatible_addons()
1098
-    {
1099
-        $incompatible_addons = get_option('ee_incompatible_addons', array());
1100
-        if (! empty($incompatible_addons)) {
1101
-            $active_plugins = get_option('active_plugins', array());
1102
-            foreach ($active_plugins as $active_plugin) {
1103
-                foreach ($incompatible_addons as $incompatible_addon) {
1104
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
1105
-                        unset($_GET['activate']);
1106
-                        espresso_deactivate_plugin($active_plugin);
1107
-                    }
1108
-                }
1109
-            }
1110
-        }
1111
-    }
1112
-
1113
-
1114
-
1115
-    /**
1116
-     *    perform_activations_upgrades_and_migrations
1117
-     *
1118
-     * @access public
1119
-     * @return    void
1120
-     */
1121
-    public function perform_activations_upgrades_and_migrations()
1122
-    {
1123
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1124
-    }
1125
-
1126
-
1127
-    /**
1128
-     * @return void
1129
-     * @throws DomainException
1130
-     */
1131
-    public function load_CPTs_and_session()
1132
-    {
1133
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1134
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1135
-        $register_custom_taxonomies = $this->loader->getShared(
1136
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1137
-        );
1138
-        $register_custom_taxonomies->registerCustomTaxonomies();
1139
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1140
-        $register_custom_post_types = $this->loader->getShared(
1141
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1142
-        );
1143
-        $register_custom_post_types->registerCustomPostTypes();
1144
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1145
-        $register_custom_taxonomy_terms = $this->loader->getShared(
1146
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1147
-        );
1148
-        $register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1149
-        // load legacy Custom Post Types and Taxonomies
1150
-        $this->loader->getShared('EE_Register_CPTs');
1151
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1152
-    }
1153
-
1154
-
1155
-
1156
-    /**
1157
-     * load_controllers
1158
-     * this is the best place to load any additional controllers that needs access to EE core.
1159
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1160
-     * time
1161
-     *
1162
-     * @access public
1163
-     * @return void
1164
-     */
1165
-    public function load_controllers()
1166
-    {
1167
-        do_action('AHEE__EE_System__load_controllers__start');
1168
-        // let's get it started
1169
-        if (
1170
-            ! $this->maintenance_mode->level()
1171
-            && ($this->request->isFrontend() || $this->request->isFrontAjax())
1172
-        ) {
1173
-            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1174
-            $this->loader->getShared('EE_Front_Controller');
1175
-        } elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1176
-            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1177
-            $this->loader->getShared('EE_Admin');
1178
-        }
1179
-        do_action('AHEE__EE_System__load_controllers__complete');
1180
-    }
1181
-
1182
-
1183
-
1184
-    /**
1185
-     * core_loaded_and_ready
1186
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1187
-     *
1188
-     * @access public
1189
-     * @return void
1190
-     */
1191
-    public function core_loaded_and_ready()
1192
-    {
1193
-        if (
1194
-            $this->request->isAdmin()
1195
-            || $this->request->isEeAjax()
1196
-            || $this->request->isFrontend()
1197
-        ) {
1198
-            $this->loader->getShared('EE_Session');
1199
-        }
1200
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1201
-        // load_espresso_template_tags
1202
-        if (
1203
-            is_readable(EE_PUBLIC . 'template_tags.php')
1204
-            && (
1205
-                $this->request->isFrontend()
1206
-                || $this->request->isAdmin()
1207
-                || $this->request->isIframe()
1208
-                || $this->request->isFeed()
1209
-            )
1210
-        ) {
1211
-            require_once EE_PUBLIC . 'template_tags.php';
1212
-        }
1213
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1214
-        if ($this->request->isAdmin() || $this->request->isFrontend() || $this->request->isIframe()) {
1215
-            $this->loader->getShared('EventEspresso\core\services\assets\Registry');
1216
-        }
1217
-    }
1218
-
1219
-
1220
-
1221
-    /**
1222
-     * initialize
1223
-     * this is the best place to begin initializing client code
1224
-     *
1225
-     * @access public
1226
-     * @return void
1227
-     */
1228
-    public function initialize()
1229
-    {
1230
-        do_action('AHEE__EE_System__initialize');
1231
-    }
1232
-
1233
-
1234
-
1235
-    /**
1236
-     * initialize_last
1237
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1238
-     * initialize has done so
1239
-     *
1240
-     * @access public
1241
-     * @return void
1242
-     */
1243
-    public function initialize_last()
1244
-    {
1245
-        do_action('AHEE__EE_System__initialize_last');
1246
-        /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1247
-        $rewrite_rules = $this->loader->getShared(
1248
-            'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1249
-        );
1250
-        $rewrite_rules->flushRewriteRules();
1251
-        add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1252
-    }
1253
-
1254
-
1255
-
1256
-    /**
1257
-     * @return void
1258
-     * @throws EE_Error
1259
-     */
1260
-    public function addEspressoToolbar()
1261
-    {
1262
-        $this->loader->getShared(
1263
-            'EventEspresso\core\domain\services\admin\AdminToolBar',
1264
-            array($this->registry->CAP)
1265
-        );
1266
-    }
1267
-
1268
-
1269
-
1270
-    /**
1271
-     * do_not_cache
1272
-     * sets no cache headers and defines no cache constants for WP plugins
1273
-     *
1274
-     * @access public
1275
-     * @return void
1276
-     */
1277
-    public static function do_not_cache()
1278
-    {
1279
-        // set no cache constants
1280
-        if (! defined('DONOTCACHEPAGE')) {
1281
-            define('DONOTCACHEPAGE', true);
1282
-        }
1283
-        if (! defined('DONOTCACHCEOBJECT')) {
1284
-            define('DONOTCACHCEOBJECT', true);
1285
-        }
1286
-        if (! defined('DONOTCACHEDB')) {
1287
-            define('DONOTCACHEDB', true);
1288
-        }
1289
-        // add no cache headers
1290
-        add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1291
-        // plus a little extra for nginx and Google Chrome
1292
-        add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1293
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1294
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1295
-    }
1296
-
1297
-
1298
-
1299
-    /**
1300
-     *    extra_nocache_headers
1301
-     *
1302
-     * @access    public
1303
-     * @param $headers
1304
-     * @return    array
1305
-     */
1306
-    public static function extra_nocache_headers($headers)
1307
-    {
1308
-        // for NGINX
1309
-        $headers['X-Accel-Expires'] = 0;
1310
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1311
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1312
-        return $headers;
1313
-    }
1314
-
1315
-
1316
-
1317
-    /**
1318
-     *    nocache_headers
1319
-     *
1320
-     * @access    public
1321
-     * @return    void
1322
-     */
1323
-    public static function nocache_headers()
1324
-    {
1325
-        nocache_headers();
1326
-    }
1327
-
1328
-
1329
-
1330
-    /**
1331
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1332
-     * never returned with the function.
1333
-     *
1334
-     * @param  array $exclude_array any existing pages being excluded are in this array.
1335
-     * @return array
1336
-     */
1337
-    public function remove_pages_from_wp_list_pages($exclude_array)
1338
-    {
1339
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1340
-    }
35
+	/**
36
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
37
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
38
+	 */
39
+	const req_type_normal = 0;
40
+
41
+	/**
42
+	 * Indicates this is a brand new installation of EE so we should install
43
+	 * tables and default data etc
44
+	 */
45
+	const req_type_new_activation = 1;
46
+
47
+	/**
48
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
49
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
50
+	 * and that default data is setup too
51
+	 */
52
+	const req_type_reactivation = 2;
53
+
54
+	/**
55
+	 * indicates that EE has been upgraded since its previous request.
56
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
57
+	 */
58
+	const req_type_upgrade = 3;
59
+
60
+	/**
61
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
62
+	 */
63
+	const req_type_downgrade = 4;
64
+
65
+	/**
66
+	 * @deprecated since version 4.6.0.dev.006
67
+	 * Now whenever a new_activation is detected the request type is still just
68
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
69
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
70
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
71
+	 * (Specifically, when the migration manager indicates migrations are finished
72
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
73
+	 */
74
+	const req_type_activation_but_not_installed = 5;
75
+
76
+	/**
77
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
78
+	 */
79
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
80
+
81
+
82
+	/**
83
+	 * @var EE_System $_instance
84
+	 */
85
+	private static $_instance;
86
+
87
+	/**
88
+	 * @var EE_Registry $registry
89
+	 */
90
+	private $registry;
91
+
92
+	/**
93
+	 * @var LoaderInterface $loader
94
+	 */
95
+	private $loader;
96
+
97
+	/**
98
+	 * @var EE_Capabilities $capabilities
99
+	 */
100
+	private $capabilities;
101
+
102
+	/**
103
+	 * @var RequestInterface $request
104
+	 */
105
+	private $request;
106
+
107
+	/**
108
+	 * @var EE_Maintenance_Mode $maintenance_mode
109
+	 */
110
+	private $maintenance_mode;
111
+
112
+	/**
113
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
114
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
115
+	 *
116
+	 * @var int $_req_type
117
+	 */
118
+	private $_req_type;
119
+
120
+	/**
121
+	 * Whether or not there was a non-micro version change in EE core version during this request
122
+	 *
123
+	 * @var boolean $_major_version_change
124
+	 */
125
+	private $_major_version_change = false;
126
+
127
+	/**
128
+	 * A Context DTO dedicated solely to identifying the current request type.
129
+	 *
130
+	 * @var RequestTypeContextCheckerInterface $request_type
131
+	 */
132
+	private $request_type;
133
+
134
+
135
+
136
+	/**
137
+	 * @singleton method used to instantiate class object
138
+	 * @param EE_Registry|null         $registry
139
+	 * @param LoaderInterface|null     $loader
140
+	 * @param RequestInterface|null          $request
141
+	 * @param EE_Maintenance_Mode|null $maintenance_mode
142
+	 * @return EE_System
143
+	 */
144
+	public static function instance(
145
+		EE_Registry $registry = null,
146
+		LoaderInterface $loader = null,
147
+		RequestInterface $request = null,
148
+		EE_Maintenance_Mode $maintenance_mode = null
149
+	) {
150
+		// check if class object is instantiated
151
+		if (! self::$_instance instanceof EE_System) {
152
+			self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
153
+		}
154
+		return self::$_instance;
155
+	}
156
+
157
+
158
+
159
+	/**
160
+	 * resets the instance and returns it
161
+	 *
162
+	 * @return EE_System
163
+	 */
164
+	public static function reset()
165
+	{
166
+		self::$_instance->_req_type = null;
167
+		//make sure none of the old hooks are left hanging around
168
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
169
+		//we need to reset the migration manager in order for it to detect DMSs properly
170
+		EE_Data_Migration_Manager::reset();
171
+		self::instance()->detect_activations_or_upgrades();
172
+		self::instance()->perform_activations_upgrades_and_migrations();
173
+		return self::instance();
174
+	}
175
+
176
+
177
+
178
+	/**
179
+	 * sets hooks for running rest of system
180
+	 * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
181
+	 * starting EE Addons from any other point may lead to problems
182
+	 *
183
+	 * @param EE_Registry         $registry
184
+	 * @param LoaderInterface     $loader
185
+	 * @param RequestInterface          $request
186
+	 * @param EE_Maintenance_Mode $maintenance_mode
187
+	 */
188
+	private function __construct(
189
+		EE_Registry $registry,
190
+		LoaderInterface $loader,
191
+		RequestInterface $request,
192
+		EE_Maintenance_Mode $maintenance_mode
193
+	) {
194
+		$this->registry         = $registry;
195
+		$this->loader           = $loader;
196
+		$this->request          = $request;
197
+		$this->maintenance_mode = $maintenance_mode;
198
+		do_action('AHEE__EE_System__construct__begin', $this);
199
+		add_action(
200
+			'AHEE__EE_Bootstrap__load_espresso_addons',
201
+			array($this, 'loadCapabilities'),
202
+			5
203
+		);
204
+		add_action(
205
+			'AHEE__EE_Bootstrap__load_espresso_addons',
206
+			array($this, 'loadCommandBus'),
207
+			7
208
+		);
209
+		add_action(
210
+			'AHEE__EE_Bootstrap__load_espresso_addons',
211
+			array($this, 'loadPluginApi'),
212
+			9
213
+		);
214
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
215
+		add_action(
216
+			'AHEE__EE_Bootstrap__load_espresso_addons',
217
+			array($this, 'load_espresso_addons')
218
+		);
219
+		// when an ee addon is activated, we want to call the core hook(s) again
220
+		// because the newly-activated addon didn't get a chance to run at all
221
+		add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
222
+		// detect whether install or upgrade
223
+		add_action(
224
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
225
+			array($this, 'detect_activations_or_upgrades'),
226
+			3
227
+		);
228
+		// load EE_Config, EE_Textdomain, etc
229
+		add_action(
230
+			'AHEE__EE_Bootstrap__load_core_configuration',
231
+			array($this, 'load_core_configuration'),
232
+			5
233
+		);
234
+		// load EE_Config, EE_Textdomain, etc
235
+		add_action(
236
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
237
+			array($this, 'register_shortcodes_modules_and_widgets'),
238
+			7
239
+		);
240
+		// you wanna get going? I wanna get going... let's get going!
241
+		add_action(
242
+			'AHEE__EE_Bootstrap__brew_espresso',
243
+			array($this, 'brew_espresso'),
244
+			9
245
+		);
246
+		//other housekeeping
247
+		//exclude EE critical pages from wp_list_pages
248
+		add_filter(
249
+			'wp_list_pages_excludes',
250
+			array($this, 'remove_pages_from_wp_list_pages'),
251
+			10
252
+		);
253
+		// ALL EE Addons should use the following hook point to attach their initial setup too
254
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
255
+		do_action('AHEE__EE_System__construct__complete', $this);
256
+	}
257
+
258
+
259
+	/**
260
+	 * load and setup EE_Capabilities
261
+	 *
262
+	 * @return void
263
+	 * @throws EE_Error
264
+	 */
265
+	public function loadCapabilities()
266
+	{
267
+		$this->capabilities = $this->loader->getShared('EE_Capabilities');
268
+		add_action(
269
+			'AHEE__EE_Capabilities__init_caps__before_initialization',
270
+			function ()
271
+			{
272
+				LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
273
+			}
274
+		);
275
+	}
276
+
277
+
278
+
279
+	/**
280
+	 * create and cache the CommandBus, and also add middleware
281
+	 * The CapChecker middleware requires the use of EE_Capabilities
282
+	 * which is why we need to load the CommandBus after Caps are set up
283
+	 *
284
+	 * @return void
285
+	 * @throws EE_Error
286
+	 */
287
+	public function loadCommandBus()
288
+	{
289
+		$this->loader->getShared(
290
+			'CommandBusInterface',
291
+			array(
292
+				null,
293
+				apply_filters(
294
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
295
+					array(
296
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
297
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
298
+					)
299
+				),
300
+			)
301
+		);
302
+	}
303
+
304
+
305
+
306
+	/**
307
+	 * @return void
308
+	 * @throws EE_Error
309
+	 */
310
+	public function loadPluginApi()
311
+	{
312
+		// set autoloaders for all of the classes implementing EEI_Plugin_API
313
+		// which provide helpers for EE plugin authors to more easily register certain components with EE.
314
+		EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
315
+		$this->loader->getShared('EE_Request_Handler');
316
+	}
317
+
318
+
319
+	/**
320
+	 * @param string $addon_name
321
+	 * @param string $version_constant
322
+	 * @param string $min_version_required
323
+	 * @param string $load_callback
324
+	 * @param string $plugin_file_constant
325
+	 * @return void
326
+	 */
327
+	private function deactivateIncompatibleAddon(
328
+		$addon_name,
329
+		$version_constant,
330
+		$min_version_required,
331
+		$load_callback,
332
+		$plugin_file_constant
333
+	) {
334
+		if (! defined($version_constant)) {
335
+			return;
336
+		}
337
+		$addon_version = constant($version_constant);
338
+		if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
339
+			remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
340
+			if (! function_exists('deactivate_plugins')) {
341
+				require_once ABSPATH . 'wp-admin/includes/plugin.php';
342
+			}
343
+			deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
344
+			unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
345
+			EE_Error::add_error(
346
+				sprintf(
347
+					esc_html__(
348
+						'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
349
+						'event_espresso'
350
+					),
351
+					$addon_name,
352
+					$min_version_required
353
+				),
354
+				__FILE__, __FUNCTION__ . "({$addon_name})", __LINE__
355
+			);
356
+			EE_Error::get_notices(false, true);
357
+		}
358
+	}
359
+
360
+
361
+	/**
362
+	 * load_espresso_addons
363
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
364
+	 * this is hooked into both:
365
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
366
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
367
+	 *    and the WP 'activate_plugin' hook point
368
+	 *
369
+	 * @access public
370
+	 * @return void
371
+	 */
372
+	public function load_espresso_addons()
373
+	{
374
+		$this->deactivateIncompatibleAddon(
375
+			'Wait Lists',
376
+			'EE_WAIT_LISTS_VERSION',
377
+			'1.0.0.beta.074',
378
+			'load_espresso_wait_lists',
379
+			'EE_WAIT_LISTS_PLUGIN_FILE'
380
+		);
381
+		$this->deactivateIncompatibleAddon(
382
+			'Automated Upcoming Event Notifications',
383
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
384
+			'1.0.0.beta.091',
385
+			'load_espresso_automated_upcoming_event_notification',
386
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
387
+		);
388
+		do_action('AHEE__EE_System__load_espresso_addons');
389
+		//if the WP API basic auth plugin isn't already loaded, load it now.
390
+		//We want it for mobile apps. Just include the entire plugin
391
+		//also, don't load the basic auth when a plugin is getting activated, because
392
+		//it could be the basic auth plugin, and it doesn't check if its methods are already defined
393
+		//and causes a fatal error
394
+		if (
395
+			$this->request->getRequestParam('activate') !== 'true'
396
+			&& ! function_exists('json_basic_auth_handler')
397
+			&& ! function_exists('json_basic_auth_error')
398
+			&& ! in_array(
399
+				$this->request->getRequestParam('action'),
400
+				array('activate', 'activate-selected'),
401
+				true
402
+			)
403
+		) {
404
+			include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
405
+		}
406
+		do_action('AHEE__EE_System__load_espresso_addons__complete');
407
+	}
408
+
409
+
410
+
411
+	/**
412
+	 * detect_activations_or_upgrades
413
+	 * Checks for activation or upgrade of core first;
414
+	 * then also checks if any registered addons have been activated or upgraded
415
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
416
+	 * which runs during the WP 'plugins_loaded' action at priority 3
417
+	 *
418
+	 * @access public
419
+	 * @return void
420
+	 */
421
+	public function detect_activations_or_upgrades()
422
+	{
423
+		//first off: let's make sure to handle core
424
+		$this->detect_if_activation_or_upgrade();
425
+		foreach ($this->registry->addons as $addon) {
426
+			if ($addon instanceof EE_Addon) {
427
+				//detect teh request type for that addon
428
+				$addon->detect_activation_or_upgrade();
429
+			}
430
+		}
431
+	}
432
+
433
+
434
+
435
+	/**
436
+	 * detect_if_activation_or_upgrade
437
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
438
+	 * and either setting up the DB or setting up maintenance mode etc.
439
+	 *
440
+	 * @access public
441
+	 * @return void
442
+	 */
443
+	public function detect_if_activation_or_upgrade()
444
+	{
445
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
446
+		// check if db has been updated, or if its a brand-new installation
447
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
448
+		$request_type       = $this->detect_req_type($espresso_db_update);
449
+		//EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
450
+		switch ($request_type) {
451
+			case EE_System::req_type_new_activation:
452
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
453
+				$this->_handle_core_version_change($espresso_db_update);
454
+				break;
455
+			case EE_System::req_type_reactivation:
456
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
457
+				$this->_handle_core_version_change($espresso_db_update);
458
+				break;
459
+			case EE_System::req_type_upgrade:
460
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
461
+				//migrations may be required now that we've upgraded
462
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
463
+				$this->_handle_core_version_change($espresso_db_update);
464
+				//				echo "done upgrade";die;
465
+				break;
466
+			case EE_System::req_type_downgrade:
467
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
468
+				//its possible migrations are no longer required
469
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
470
+				$this->_handle_core_version_change($espresso_db_update);
471
+				break;
472
+			case EE_System::req_type_normal:
473
+			default:
474
+				break;
475
+		}
476
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
477
+	}
478
+
479
+
480
+
481
+	/**
482
+	 * Updates the list of installed versions and sets hooks for
483
+	 * initializing the database later during the request
484
+	 *
485
+	 * @param array $espresso_db_update
486
+	 */
487
+	private function _handle_core_version_change($espresso_db_update)
488
+	{
489
+		$this->update_list_of_installed_versions($espresso_db_update);
490
+		//get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
491
+		add_action(
492
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
493
+			array($this, 'initialize_db_if_no_migrations_required')
494
+		);
495
+	}
496
+
497
+
498
+
499
+	/**
500
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
501
+	 * information about what versions of EE have been installed and activated,
502
+	 * NOT necessarily the state of the database
503
+	 *
504
+	 * @param mixed $espresso_db_update           the value of the WordPress option.
505
+	 *                                            If not supplied, fetches it from the options table
506
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
507
+	 */
508
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null)
509
+	{
510
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
511
+		if (! $espresso_db_update) {
512
+			$espresso_db_update = get_option('espresso_db_update');
513
+		}
514
+		// check that option is an array
515
+		if (! is_array($espresso_db_update)) {
516
+			// if option is FALSE, then it never existed
517
+			if ($espresso_db_update === false) {
518
+				// make $espresso_db_update an array and save option with autoload OFF
519
+				$espresso_db_update = array();
520
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
521
+			} else {
522
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
523
+				$espresso_db_update = array($espresso_db_update => array());
524
+				update_option('espresso_db_update', $espresso_db_update);
525
+			}
526
+		} else {
527
+			$corrected_db_update = array();
528
+			//if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
529
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
530
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
531
+					//the key is an int, and the value IS NOT an array
532
+					//so it must be numerically-indexed, where values are versions installed...
533
+					//fix it!
534
+					$version_string                         = $should_be_array;
535
+					$corrected_db_update[ $version_string ] = array('unknown-date');
536
+				} else {
537
+					//ok it checks out
538
+					$corrected_db_update[ $should_be_version_string ] = $should_be_array;
539
+				}
540
+			}
541
+			$espresso_db_update = $corrected_db_update;
542
+			update_option('espresso_db_update', $espresso_db_update);
543
+		}
544
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
545
+		return $espresso_db_update;
546
+	}
547
+
548
+
549
+
550
+	/**
551
+	 * Does the traditional work of setting up the plugin's database and adding default data.
552
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
553
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
554
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
555
+	 * so that it will be done when migrations are finished
556
+	 *
557
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
558
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
559
+	 *                                       This is a resource-intensive job
560
+	 *                                       so we prefer to only do it when necessary
561
+	 * @return void
562
+	 * @throws EE_Error
563
+	 */
564
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
565
+	{
566
+		$request_type = $this->detect_req_type();
567
+		//only initialize system if we're not in maintenance mode.
568
+		if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
569
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
570
+			$rewrite_rules = $this->loader->getShared(
571
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
572
+			);
573
+			$rewrite_rules->flush();
574
+			if ($verify_schema) {
575
+				EEH_Activation::initialize_db_and_folders();
576
+			}
577
+			EEH_Activation::initialize_db_content();
578
+			EEH_Activation::system_initialization();
579
+			if ($initialize_addons_too) {
580
+				$this->initialize_addons();
581
+			}
582
+		} else {
583
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
584
+		}
585
+		if ($request_type === EE_System::req_type_new_activation
586
+			|| $request_type === EE_System::req_type_reactivation
587
+			|| (
588
+				$request_type === EE_System::req_type_upgrade
589
+				&& $this->is_major_version_change()
590
+			)
591
+		) {
592
+			add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
593
+		}
594
+	}
595
+
596
+
597
+
598
+	/**
599
+	 * Initializes the db for all registered addons
600
+	 *
601
+	 * @throws EE_Error
602
+	 */
603
+	public function initialize_addons()
604
+	{
605
+		//foreach registered addon, make sure its db is up-to-date too
606
+		foreach ($this->registry->addons as $addon) {
607
+			if ($addon instanceof EE_Addon) {
608
+				$addon->initialize_db_if_no_migrations_required();
609
+			}
610
+		}
611
+	}
612
+
613
+
614
+
615
+	/**
616
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
617
+	 *
618
+	 * @param    array  $version_history
619
+	 * @param    string $current_version_to_add version to be added to the version history
620
+	 * @return    boolean success as to whether or not this option was changed
621
+	 */
622
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
623
+	{
624
+		if (! $version_history) {
625
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
626
+		}
627
+		if ($current_version_to_add === null) {
628
+			$current_version_to_add = espresso_version();
629
+		}
630
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
631
+		// re-save
632
+		return update_option('espresso_db_update', $version_history);
633
+	}
634
+
635
+
636
+
637
+	/**
638
+	 * Detects if the current version indicated in the has existed in the list of
639
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
640
+	 *
641
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
642
+	 *                                  If not supplied, fetches it from the options table.
643
+	 *                                  Also, caches its result so later parts of the code can also know whether
644
+	 *                                  there's been an update or not. This way we can add the current version to
645
+	 *                                  espresso_db_update, but still know if this is a new install or not
646
+	 * @return int one of the constants on EE_System::req_type_
647
+	 */
648
+	public function detect_req_type($espresso_db_update = null)
649
+	{
650
+		if ($this->_req_type === null) {
651
+			$espresso_db_update          = ! empty($espresso_db_update)
652
+				? $espresso_db_update
653
+				: $this->fix_espresso_db_upgrade_option();
654
+			$this->_req_type             = EE_System::detect_req_type_given_activation_history(
655
+				$espresso_db_update,
656
+				'ee_espresso_activation', espresso_version()
657
+			);
658
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
659
+			$this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
660
+		}
661
+		return $this->_req_type;
662
+	}
663
+
664
+
665
+
666
+	/**
667
+	 * Returns whether or not there was a non-micro version change (ie, change in either
668
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
669
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
670
+	 *
671
+	 * @param $activation_history
672
+	 * @return bool
673
+	 */
674
+	private function _detect_major_version_change($activation_history)
675
+	{
676
+		$previous_version       = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
677
+		$previous_version_parts = explode('.', $previous_version);
678
+		$current_version_parts  = explode('.', espresso_version());
679
+		return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
680
+			   && ($previous_version_parts[0] !== $current_version_parts[0]
681
+				   || $previous_version_parts[1] !== $current_version_parts[1]
682
+			   );
683
+	}
684
+
685
+
686
+
687
+	/**
688
+	 * Returns true if either the major or minor version of EE changed during this request.
689
+	 * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
690
+	 *
691
+	 * @return bool
692
+	 */
693
+	public function is_major_version_change()
694
+	{
695
+		return $this->_major_version_change;
696
+	}
697
+
698
+
699
+
700
+	/**
701
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
702
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
703
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
704
+	 * just activated to (for core that will always be espresso_version())
705
+	 *
706
+	 * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
707
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
708
+	 * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
709
+	 *                                                 indicate that this plugin was just activated
710
+	 * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
711
+	 *                                                 espresso_version())
712
+	 * @return int one of the constants on EE_System::req_type_*
713
+	 */
714
+	public static function detect_req_type_given_activation_history(
715
+		$activation_history_for_addon,
716
+		$activation_indicator_option_name,
717
+		$version_to_upgrade_to
718
+	) {
719
+		$version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
720
+		if ($activation_history_for_addon) {
721
+			//it exists, so this isn't a completely new install
722
+			//check if this version already in that list of previously installed versions
723
+			if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
724
+				//it a version we haven't seen before
725
+				if ($version_is_higher === 1) {
726
+					$req_type = EE_System::req_type_upgrade;
727
+				} else {
728
+					$req_type = EE_System::req_type_downgrade;
729
+				}
730
+				delete_option($activation_indicator_option_name);
731
+			} else {
732
+				// its not an update. maybe a reactivation?
733
+				if (get_option($activation_indicator_option_name, false)) {
734
+					if ($version_is_higher === -1) {
735
+						$req_type = EE_System::req_type_downgrade;
736
+					} elseif ($version_is_higher === 0) {
737
+						//we've seen this version before, but it's an activation. must be a reactivation
738
+						$req_type = EE_System::req_type_reactivation;
739
+					} else {//$version_is_higher === 1
740
+						$req_type = EE_System::req_type_upgrade;
741
+					}
742
+					delete_option($activation_indicator_option_name);
743
+				} else {
744
+					//we've seen this version before and the activation indicate doesn't show it was just activated
745
+					if ($version_is_higher === -1) {
746
+						$req_type = EE_System::req_type_downgrade;
747
+					} elseif ($version_is_higher === 0) {
748
+						//we've seen this version before and it's not an activation. its normal request
749
+						$req_type = EE_System::req_type_normal;
750
+					} else {//$version_is_higher === 1
751
+						$req_type = EE_System::req_type_upgrade;
752
+					}
753
+				}
754
+			}
755
+		} else {
756
+			//brand new install
757
+			$req_type = EE_System::req_type_new_activation;
758
+			delete_option($activation_indicator_option_name);
759
+		}
760
+		return $req_type;
761
+	}
762
+
763
+
764
+
765
+	/**
766
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
767
+	 * the $activation_history_for_addon
768
+	 *
769
+	 * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
770
+	 *                                             sometimes containing 'unknown-date'
771
+	 * @param string $version_to_upgrade_to        (current version)
772
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
773
+	 *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
774
+	 *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
775
+	 *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
776
+	 */
777
+	private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
778
+	{
779
+		//find the most recently-activated version
780
+		$most_recently_active_version =
781
+			EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
782
+		return version_compare($version_to_upgrade_to, $most_recently_active_version);
783
+	}
784
+
785
+
786
+
787
+	/**
788
+	 * Gets the most recently active version listed in the activation history,
789
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
790
+	 *
791
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
792
+	 *                                   sometimes containing 'unknown-date'
793
+	 * @return string
794
+	 */
795
+	private static function _get_most_recently_active_version_from_activation_history($activation_history)
796
+	{
797
+		$most_recently_active_version_activation = '1970-01-01 00:00:00';
798
+		$most_recently_active_version            = '0.0.0.dev.000';
799
+		if (is_array($activation_history)) {
800
+			foreach ($activation_history as $version => $times_activated) {
801
+				//check there is a record of when this version was activated. Otherwise,
802
+				//mark it as unknown
803
+				if (! $times_activated) {
804
+					$times_activated = array('unknown-date');
805
+				}
806
+				if (is_string($times_activated)) {
807
+					$times_activated = array($times_activated);
808
+				}
809
+				foreach ($times_activated as $an_activation) {
810
+					if ($an_activation !== 'unknown-date'
811
+						&& $an_activation
812
+						   > $most_recently_active_version_activation) {
813
+						$most_recently_active_version            = $version;
814
+						$most_recently_active_version_activation = $an_activation === 'unknown-date'
815
+							? '1970-01-01 00:00:00'
816
+							: $an_activation;
817
+					}
818
+				}
819
+			}
820
+		}
821
+		return $most_recently_active_version;
822
+	}
823
+
824
+
825
+
826
+	/**
827
+	 * This redirects to the about EE page after activation
828
+	 *
829
+	 * @return void
830
+	 */
831
+	public function redirect_to_about_ee()
832
+	{
833
+		$notices = EE_Error::get_notices(false);
834
+		//if current user is an admin and it's not an ajax or rest request
835
+		if (
836
+			! isset($notices['errors'])
837
+			&& $this->request->isAdmin()
838
+			&& apply_filters(
839
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
840
+				$this->capabilities->current_user_can('manage_options', 'espresso_about_default')
841
+			)
842
+		) {
843
+			$query_params = array('page' => 'espresso_about');
844
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
845
+				$query_params['new_activation'] = true;
846
+			}
847
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
848
+				$query_params['reactivation'] = true;
849
+			}
850
+			$url = add_query_arg($query_params, admin_url('admin.php'));
851
+			wp_safe_redirect($url);
852
+			exit();
853
+		}
854
+	}
855
+
856
+
857
+
858
+	/**
859
+	 * load_core_configuration
860
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
861
+	 * which runs during the WP 'plugins_loaded' action at priority 5
862
+	 *
863
+	 * @return void
864
+	 * @throws ReflectionException
865
+	 */
866
+	public function load_core_configuration()
867
+	{
868
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
869
+		$this->loader->getShared('EE_Load_Textdomain');
870
+		//load textdomain
871
+		EE_Load_Textdomain::load_textdomain();
872
+		// load and setup EE_Config and EE_Network_Config
873
+		$config = $this->loader->getShared('EE_Config');
874
+		$this->loader->getShared('EE_Network_Config');
875
+		// setup autoloaders
876
+		// enable logging?
877
+		if ($config->admin->use_full_logging) {
878
+			$this->loader->getShared('EE_Log');
879
+		}
880
+		// check for activation errors
881
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
882
+		if ($activation_errors) {
883
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
884
+			update_option('ee_plugin_activation_errors', false);
885
+		}
886
+		// get model names
887
+		$this->_parse_model_names();
888
+		//load caf stuff a chance to play during the activation process too.
889
+		$this->_maybe_brew_regular();
890
+		// configure custom post type definitions
891
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
892
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
893
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
894
+	}
895
+
896
+
897
+
898
+	/**
899
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
900
+	 *
901
+	 * @return void
902
+	 * @throws ReflectionException
903
+	 */
904
+	private function _parse_model_names()
905
+	{
906
+		//get all the files in the EE_MODELS folder that end in .model.php
907
+		$models                 = glob(EE_MODELS . '*.model.php');
908
+		$model_names            = array();
909
+		$non_abstract_db_models = array();
910
+		foreach ($models as $model) {
911
+			// get model classname
912
+			$classname       = EEH_File::get_classname_from_filepath_with_standard_filename($model);
913
+			$short_name      = str_replace('EEM_', '', $classname);
914
+			$reflectionClass = new ReflectionClass($classname);
915
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
916
+				$non_abstract_db_models[ $short_name ] = $classname;
917
+			}
918
+			$model_names[ $short_name ] = $classname;
919
+		}
920
+		$this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
921
+		$this->registry->non_abstract_db_models = apply_filters(
922
+			'FHEE__EE_System__parse_implemented_model_names',
923
+			$non_abstract_db_models
924
+		);
925
+	}
926
+
927
+
928
+	/**
929
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
930
+	 * that need to be setup before our EE_System launches.
931
+	 *
932
+	 * @return void
933
+	 * @throws DomainException
934
+	 * @throws InvalidArgumentException
935
+	 * @throws InvalidDataTypeException
936
+	 * @throws InvalidInterfaceException
937
+	 * @throws InvalidClassException
938
+	 * @throws InvalidFilePathException
939
+	 */
940
+	private function _maybe_brew_regular()
941
+	{
942
+		/** @var Domain $domain */
943
+		$domain = DomainFactory::getShared(
944
+			new FullyQualifiedName(
945
+				'EventEspresso\core\domain\Domain'
946
+			),
947
+			array(
948
+				new FilePath(EVENT_ESPRESSO_MAIN_FILE),
949
+				Version::fromString(espresso_version())
950
+			)
951
+		);
952
+		if ($domain->isCaffeinated()) {
953
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
954
+		}
955
+	}
956
+
957
+
958
+
959
+	/**
960
+	 * register_shortcodes_modules_and_widgets
961
+	 * generate lists of shortcodes and modules, then verify paths and classes
962
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
963
+	 * which runs during the WP 'plugins_loaded' action at priority 7
964
+	 *
965
+	 * @access public
966
+	 * @return void
967
+	 * @throws Exception
968
+	 */
969
+	public function register_shortcodes_modules_and_widgets()
970
+	{
971
+		try {
972
+			// load, register, and add shortcodes the new way
973
+			if ($this->request->isFrontend() || $this->request->isIframe()) {
974
+				$this->loader->getShared(
975
+					'EventEspresso\core\services\shortcodes\ShortcodesManager',
976
+					array(
977
+						// and the old way, but we'll put it under control of the new system
978
+						EE_Config::getLegacyShortcodesManager(),
979
+					)
980
+				);
981
+			}
982
+			if (function_exists('register_block_type')) {
983
+				$editor_block_collection = $this->loader->getShared(
984
+					'EventEspresso\core\domain\entities\editor\EditorBlockCollection'
985
+				);
986
+				// or the even newer newer new way
987
+				if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAdmin()) {
988
+					$this->loader->getShared(
989
+						'EventEspresso\core\services\editor\EditorBlockRegistrationManager',
990
+						array($editor_block_collection, $this->request)
991
+					);
992
+				}
993
+			}
994
+		} catch (Exception $exception) {
995
+			new ExceptionStackTraceDisplay($exception);
996
+		}
997
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
998
+		// check for addons using old hook point
999
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
1000
+			$this->_incompatible_addon_error();
1001
+		}
1002
+	}
1003
+
1004
+
1005
+
1006
+	/**
1007
+	 * _incompatible_addon_error
1008
+	 *
1009
+	 * @access public
1010
+	 * @return void
1011
+	 */
1012
+	private function _incompatible_addon_error()
1013
+	{
1014
+		// get array of classes hooking into here
1015
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
1016
+			'AHEE__EE_System__register_shortcodes_modules_and_addons'
1017
+		);
1018
+		if (! empty($class_names)) {
1019
+			$msg = __(
1020
+				'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1021
+				'event_espresso'
1022
+			);
1023
+			$msg .= '<ul>';
1024
+			foreach ($class_names as $class_name) {
1025
+				$msg .= '<li><b>Event Espresso - ' . str_replace(
1026
+						array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
1027
+						$class_name
1028
+					) . '</b></li>';
1029
+			}
1030
+			$msg .= '</ul>';
1031
+			$msg .= __(
1032
+				'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1033
+				'event_espresso'
1034
+			);
1035
+			// save list of incompatible addons to wp-options for later use
1036
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
1037
+			if (is_admin()) {
1038
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1039
+			}
1040
+		}
1041
+	}
1042
+
1043
+
1044
+
1045
+	/**
1046
+	 * brew_espresso
1047
+	 * begins the process of setting hooks for initializing EE in the correct order
1048
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1049
+	 * which runs during the WP 'plugins_loaded' action at priority 9
1050
+	 *
1051
+	 * @return void
1052
+	 */
1053
+	public function brew_espresso()
1054
+	{
1055
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
1056
+		// load some final core systems
1057
+		add_action('init', array($this, 'set_hooks_for_core'), 1);
1058
+		add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1059
+		add_action('init', array($this, 'load_CPTs_and_session'), 5);
1060
+		add_action('init', array($this, 'load_controllers'), 7);
1061
+		add_action('init', array($this, 'core_loaded_and_ready'), 9);
1062
+		add_action('init', array($this, 'initialize'), 10);
1063
+		add_action('init', array($this, 'initialize_last'), 100);
1064
+		if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1065
+			// pew pew pew
1066
+			$this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1067
+			do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1068
+		}
1069
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
1070
+	}
1071
+
1072
+
1073
+
1074
+	/**
1075
+	 *    set_hooks_for_core
1076
+	 *
1077
+	 * @access public
1078
+	 * @return    void
1079
+	 * @throws EE_Error
1080
+	 */
1081
+	public function set_hooks_for_core()
1082
+	{
1083
+		$this->_deactivate_incompatible_addons();
1084
+		do_action('AHEE__EE_System__set_hooks_for_core');
1085
+		$this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1086
+		//caps need to be initialized on every request so that capability maps are set.
1087
+		//@see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1088
+		$this->registry->CAP->init_caps();
1089
+	}
1090
+
1091
+
1092
+
1093
+	/**
1094
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
1095
+	 * deactivates any addons considered incompatible with the current version of EE
1096
+	 */
1097
+	private function _deactivate_incompatible_addons()
1098
+	{
1099
+		$incompatible_addons = get_option('ee_incompatible_addons', array());
1100
+		if (! empty($incompatible_addons)) {
1101
+			$active_plugins = get_option('active_plugins', array());
1102
+			foreach ($active_plugins as $active_plugin) {
1103
+				foreach ($incompatible_addons as $incompatible_addon) {
1104
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
1105
+						unset($_GET['activate']);
1106
+						espresso_deactivate_plugin($active_plugin);
1107
+					}
1108
+				}
1109
+			}
1110
+		}
1111
+	}
1112
+
1113
+
1114
+
1115
+	/**
1116
+	 *    perform_activations_upgrades_and_migrations
1117
+	 *
1118
+	 * @access public
1119
+	 * @return    void
1120
+	 */
1121
+	public function perform_activations_upgrades_and_migrations()
1122
+	{
1123
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1124
+	}
1125
+
1126
+
1127
+	/**
1128
+	 * @return void
1129
+	 * @throws DomainException
1130
+	 */
1131
+	public function load_CPTs_and_session()
1132
+	{
1133
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
1134
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1135
+		$register_custom_taxonomies = $this->loader->getShared(
1136
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1137
+		);
1138
+		$register_custom_taxonomies->registerCustomTaxonomies();
1139
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1140
+		$register_custom_post_types = $this->loader->getShared(
1141
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1142
+		);
1143
+		$register_custom_post_types->registerCustomPostTypes();
1144
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1145
+		$register_custom_taxonomy_terms = $this->loader->getShared(
1146
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1147
+		);
1148
+		$register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1149
+		// load legacy Custom Post Types and Taxonomies
1150
+		$this->loader->getShared('EE_Register_CPTs');
1151
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1152
+	}
1153
+
1154
+
1155
+
1156
+	/**
1157
+	 * load_controllers
1158
+	 * this is the best place to load any additional controllers that needs access to EE core.
1159
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1160
+	 * time
1161
+	 *
1162
+	 * @access public
1163
+	 * @return void
1164
+	 */
1165
+	public function load_controllers()
1166
+	{
1167
+		do_action('AHEE__EE_System__load_controllers__start');
1168
+		// let's get it started
1169
+		if (
1170
+			! $this->maintenance_mode->level()
1171
+			&& ($this->request->isFrontend() || $this->request->isFrontAjax())
1172
+		) {
1173
+			do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1174
+			$this->loader->getShared('EE_Front_Controller');
1175
+		} elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1176
+			do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1177
+			$this->loader->getShared('EE_Admin');
1178
+		}
1179
+		do_action('AHEE__EE_System__load_controllers__complete');
1180
+	}
1181
+
1182
+
1183
+
1184
+	/**
1185
+	 * core_loaded_and_ready
1186
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1187
+	 *
1188
+	 * @access public
1189
+	 * @return void
1190
+	 */
1191
+	public function core_loaded_and_ready()
1192
+	{
1193
+		if (
1194
+			$this->request->isAdmin()
1195
+			|| $this->request->isEeAjax()
1196
+			|| $this->request->isFrontend()
1197
+		) {
1198
+			$this->loader->getShared('EE_Session');
1199
+		}
1200
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1201
+		// load_espresso_template_tags
1202
+		if (
1203
+			is_readable(EE_PUBLIC . 'template_tags.php')
1204
+			&& (
1205
+				$this->request->isFrontend()
1206
+				|| $this->request->isAdmin()
1207
+				|| $this->request->isIframe()
1208
+				|| $this->request->isFeed()
1209
+			)
1210
+		) {
1211
+			require_once EE_PUBLIC . 'template_tags.php';
1212
+		}
1213
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1214
+		if ($this->request->isAdmin() || $this->request->isFrontend() || $this->request->isIframe()) {
1215
+			$this->loader->getShared('EventEspresso\core\services\assets\Registry');
1216
+		}
1217
+	}
1218
+
1219
+
1220
+
1221
+	/**
1222
+	 * initialize
1223
+	 * this is the best place to begin initializing client code
1224
+	 *
1225
+	 * @access public
1226
+	 * @return void
1227
+	 */
1228
+	public function initialize()
1229
+	{
1230
+		do_action('AHEE__EE_System__initialize');
1231
+	}
1232
+
1233
+
1234
+
1235
+	/**
1236
+	 * initialize_last
1237
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1238
+	 * initialize has done so
1239
+	 *
1240
+	 * @access public
1241
+	 * @return void
1242
+	 */
1243
+	public function initialize_last()
1244
+	{
1245
+		do_action('AHEE__EE_System__initialize_last');
1246
+		/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1247
+		$rewrite_rules = $this->loader->getShared(
1248
+			'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1249
+		);
1250
+		$rewrite_rules->flushRewriteRules();
1251
+		add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1252
+	}
1253
+
1254
+
1255
+
1256
+	/**
1257
+	 * @return void
1258
+	 * @throws EE_Error
1259
+	 */
1260
+	public function addEspressoToolbar()
1261
+	{
1262
+		$this->loader->getShared(
1263
+			'EventEspresso\core\domain\services\admin\AdminToolBar',
1264
+			array($this->registry->CAP)
1265
+		);
1266
+	}
1267
+
1268
+
1269
+
1270
+	/**
1271
+	 * do_not_cache
1272
+	 * sets no cache headers and defines no cache constants for WP plugins
1273
+	 *
1274
+	 * @access public
1275
+	 * @return void
1276
+	 */
1277
+	public static function do_not_cache()
1278
+	{
1279
+		// set no cache constants
1280
+		if (! defined('DONOTCACHEPAGE')) {
1281
+			define('DONOTCACHEPAGE', true);
1282
+		}
1283
+		if (! defined('DONOTCACHCEOBJECT')) {
1284
+			define('DONOTCACHCEOBJECT', true);
1285
+		}
1286
+		if (! defined('DONOTCACHEDB')) {
1287
+			define('DONOTCACHEDB', true);
1288
+		}
1289
+		// add no cache headers
1290
+		add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1291
+		// plus a little extra for nginx and Google Chrome
1292
+		add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1293
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1294
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1295
+	}
1296
+
1297
+
1298
+
1299
+	/**
1300
+	 *    extra_nocache_headers
1301
+	 *
1302
+	 * @access    public
1303
+	 * @param $headers
1304
+	 * @return    array
1305
+	 */
1306
+	public static function extra_nocache_headers($headers)
1307
+	{
1308
+		// for NGINX
1309
+		$headers['X-Accel-Expires'] = 0;
1310
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1311
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1312
+		return $headers;
1313
+	}
1314
+
1315
+
1316
+
1317
+	/**
1318
+	 *    nocache_headers
1319
+	 *
1320
+	 * @access    public
1321
+	 * @return    void
1322
+	 */
1323
+	public static function nocache_headers()
1324
+	{
1325
+		nocache_headers();
1326
+	}
1327
+
1328
+
1329
+
1330
+	/**
1331
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1332
+	 * never returned with the function.
1333
+	 *
1334
+	 * @param  array $exclude_array any existing pages being excluded are in this array.
1335
+	 * @return array
1336
+	 */
1337
+	public function remove_pages_from_wp_list_pages($exclude_array)
1338
+	{
1339
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1340
+	}
1341 1341
 
1342 1342
 
1343 1343
 
Please login to merge, or discard this patch.
core/db_models/EEM_Line_Item.model.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -429,7 +429,7 @@
 block discarded – undo
429 429
      * If $expired is set to true, then only line items for expired sessions will be returned.
430 430
      * If $expired is set to false, then only line items for active sessions will be returned.
431 431
      *
432
-     * @param null $expired
432
+     * @param boolean $expired
433 433
      * @return EE_Base_Class[]|EE_Line_Item[]
434 434
      * @throws InvalidInterfaceException
435 435
      * @throws InvalidDataTypeException
Please login to merge, or discard this patch.
Indentation   +438 added lines, -438 removed lines patch added patch discarded remove patch
@@ -47,446 +47,446 @@
 block discarded – undo
47 47
 class EEM_Line_Item extends EEM_Base
48 48
 {
49 49
 
50
-    /**
51
-     * Tax sub-total is just the total of all the taxes, which should be children
52
-     * of this line item. There should only ever be one tax sub-total, and it should
53
-     * be a direct child of. Its quantity and LIN_unit_price = 1.
54
-     */
55
-    const type_tax_sub_total = 'tax-sub-total';
56
-
57
-    /**
58
-     * Tax line items indicate a tax applied to all the taxable line items.
59
-     * Should not have any children line items. Its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal
60
-     * (eg 10% tax = 10, not 0.1). Its LIN_total = LIN_unit_price * pre-tax-total. Quantity = 1.
61
-     */
62
-    const type_tax = 'tax';
63
-
64
-    /**
65
-     * Indicating individual items purchased, or discounts or surcharges.
66
-     * The sum of all the regular line items  plus the tax items should equal
67
-     * the grand total.
68
-     * Possible children are sub-line-items and cancellations.
69
-     * For flat items, LIN_unit_price * LIN_quantity = LIN_total. Its LIN_total is the sum of all the children
70
-     * LIN_totals. Its LIN_percent = 0.
71
-     * For percent items, its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal (eg 10% = 10, not 0.1).
72
-     * Its LIN_total is LIN_percent / 100 * sum of lower-priority sibling line items. Quantity = 1.
73
-     */
74
-    const type_line_item = 'line-item';
75
-
76
-    /**
77
-     * Line item indicating all the factors that make a single line item.
78
-     * Sub-line items should have NO children line items.
79
-     * For flat sub-items, their quantity should match their parent item, their LIN_unit_price should be this sub-item's
80
-     * contribution towards the price of ONE of their parent items, and its LIN_total should be
81
-     *  = LIN_quantity * LIN_unit_price. Its LIN_percent = 0.
82
-     * For percent sub-items, the quantity should be 1, LIN_unit_price should be 0, and its LIN_total should
83
-     * = LIN_percent / 100 * sum of lower-priority sibling line items..
84
-     */
85
-    const type_sub_line_item = 'sub-item';
86
-
87
-    /**
88
-     * Line item indicating a sub-total (eg total for an event, or pre-tax subtotal).
89
-     * Direct children should be event subtotals.
90
-     * Should have quantity of 1, and a LIN_total and LIN_unit_price of the sum of all its sub-items' LIN_totals.
91
-     *
92
-     */
93
-    const type_sub_total = 'sub-total';
94
-
95
-    /**
96
-     * Line item for the grand total of an order. Its direct children
97
-     * should be tax subtotals and (pre-tax) subtotals, and possibly a regular line item
98
-     * indicating a transaction-wide discount/surcharge. Should have a quantity of 1, a LIN_total and LIN_unit_price of
99
-     * the entire order's mount.
100
-     */
101
-    const type_total = 'total';
102
-
103
-    /**
104
-     * When a line item is cancelled, a sub-line-item of type 'cancellation'
105
-     * should be created, indicating the quantity that were cancelled
106
-     * (because a line item could have a quantity of 1, and its cancellation item
107
-     * could be for 3, indicating that originally 4 were purchased, but 3 have been
108
-     * cancelled, and only one remains).
109
-     * When items are refunded, a cancellation line item should be made, which points
110
-     * to teh payment model object which actually refunded the payment.
111
-     * Cancellations should NOT have any children line items; the should NOT affect
112
-     * any calculations, and are only meant as a record that cancellations have occurred.
113
-     * Their LIN_percent should be 0.
114
-     */
115
-    const type_cancellation = 'cancellation';
116
-
117
-    // private instance of the EEM_Line_Item object
118
-    protected static $_instance = NULL;
119
-
120
-
121
-    /**
122
-     *        private constructor to prevent direct creation
123
-     * @Constructor
124
-     * @access protected
125
-     * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any incoming timezone data that gets saved).  Note this just sends the timezone info to the date time model field objects.  Default is NULL (and will be assumed using the set timezone in the 'timezone_string' wp option)
126
-     * @return \EEM_Line_Item
127
-     */
128
-    protected function __construct($timezone)
129
-    {
130
-        $this->singular_item = __('Line Item', 'event_espresso');
131
-        $this->plural_item = __('Line Items', 'event_espresso');
132
-
133
-        $this->_tables = array(
134
-            'Line_Item' => new EE_Primary_Table('esp_line_item', 'LIN_ID')
135
-        );
136
-        $line_items_can_be_for = apply_filters('FHEE__EEM_Line_Item__line_items_can_be_for', array('Ticket', 'Price', 'Event'));
137
-        $this->_fields = array(
138
-            'Line_Item' => array(
139
-                'LIN_ID' => new EE_Primary_Key_Int_Field('LIN_ID', __("ID", "event_espresso")),
140
-                'LIN_code' => new EE_Slug_Field('LIN_code', __("Code for index into Cart", "event_espresso"), TRUE),
141
-                'TXN_ID' => new EE_Foreign_Key_Int_Field('TXN_ID', __("Transaction ID", "event_espresso"), TRUE, NULL, 'Transaction'),
142
-                'LIN_name' => new EE_Full_HTML_Field('LIN_name', __("Line Item Name", "event_espresso"), FALSE, ''),
143
-                'LIN_desc' => new EE_Full_HTML_Field('LIN_desc', __("Line Item Description", "event_espresso"), TRUE),
144
-                'LIN_unit_price' => new EE_Money_Field('LIN_unit_price', __("Unit Price", "event_espresso"), FALSE, 0),
145
-                'LIN_percent' => new EE_Float_Field('LIN_percent', __("Percent", "event_espresso"), FALSE, 0),
146
-                'LIN_is_taxable' => new EE_Boolean_Field('LIN_is_taxable', __("Taxable", "event_espresso"), FALSE, FALSE),
147
-                'LIN_order' => new EE_Integer_Field('LIN_order', __("Order of Application towards total of parent", "event_espresso"), FALSE, 1),
148
-                'LIN_total' => new EE_Money_Field('LIN_total', __("Total (unit price x quantity)", "event_espresso"), FALSE, 0),
149
-                'LIN_quantity' => new EE_Integer_Field('LIN_quantity', __("Quantity", "event_espresso"), TRUE, 1),
150
-                'LIN_parent' => new EE_Integer_Field('LIN_parent', __("Parent ID (this item goes towards that Line Item's total)", "event_espresso"), TRUE, NULL),
151
-                'LIN_type' => new EE_Enum_Text_Field('LIN_type', __("Type", "event_espresso"), FALSE, 'line-item', array(
152
-                        self::type_line_item => __("Line Item", "event_espresso"),
153
-                        self::type_sub_line_item => __("Sub-Item", "event_espresso"),
154
-                        self::type_sub_total => __("Subtotal", "event_espresso"),
155
-                        self::type_tax_sub_total => __("Tax Subtotal", "event_espresso"),
156
-                        self::type_tax => __("Tax", "event_espresso"),
157
-                        self::type_total => __("Total", "event_espresso"),
158
-                        self::type_cancellation => __('Cancellation', 'event_espresso')
159
-                    )
160
-                ),
161
-                'OBJ_ID' => new EE_Foreign_Key_Int_Field('OBJ_ID', __('ID of Item purchased.', 'event_espresso'), TRUE, NULL, $line_items_can_be_for),
162
-                'OBJ_type' => new EE_Any_Foreign_Model_Name_Field('OBJ_type', __("Model Name this Line Item is for", "event_espresso"), TRUE, NULL, $line_items_can_be_for),
163
-                'LIN_timestamp' => new EE_Datetime_Field('LIN_timestamp', __('When the line item was created', 'event_espresso'), false, EE_Datetime_Field::now, $timezone),
164
-            )
165
-        );
166
-        $this->_model_relations = array(
167
-            'Transaction' => new EE_Belongs_To_Relation(),
168
-            'Ticket' => new EE_Belongs_To_Any_Relation(),
169
-            'Price' => new EE_Belongs_To_Any_Relation(),
170
-            'Event' => new EE_Belongs_To_Any_Relation()
171
-        );
172
-        $this->_model_chain_to_wp_user = 'Transaction.Registration.Event';
173
-        $this->_caps_slug = 'transactions';
174
-        parent::__construct($timezone);
175
-    }
176
-
177
-
178
-    /**
179
-     * Gets all the line items for this transaction of the given type
180
-     * @param string $line_item_type like one of EEM_Line_Item::type_*
181
-     * @param EE_Transaction|int $transaction
182
-     * @return EE_Line_Item[]
183
-     */
184
-    public function get_all_of_type_for_transaction($line_item_type, $transaction)
185
-    {
186
-        $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction);
187
-        return $this->get_all(array(array(
188
-            'LIN_type' => $line_item_type,
189
-            'TXN_ID' => $transaction
190
-        )));
191
-    }
192
-
193
-
194
-    /**
195
-     * Gets all line items unrelated to tickets that are normal line items
196
-     * (eg shipping, promotions, and miscellaneous other stuff should probably fit in this category)
197
-     * @param EE_Transaction|int $transaction
198
-     * @return EE_Line_Item[]
199
-     */
200
-    public function get_all_non_ticket_line_items_for_transaction($transaction)
201
-    {
202
-        $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction);
203
-        return $this->get_all(array(array(
204
-            'LIN_type' => self::type_line_item,
205
-            'TXN_ID' => $transaction,
206
-            'OR' => array(
207
-                'OBJ_type*notticket' => array('!=', 'Ticket'),
208
-                'OBJ_type*null' => array('IS_NULL'))
209
-        )));
210
-    }
211
-
212
-    /**
213
-     * Deletes line items with no transaction who have passed the transaction cutoff time.
214
-     * This needs to be very efficient
215
-     * because if there are spam bots afoot there will be LOTS of line items
216
-     * @return int count of how many deleted
217
-     */
218
-    public function delete_line_items_with_no_transaction()
219
-    {
220
-        /** @type WPDB $wpdb */
221
-        global $wpdb;
222
-        $time_to_leave_alone = apply_filters(
223
-            'FHEE__EEM_Line_Item__delete_line_items_with_no_transaction__time_to_leave_alone', WEEK_IN_SECONDS
224
-        );
225
-        $query = $wpdb->prepare(
226
-            'DELETE li
50
+	/**
51
+	 * Tax sub-total is just the total of all the taxes, which should be children
52
+	 * of this line item. There should only ever be one tax sub-total, and it should
53
+	 * be a direct child of. Its quantity and LIN_unit_price = 1.
54
+	 */
55
+	const type_tax_sub_total = 'tax-sub-total';
56
+
57
+	/**
58
+	 * Tax line items indicate a tax applied to all the taxable line items.
59
+	 * Should not have any children line items. Its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal
60
+	 * (eg 10% tax = 10, not 0.1). Its LIN_total = LIN_unit_price * pre-tax-total. Quantity = 1.
61
+	 */
62
+	const type_tax = 'tax';
63
+
64
+	/**
65
+	 * Indicating individual items purchased, or discounts or surcharges.
66
+	 * The sum of all the regular line items  plus the tax items should equal
67
+	 * the grand total.
68
+	 * Possible children are sub-line-items and cancellations.
69
+	 * For flat items, LIN_unit_price * LIN_quantity = LIN_total. Its LIN_total is the sum of all the children
70
+	 * LIN_totals. Its LIN_percent = 0.
71
+	 * For percent items, its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal (eg 10% = 10, not 0.1).
72
+	 * Its LIN_total is LIN_percent / 100 * sum of lower-priority sibling line items. Quantity = 1.
73
+	 */
74
+	const type_line_item = 'line-item';
75
+
76
+	/**
77
+	 * Line item indicating all the factors that make a single line item.
78
+	 * Sub-line items should have NO children line items.
79
+	 * For flat sub-items, their quantity should match their parent item, their LIN_unit_price should be this sub-item's
80
+	 * contribution towards the price of ONE of their parent items, and its LIN_total should be
81
+	 *  = LIN_quantity * LIN_unit_price. Its LIN_percent = 0.
82
+	 * For percent sub-items, the quantity should be 1, LIN_unit_price should be 0, and its LIN_total should
83
+	 * = LIN_percent / 100 * sum of lower-priority sibling line items..
84
+	 */
85
+	const type_sub_line_item = 'sub-item';
86
+
87
+	/**
88
+	 * Line item indicating a sub-total (eg total for an event, or pre-tax subtotal).
89
+	 * Direct children should be event subtotals.
90
+	 * Should have quantity of 1, and a LIN_total and LIN_unit_price of the sum of all its sub-items' LIN_totals.
91
+	 *
92
+	 */
93
+	const type_sub_total = 'sub-total';
94
+
95
+	/**
96
+	 * Line item for the grand total of an order. Its direct children
97
+	 * should be tax subtotals and (pre-tax) subtotals, and possibly a regular line item
98
+	 * indicating a transaction-wide discount/surcharge. Should have a quantity of 1, a LIN_total and LIN_unit_price of
99
+	 * the entire order's mount.
100
+	 */
101
+	const type_total = 'total';
102
+
103
+	/**
104
+	 * When a line item is cancelled, a sub-line-item of type 'cancellation'
105
+	 * should be created, indicating the quantity that were cancelled
106
+	 * (because a line item could have a quantity of 1, and its cancellation item
107
+	 * could be for 3, indicating that originally 4 were purchased, but 3 have been
108
+	 * cancelled, and only one remains).
109
+	 * When items are refunded, a cancellation line item should be made, which points
110
+	 * to teh payment model object which actually refunded the payment.
111
+	 * Cancellations should NOT have any children line items; the should NOT affect
112
+	 * any calculations, and are only meant as a record that cancellations have occurred.
113
+	 * Their LIN_percent should be 0.
114
+	 */
115
+	const type_cancellation = 'cancellation';
116
+
117
+	// private instance of the EEM_Line_Item object
118
+	protected static $_instance = NULL;
119
+
120
+
121
+	/**
122
+	 *        private constructor to prevent direct creation
123
+	 * @Constructor
124
+	 * @access protected
125
+	 * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any incoming timezone data that gets saved).  Note this just sends the timezone info to the date time model field objects.  Default is NULL (and will be assumed using the set timezone in the 'timezone_string' wp option)
126
+	 * @return \EEM_Line_Item
127
+	 */
128
+	protected function __construct($timezone)
129
+	{
130
+		$this->singular_item = __('Line Item', 'event_espresso');
131
+		$this->plural_item = __('Line Items', 'event_espresso');
132
+
133
+		$this->_tables = array(
134
+			'Line_Item' => new EE_Primary_Table('esp_line_item', 'LIN_ID')
135
+		);
136
+		$line_items_can_be_for = apply_filters('FHEE__EEM_Line_Item__line_items_can_be_for', array('Ticket', 'Price', 'Event'));
137
+		$this->_fields = array(
138
+			'Line_Item' => array(
139
+				'LIN_ID' => new EE_Primary_Key_Int_Field('LIN_ID', __("ID", "event_espresso")),
140
+				'LIN_code' => new EE_Slug_Field('LIN_code', __("Code for index into Cart", "event_espresso"), TRUE),
141
+				'TXN_ID' => new EE_Foreign_Key_Int_Field('TXN_ID', __("Transaction ID", "event_espresso"), TRUE, NULL, 'Transaction'),
142
+				'LIN_name' => new EE_Full_HTML_Field('LIN_name', __("Line Item Name", "event_espresso"), FALSE, ''),
143
+				'LIN_desc' => new EE_Full_HTML_Field('LIN_desc', __("Line Item Description", "event_espresso"), TRUE),
144
+				'LIN_unit_price' => new EE_Money_Field('LIN_unit_price', __("Unit Price", "event_espresso"), FALSE, 0),
145
+				'LIN_percent' => new EE_Float_Field('LIN_percent', __("Percent", "event_espresso"), FALSE, 0),
146
+				'LIN_is_taxable' => new EE_Boolean_Field('LIN_is_taxable', __("Taxable", "event_espresso"), FALSE, FALSE),
147
+				'LIN_order' => new EE_Integer_Field('LIN_order', __("Order of Application towards total of parent", "event_espresso"), FALSE, 1),
148
+				'LIN_total' => new EE_Money_Field('LIN_total', __("Total (unit price x quantity)", "event_espresso"), FALSE, 0),
149
+				'LIN_quantity' => new EE_Integer_Field('LIN_quantity', __("Quantity", "event_espresso"), TRUE, 1),
150
+				'LIN_parent' => new EE_Integer_Field('LIN_parent', __("Parent ID (this item goes towards that Line Item's total)", "event_espresso"), TRUE, NULL),
151
+				'LIN_type' => new EE_Enum_Text_Field('LIN_type', __("Type", "event_espresso"), FALSE, 'line-item', array(
152
+						self::type_line_item => __("Line Item", "event_espresso"),
153
+						self::type_sub_line_item => __("Sub-Item", "event_espresso"),
154
+						self::type_sub_total => __("Subtotal", "event_espresso"),
155
+						self::type_tax_sub_total => __("Tax Subtotal", "event_espresso"),
156
+						self::type_tax => __("Tax", "event_espresso"),
157
+						self::type_total => __("Total", "event_espresso"),
158
+						self::type_cancellation => __('Cancellation', 'event_espresso')
159
+					)
160
+				),
161
+				'OBJ_ID' => new EE_Foreign_Key_Int_Field('OBJ_ID', __('ID of Item purchased.', 'event_espresso'), TRUE, NULL, $line_items_can_be_for),
162
+				'OBJ_type' => new EE_Any_Foreign_Model_Name_Field('OBJ_type', __("Model Name this Line Item is for", "event_espresso"), TRUE, NULL, $line_items_can_be_for),
163
+				'LIN_timestamp' => new EE_Datetime_Field('LIN_timestamp', __('When the line item was created', 'event_espresso'), false, EE_Datetime_Field::now, $timezone),
164
+			)
165
+		);
166
+		$this->_model_relations = array(
167
+			'Transaction' => new EE_Belongs_To_Relation(),
168
+			'Ticket' => new EE_Belongs_To_Any_Relation(),
169
+			'Price' => new EE_Belongs_To_Any_Relation(),
170
+			'Event' => new EE_Belongs_To_Any_Relation()
171
+		);
172
+		$this->_model_chain_to_wp_user = 'Transaction.Registration.Event';
173
+		$this->_caps_slug = 'transactions';
174
+		parent::__construct($timezone);
175
+	}
176
+
177
+
178
+	/**
179
+	 * Gets all the line items for this transaction of the given type
180
+	 * @param string $line_item_type like one of EEM_Line_Item::type_*
181
+	 * @param EE_Transaction|int $transaction
182
+	 * @return EE_Line_Item[]
183
+	 */
184
+	public function get_all_of_type_for_transaction($line_item_type, $transaction)
185
+	{
186
+		$transaction = EEM_Transaction::instance()->ensure_is_ID($transaction);
187
+		return $this->get_all(array(array(
188
+			'LIN_type' => $line_item_type,
189
+			'TXN_ID' => $transaction
190
+		)));
191
+	}
192
+
193
+
194
+	/**
195
+	 * Gets all line items unrelated to tickets that are normal line items
196
+	 * (eg shipping, promotions, and miscellaneous other stuff should probably fit in this category)
197
+	 * @param EE_Transaction|int $transaction
198
+	 * @return EE_Line_Item[]
199
+	 */
200
+	public function get_all_non_ticket_line_items_for_transaction($transaction)
201
+	{
202
+		$transaction = EEM_Transaction::instance()->ensure_is_ID($transaction);
203
+		return $this->get_all(array(array(
204
+			'LIN_type' => self::type_line_item,
205
+			'TXN_ID' => $transaction,
206
+			'OR' => array(
207
+				'OBJ_type*notticket' => array('!=', 'Ticket'),
208
+				'OBJ_type*null' => array('IS_NULL'))
209
+		)));
210
+	}
211
+
212
+	/**
213
+	 * Deletes line items with no transaction who have passed the transaction cutoff time.
214
+	 * This needs to be very efficient
215
+	 * because if there are spam bots afoot there will be LOTS of line items
216
+	 * @return int count of how many deleted
217
+	 */
218
+	public function delete_line_items_with_no_transaction()
219
+	{
220
+		/** @type WPDB $wpdb */
221
+		global $wpdb;
222
+		$time_to_leave_alone = apply_filters(
223
+			'FHEE__EEM_Line_Item__delete_line_items_with_no_transaction__time_to_leave_alone', WEEK_IN_SECONDS
224
+		);
225
+		$query = $wpdb->prepare(
226
+			'DELETE li
227 227
 				FROM ' . $this->table() . ' li
228 228
 				LEFT JOIN ' . EEM_Transaction::instance()->table() . ' t ON li.TXN_ID = t.TXN_ID
229 229
 				WHERE t.TXN_ID IS NULL AND li.LIN_timestamp < %s',
230
-            // use GMT time because that's what TXN_timestamps are in
231
-            date('Y-m-d H:i:s', time() - $time_to_leave_alone)
232
-        );
233
-        return $wpdb->query($query);
234
-    }
235
-
236
-
237
-    /**
238
-     * get_line_item_for_transaction_object
239
-     * Gets a transaction's line item record for a specific object such as a EE_Event or EE_Ticket
240
-     *
241
-     * @param int $TXN_ID
242
-     * @param \EE_Base_Class $object
243
-     * @return EE_Line_Item[]
244
-     */
245
-    public function get_line_item_for_transaction_object($TXN_ID, EE_Base_Class $object)
246
-    {
247
-        return $this->get_all(array(array(
248
-            'TXN_ID' => $TXN_ID,
249
-            'OBJ_type' => str_replace('EE_', '', get_class($object)),
250
-            'OBJ_ID' => $object->ID()
251
-        )));
252
-    }
253
-
254
-
255
-    /**
256
-     * get_object_line_items_for_transaction
257
-     * Gets all of the the object line items for a transaction, based on an object type plus an array of object IDs
258
-     *
259
-     * @param int $TXN_ID
260
-     * @param string $OBJ_type
261
-     * @param array $OBJ_IDs
262
-     * @return EE_Line_Item[]
263
-     */
264
-    public function get_object_line_items_for_transaction($TXN_ID, $OBJ_type = 'Event', $OBJ_IDs = array())
265
-    {
266
-        $query_params = array(
267
-            'OBJ_type' => $OBJ_type,
268
-            // if incoming $OBJ_IDs is an array, then make sure it is formatted correctly for the query
269
-            'OBJ_ID' => is_array($OBJ_IDs) && !isset($OBJ_IDs['IN']) ? array('IN', $OBJ_IDs) : $OBJ_IDs
270
-        );
271
-        if ($TXN_ID) {
272
-            $query_params['TXN_ID'] = $TXN_ID;
273
-        }
274
-        return $this->get_all(array($query_params));
275
-    }
276
-
277
-
278
-    /**
279
-     * get_all_ticket_line_items_for_transaction
280
-     *
281
-     * @param EE_Transaction $transaction
282
-     * @return EE_Line_Item[]
283
-     */
284
-    public function get_all_ticket_line_items_for_transaction(EE_Transaction $transaction)
285
-    {
286
-        return $this->get_all(array(
287
-            array(
288
-                'TXN_ID' => $transaction->ID(),
289
-                'OBJ_type' => 'Ticket',
290
-            )
291
-        ));
292
-    }
293
-
294
-
295
-    /**
296
-     * get_ticket_line_item_for_transaction
297
-     *
298
-     * @param int $TXN_ID
299
-     * @param int $TKT_ID
300
-     * @return \EE_Line_Item
301
-     */
302
-    public function get_ticket_line_item_for_transaction($TXN_ID, $TKT_ID)
303
-    {
304
-        return $this->get_one(array(
305
-            array(
306
-                'TXN_ID' => EEM_Transaction::instance()->ensure_is_ID($TXN_ID),
307
-                'OBJ_ID' => $TKT_ID,
308
-                'OBJ_type' => 'Ticket',
309
-            )
310
-        ));
311
-    }
312
-
313
-
314
-    /**
315
-     * get_existing_promotion_line_item
316
-     * searches the cart for existing line items for the specified promotion
317
-     *
318
-     * @since   1.0.0
319
-     *
320
-     * @param EE_Line_Item $parent_line_item
321
-     * @param EE_Promotion $promotion
322
-     * @return EE_Line_Item
323
-     */
324
-    public function get_existing_promotion_line_item(EE_Line_Item $parent_line_item, EE_Promotion $promotion)
325
-    {
326
-        return $this->get_one(array(
327
-            array(
328
-                'TXN_ID' => $parent_line_item->TXN_ID(),
329
-                'LIN_parent' => $parent_line_item->ID(),
330
-                'OBJ_type' => 'Promotion',
331
-                'OBJ_ID' => $promotion->ID()
332
-            )
333
-        ));
334
-    }
335
-
336
-
337
-    /**
338
-     * get_all_promotion_line_items
339
-     * searches the cart for any and all existing promotion line items
340
-     *
341
-     * @since   1.0.0
342
-     *
343
-     * @param EE_Line_Item $parent_line_item
344
-     * @return EE_Line_Item[]
345
-     */
346
-    public function get_all_promotion_line_items(EE_Line_Item $parent_line_item)
347
-    {
348
-        return $this->get_all(array(
349
-            array(
350
-                'TXN_ID' => $parent_line_item->TXN_ID(),
351
-                'LIN_parent' => $parent_line_item->ID(),
352
-                'OBJ_type' => 'Promotion'
353
-            )
354
-        ));
355
-    }
356
-
357
-    /**
358
-     * Gets the registration's corresponding line item.
359
-     * Note: basically does NOT support having multiple line items for a single ticket,
360
-     * which would happen if some of the registrations had a price modifier while others didn't.
361
-     * In order to support that, we'd probably need a LIN_ID on registrations or something.
362
-     * @param EE_Registration $registration
363
-     * @return EE_Line_ITem
364
-     */
365
-    public function get_line_item_for_registration(EE_Registration $registration)
366
-    {
367
-        return $this->get_one($this->line_item_for_registration_query_params($registration));
368
-    }
369
-
370
-    /**
371
-     * Gets the query params used to retrieve a specific line item for the given registration
372
-     * @param EE_Registration $registration
373
-     * @param array $original_query_params any extra query params you'd like to be merged with
374
-     * @return array like EEM_Base::get_all()'s $query_params
375
-     */
376
-    public function line_item_for_registration_query_params(EE_Registration $registration, $original_query_params = array())
377
-    {
378
-        return array_replace_recursive($original_query_params, array(
379
-            array(
380
-                'OBJ_ID' => $registration->ticket_ID(),
381
-                'OBJ_type' => 'Ticket',
382
-                'TXN_ID' => $registration->transaction_ID()
383
-            )
384
-        ));
385
-    }
386
-
387
-
388
-    /**
389
-     * @return EE_Base_Class[]|EE_Line_Item[]
390
-     * @throws InvalidInterfaceException
391
-     * @throws InvalidDataTypeException
392
-     * @throws EE_Error
393
-     * @throws InvalidArgumentException
394
-     */
395
-    public function get_total_line_items_with_no_transaction()
396
-    {
397
-        return $this->get_total_line_items_for_carts();
398
-    }
399
-
400
-
401
-    /**
402
-     * @return EE_Base_Class[]|EE_Line_Item[]
403
-     * @throws InvalidInterfaceException
404
-     * @throws InvalidDataTypeException
405
-     * @throws EE_Error
406
-     * @throws InvalidArgumentException
407
-     */
408
-    public function get_total_line_items_for_active_carts()
409
-    {
410
-        return $this->get_total_line_items_for_carts(false);
411
-    }
412
-
413
-
414
-    /**
415
-     * @return EE_Base_Class[]|EE_Line_Item[]
416
-     * @throws InvalidInterfaceException
417
-     * @throws InvalidDataTypeException
418
-     * @throws EE_Error
419
-     * @throws InvalidArgumentException
420
-     */
421
-    public function get_total_line_items_for_expired_carts()
422
-    {
423
-        return $this->get_total_line_items_for_carts(true);
424
-    }
425
-
426
-
427
-    /**
428
-     * Returns an array of grand total line items where the TXN_ID is 0.
429
-     * If $expired is set to true, then only line items for expired sessions will be returned.
430
-     * If $expired is set to false, then only line items for active sessions will be returned.
431
-     *
432
-     * @param null $expired
433
-     * @return EE_Base_Class[]|EE_Line_Item[]
434
-     * @throws InvalidInterfaceException
435
-     * @throws InvalidDataTypeException
436
-     * @throws EE_Error
437
-     * @throws InvalidArgumentException
438
-     * @throws InvalidDataTypeException
439
-     * @throws InvalidInterfaceException
440
-     */
441
-    private function get_total_line_items_for_carts($expired = null)
442
-    {
443
-        $where_params = array(
444
-            'TXN_ID' => 0,
445
-            'LIN_type' => 'total',
446
-        );
447
-        if ($expired !== null) {
448
-            /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
449
-            $session_lifespan = LoaderFactory::getLoader()->getShared(
450
-                'EventEspresso\core\domain\values\session\SessionLifespan'
451
-            );
452
-            $where_params['LIN_timestamp'] = array(
453
-                $expired ? '<=' : '>',
454
-                $session_lifespan->expiration(),
455
-            );
456
-        }
457
-        return $this->get_all(array($where_params));
458
-    }
459
-
460
-
461
-    /**
462
-     * Returns an array of ticket total line items where the TXN_ID is 0
463
-     * AND the timestamp is older than the session lifespan.
464
-     *
465
-     * @param int $timestamp
466
-     * @return EE_Base_Class[]|EE_Line_Item[]
467
-     * @throws EE_Error
468
-     * @throws InvalidArgumentException
469
-     * @throws InvalidDataTypeException
470
-     * @throws InvalidInterfaceException
471
-     */
472
-    public function getTicketLineItemsForExpiredCarts($timestamp = 0)
473
-    {
474
-        if(! absint($timestamp)) {
475
-            /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
476
-            $session_lifespan = LoaderFactory::getLoader()->getShared(
477
-                'EventEspresso\core\domain\values\session\SessionLifespan'
478
-            );
479
-            $timestamp = $session_lifespan->expiration();
480
-        }
481
-        return $this->get_all(
482
-            array(
483
-                array(
484
-                    'TXN_ID'        => 0,
485
-                    'OBJ_type'      => 'Ticket',
486
-                    'LIN_timestamp' => array('<=', $timestamp),
487
-                )
488
-            )
489
-        );
490
-    }
230
+			// use GMT time because that's what TXN_timestamps are in
231
+			date('Y-m-d H:i:s', time() - $time_to_leave_alone)
232
+		);
233
+		return $wpdb->query($query);
234
+	}
235
+
236
+
237
+	/**
238
+	 * get_line_item_for_transaction_object
239
+	 * Gets a transaction's line item record for a specific object such as a EE_Event or EE_Ticket
240
+	 *
241
+	 * @param int $TXN_ID
242
+	 * @param \EE_Base_Class $object
243
+	 * @return EE_Line_Item[]
244
+	 */
245
+	public function get_line_item_for_transaction_object($TXN_ID, EE_Base_Class $object)
246
+	{
247
+		return $this->get_all(array(array(
248
+			'TXN_ID' => $TXN_ID,
249
+			'OBJ_type' => str_replace('EE_', '', get_class($object)),
250
+			'OBJ_ID' => $object->ID()
251
+		)));
252
+	}
253
+
254
+
255
+	/**
256
+	 * get_object_line_items_for_transaction
257
+	 * Gets all of the the object line items for a transaction, based on an object type plus an array of object IDs
258
+	 *
259
+	 * @param int $TXN_ID
260
+	 * @param string $OBJ_type
261
+	 * @param array $OBJ_IDs
262
+	 * @return EE_Line_Item[]
263
+	 */
264
+	public function get_object_line_items_for_transaction($TXN_ID, $OBJ_type = 'Event', $OBJ_IDs = array())
265
+	{
266
+		$query_params = array(
267
+			'OBJ_type' => $OBJ_type,
268
+			// if incoming $OBJ_IDs is an array, then make sure it is formatted correctly for the query
269
+			'OBJ_ID' => is_array($OBJ_IDs) && !isset($OBJ_IDs['IN']) ? array('IN', $OBJ_IDs) : $OBJ_IDs
270
+		);
271
+		if ($TXN_ID) {
272
+			$query_params['TXN_ID'] = $TXN_ID;
273
+		}
274
+		return $this->get_all(array($query_params));
275
+	}
276
+
277
+
278
+	/**
279
+	 * get_all_ticket_line_items_for_transaction
280
+	 *
281
+	 * @param EE_Transaction $transaction
282
+	 * @return EE_Line_Item[]
283
+	 */
284
+	public function get_all_ticket_line_items_for_transaction(EE_Transaction $transaction)
285
+	{
286
+		return $this->get_all(array(
287
+			array(
288
+				'TXN_ID' => $transaction->ID(),
289
+				'OBJ_type' => 'Ticket',
290
+			)
291
+		));
292
+	}
293
+
294
+
295
+	/**
296
+	 * get_ticket_line_item_for_transaction
297
+	 *
298
+	 * @param int $TXN_ID
299
+	 * @param int $TKT_ID
300
+	 * @return \EE_Line_Item
301
+	 */
302
+	public function get_ticket_line_item_for_transaction($TXN_ID, $TKT_ID)
303
+	{
304
+		return $this->get_one(array(
305
+			array(
306
+				'TXN_ID' => EEM_Transaction::instance()->ensure_is_ID($TXN_ID),
307
+				'OBJ_ID' => $TKT_ID,
308
+				'OBJ_type' => 'Ticket',
309
+			)
310
+		));
311
+	}
312
+
313
+
314
+	/**
315
+	 * get_existing_promotion_line_item
316
+	 * searches the cart for existing line items for the specified promotion
317
+	 *
318
+	 * @since   1.0.0
319
+	 *
320
+	 * @param EE_Line_Item $parent_line_item
321
+	 * @param EE_Promotion $promotion
322
+	 * @return EE_Line_Item
323
+	 */
324
+	public function get_existing_promotion_line_item(EE_Line_Item $parent_line_item, EE_Promotion $promotion)
325
+	{
326
+		return $this->get_one(array(
327
+			array(
328
+				'TXN_ID' => $parent_line_item->TXN_ID(),
329
+				'LIN_parent' => $parent_line_item->ID(),
330
+				'OBJ_type' => 'Promotion',
331
+				'OBJ_ID' => $promotion->ID()
332
+			)
333
+		));
334
+	}
335
+
336
+
337
+	/**
338
+	 * get_all_promotion_line_items
339
+	 * searches the cart for any and all existing promotion line items
340
+	 *
341
+	 * @since   1.0.0
342
+	 *
343
+	 * @param EE_Line_Item $parent_line_item
344
+	 * @return EE_Line_Item[]
345
+	 */
346
+	public function get_all_promotion_line_items(EE_Line_Item $parent_line_item)
347
+	{
348
+		return $this->get_all(array(
349
+			array(
350
+				'TXN_ID' => $parent_line_item->TXN_ID(),
351
+				'LIN_parent' => $parent_line_item->ID(),
352
+				'OBJ_type' => 'Promotion'
353
+			)
354
+		));
355
+	}
356
+
357
+	/**
358
+	 * Gets the registration's corresponding line item.
359
+	 * Note: basically does NOT support having multiple line items for a single ticket,
360
+	 * which would happen if some of the registrations had a price modifier while others didn't.
361
+	 * In order to support that, we'd probably need a LIN_ID on registrations or something.
362
+	 * @param EE_Registration $registration
363
+	 * @return EE_Line_ITem
364
+	 */
365
+	public function get_line_item_for_registration(EE_Registration $registration)
366
+	{
367
+		return $this->get_one($this->line_item_for_registration_query_params($registration));
368
+	}
369
+
370
+	/**
371
+	 * Gets the query params used to retrieve a specific line item for the given registration
372
+	 * @param EE_Registration $registration
373
+	 * @param array $original_query_params any extra query params you'd like to be merged with
374
+	 * @return array like EEM_Base::get_all()'s $query_params
375
+	 */
376
+	public function line_item_for_registration_query_params(EE_Registration $registration, $original_query_params = array())
377
+	{
378
+		return array_replace_recursive($original_query_params, array(
379
+			array(
380
+				'OBJ_ID' => $registration->ticket_ID(),
381
+				'OBJ_type' => 'Ticket',
382
+				'TXN_ID' => $registration->transaction_ID()
383
+			)
384
+		));
385
+	}
386
+
387
+
388
+	/**
389
+	 * @return EE_Base_Class[]|EE_Line_Item[]
390
+	 * @throws InvalidInterfaceException
391
+	 * @throws InvalidDataTypeException
392
+	 * @throws EE_Error
393
+	 * @throws InvalidArgumentException
394
+	 */
395
+	public function get_total_line_items_with_no_transaction()
396
+	{
397
+		return $this->get_total_line_items_for_carts();
398
+	}
399
+
400
+
401
+	/**
402
+	 * @return EE_Base_Class[]|EE_Line_Item[]
403
+	 * @throws InvalidInterfaceException
404
+	 * @throws InvalidDataTypeException
405
+	 * @throws EE_Error
406
+	 * @throws InvalidArgumentException
407
+	 */
408
+	public function get_total_line_items_for_active_carts()
409
+	{
410
+		return $this->get_total_line_items_for_carts(false);
411
+	}
412
+
413
+
414
+	/**
415
+	 * @return EE_Base_Class[]|EE_Line_Item[]
416
+	 * @throws InvalidInterfaceException
417
+	 * @throws InvalidDataTypeException
418
+	 * @throws EE_Error
419
+	 * @throws InvalidArgumentException
420
+	 */
421
+	public function get_total_line_items_for_expired_carts()
422
+	{
423
+		return $this->get_total_line_items_for_carts(true);
424
+	}
425
+
426
+
427
+	/**
428
+	 * Returns an array of grand total line items where the TXN_ID is 0.
429
+	 * If $expired is set to true, then only line items for expired sessions will be returned.
430
+	 * If $expired is set to false, then only line items for active sessions will be returned.
431
+	 *
432
+	 * @param null $expired
433
+	 * @return EE_Base_Class[]|EE_Line_Item[]
434
+	 * @throws InvalidInterfaceException
435
+	 * @throws InvalidDataTypeException
436
+	 * @throws EE_Error
437
+	 * @throws InvalidArgumentException
438
+	 * @throws InvalidDataTypeException
439
+	 * @throws InvalidInterfaceException
440
+	 */
441
+	private function get_total_line_items_for_carts($expired = null)
442
+	{
443
+		$where_params = array(
444
+			'TXN_ID' => 0,
445
+			'LIN_type' => 'total',
446
+		);
447
+		if ($expired !== null) {
448
+			/** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
449
+			$session_lifespan = LoaderFactory::getLoader()->getShared(
450
+				'EventEspresso\core\domain\values\session\SessionLifespan'
451
+			);
452
+			$where_params['LIN_timestamp'] = array(
453
+				$expired ? '<=' : '>',
454
+				$session_lifespan->expiration(),
455
+			);
456
+		}
457
+		return $this->get_all(array($where_params));
458
+	}
459
+
460
+
461
+	/**
462
+	 * Returns an array of ticket total line items where the TXN_ID is 0
463
+	 * AND the timestamp is older than the session lifespan.
464
+	 *
465
+	 * @param int $timestamp
466
+	 * @return EE_Base_Class[]|EE_Line_Item[]
467
+	 * @throws EE_Error
468
+	 * @throws InvalidArgumentException
469
+	 * @throws InvalidDataTypeException
470
+	 * @throws InvalidInterfaceException
471
+	 */
472
+	public function getTicketLineItemsForExpiredCarts($timestamp = 0)
473
+	{
474
+		if(! absint($timestamp)) {
475
+			/** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
476
+			$session_lifespan = LoaderFactory::getLoader()->getShared(
477
+				'EventEspresso\core\domain\values\session\SessionLifespan'
478
+			);
479
+			$timestamp = $session_lifespan->expiration();
480
+		}
481
+		return $this->get_all(
482
+			array(
483
+				array(
484
+					'TXN_ID'        => 0,
485
+					'OBJ_type'      => 'Ticket',
486
+					'LIN_timestamp' => array('<=', $timestamp),
487
+				)
488
+			)
489
+		);
490
+	}
491 491
 
492 492
 }
Please login to merge, or discard this patch.
core/domain/services/admin/ExitModal.php 1 patch
Indentation   +82 added lines, -82 removed lines patch added patch discarded remove patch
@@ -19,94 +19,94 @@
 block discarded – undo
19 19
 class ExitModal
20 20
 {
21 21
 
22
-    /**
23
-     * @var Registry
24
-     */
25
-    private $assets_registry;
22
+	/**
23
+	 * @var Registry
24
+	 */
25
+	private $assets_registry;
26 26
 
27
-    /**
28
-     * ExitModal constructor.
29
-     *
30
-     * @param Registry $assets_registry
31
-     */
32
-    public function __construct(Registry $assets_registry)
33
-    {
34
-        $this->assets_registry = $assets_registry;
35
-        add_action('in_admin_footer', array($this, 'modalContainer'));
36
-        add_action('admin_enqueue_scripts', array($this, 'enqueues'));
37
-    }
27
+	/**
28
+	 * ExitModal constructor.
29
+	 *
30
+	 * @param Registry $assets_registry
31
+	 */
32
+	public function __construct(Registry $assets_registry)
33
+	{
34
+		$this->assets_registry = $assets_registry;
35
+		add_action('in_admin_footer', array($this, 'modalContainer'));
36
+		add_action('admin_enqueue_scripts', array($this, 'enqueues'));
37
+	}
38 38
 
39 39
 
40
-    /**
41
-     * Callback on in_admin_footer that is used to output the exit modal container.
42
-     */
43
-    public function modalContainer()
44
-    {
45
-        echo '<div id="ee-exit-survey-modal"></div>';
46
-    }
40
+	/**
41
+	 * Callback on in_admin_footer that is used to output the exit modal container.
42
+	 */
43
+	public function modalContainer()
44
+	{
45
+		echo '<div id="ee-exit-survey-modal"></div>';
46
+	}
47 47
 
48 48
 
49
-    /**
50
-     * Callback for `admin_enqueue_scripts` to take care of enqueueing scripts and styles specific to the modal.
51
-     *
52
-     * @throws InvalidArgumentException
53
-     */
54
-    public function enqueues()
55
-    {
56
-        $current_user = new WP_User(get_current_user_id());
57
-        $this->assets_registry->addData(
58
-            'exitModali18n',
59
-            array(
60
-                'introText' => htmlspecialchars(
61
-                    __(
62
-                        'Do you have a moment to share why you are deactivating Event Espresso?',
63
-                        'event_espresso'
64
-                    ),
65
-                    ENT_NOQUOTES
66
-                ),
67
-                'doSurveyButtonText' => htmlspecialchars(
68
-                    __(
69
-                        'Sure I\'ll help',
70
-                        'event_espresso'
71
-                    ),
72
-                    ENT_NOQUOTES
73
-                ),
74
-                'skipButtonText' => htmlspecialchars(
75
-                    __(
76
-                        'Skip',
77
-                        'event_espresso'
78
-                    ),
79
-                    ENT_NOQUOTES
80
-                )
81
-            )
82
-        );
83
-        $this->assets_registry->addData(
84
-            'exitModalInfo',
85
-            array(
86
-                'firstname' => htmlspecialchars($current_user->user_firstname),
87
-                'emailaddress' => htmlspecialchars($current_user->user_email),
88
-                'website' => htmlspecialchars(site_url()),
89
-                'isModalActive' => $this->isModalActive()
90
-            )
91
-        );
49
+	/**
50
+	 * Callback for `admin_enqueue_scripts` to take care of enqueueing scripts and styles specific to the modal.
51
+	 *
52
+	 * @throws InvalidArgumentException
53
+	 */
54
+	public function enqueues()
55
+	{
56
+		$current_user = new WP_User(get_current_user_id());
57
+		$this->assets_registry->addData(
58
+			'exitModali18n',
59
+			array(
60
+				'introText' => htmlspecialchars(
61
+					__(
62
+						'Do you have a moment to share why you are deactivating Event Espresso?',
63
+						'event_espresso'
64
+					),
65
+					ENT_NOQUOTES
66
+				),
67
+				'doSurveyButtonText' => htmlspecialchars(
68
+					__(
69
+						'Sure I\'ll help',
70
+						'event_espresso'
71
+					),
72
+					ENT_NOQUOTES
73
+				),
74
+				'skipButtonText' => htmlspecialchars(
75
+					__(
76
+						'Skip',
77
+						'event_espresso'
78
+					),
79
+					ENT_NOQUOTES
80
+				)
81
+			)
82
+		);
83
+		$this->assets_registry->addData(
84
+			'exitModalInfo',
85
+			array(
86
+				'firstname' => htmlspecialchars($current_user->user_firstname),
87
+				'emailaddress' => htmlspecialchars($current_user->user_email),
88
+				'website' => htmlspecialchars(site_url()),
89
+				'isModalActive' => $this->isModalActive()
90
+			)
91
+		);
92 92
 
93
-        wp_enqueue_script('ee-wp-plugins-page');
94
-        wp_enqueue_style('ee-wp-plugins-page');
95
-    }
93
+		wp_enqueue_script('ee-wp-plugins-page');
94
+		wp_enqueue_style('ee-wp-plugins-page');
95
+	}
96 96
 
97 97
 
98
-    /**
99
-     * Exposes a filter switch for turning off the enqueueing of the modal script.
100
-     * @return bool
101
-     */
102
-    private function isModalActive()
103
-    {
104
-        return filter_var(
105
-            apply_filters(
106
-                'FHEE__EventEspresso_core_domain_services_admin_ExitModal__isModalActive',
107
-                true
108
-            ),
109
-            FILTER_VALIDATE_BOOLEAN
110
-        );
111
-    }
98
+	/**
99
+	 * Exposes a filter switch for turning off the enqueueing of the modal script.
100
+	 * @return bool
101
+	 */
102
+	private function isModalActive()
103
+	{
104
+		return filter_var(
105
+			apply_filters(
106
+				'FHEE__EventEspresso_core_domain_services_admin_ExitModal__isModalActive',
107
+				true
108
+			),
109
+			FILTER_VALIDATE_BOOLEAN
110
+		);
111
+	}
112 112
 }
Please login to merge, or discard this patch.
core/services/assets/Registry.php 2 patches
Indentation   +694 added lines, -694 removed lines patch added patch discarded remove patch
@@ -27,705 +27,705 @@
 block discarded – undo
27 27
 class Registry
28 28
 {
29 29
 
30
-    const ASSET_TYPE_CSS = 'css';
31
-    const ASSET_TYPE_JS = 'js';
32
-    const ASSET_NAMESPACE = 'core';
33
-
34
-    /**
35
-     * @var EE_Template_Config $template_config
36
-     */
37
-    protected $template_config;
38
-
39
-    /**
40
-     * @var EE_Currency_Config $currency_config
41
-     */
42
-    protected $currency_config;
43
-
44
-    /**
45
-     * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script.
46
-     *
47
-     * @var array
48
-     */
49
-    protected $jsdata = array();
50
-
51
-
52
-    /**
53
-     * This keeps track of all scripts with registered data.  It is used to prevent duplicate data objects setup in the
54
-     * page source.
55
-     * @var array
56
-     */
57
-    protected $script_handles_with_data = array();
58
-
59
-
60
-    /**
61
-     * @var DomainInterface
62
-     */
63
-    protected $domain;
64
-
65
-
66
-    /**
67
-     * @var I18nRegistry
68
-     */
69
-    private $i18n_registry;
70
-
71
-
72
-
73
-    /**
74
-     * Holds the manifest data obtained from registered manifest files.
75
-     * Manifests are maps of asset chunk name to actual built asset file names.
76
-     * Shape of this array is:
77
-     *
78
-     * array(
79
-     *  'some_namespace_slug' => array(
80
-     *      'some_chunk_name' => array(
81
-     *          'js' => 'filename.js'
82
-     *          'css' => 'filename.js'
83
-     *      ),
84
-     *      'url_base' => 'https://baseurl.com/to/assets
85
-     *  )
86
-     * )
87
-     *
88
-     * @var array
89
-     */
90
-    private $manifest_data = array();
91
-
92
-
93
-    /**
94
-     * Registry constructor.
95
-     * Hooking into WP actions for script registry.
96
-     *
97
-     * @param EE_Template_Config $template_config
98
-     * @param EE_Currency_Config $currency_config
99
-     * @param I18nRegistry       $i18n_registry
100
-     * @param DomainInterface    $domain
101
-     * @throws InvalidArgumentException
102
-     * @throws InvalidFilePathException
103
-     */
104
-    public function __construct(
105
-        EE_Template_Config $template_config,
106
-        EE_Currency_Config $currency_config,
107
-        I18nRegistry $i18n_registry,
108
-        DomainInterface $domain
109
-    ) {
110
-        $this->template_config = $template_config;
111
-        $this->currency_config = $currency_config;
112
-        $this->domain = $domain;
113
-        $this->i18n_registry = $i18n_registry;
114
-        $this->registerManifestFile(
115
-            self::ASSET_NAMESPACE,
116
-            $this->domain->distributionAssetsUrl(),
117
-            $this->domain->distributionAssetsPath() . 'build-manifest.json'
118
-        );
119
-        add_action('wp_enqueue_scripts', array($this, 'scripts'), 1);
120
-        add_action('admin_enqueue_scripts', array($this, 'scripts'), 1);
121
-        add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 2);
122
-        add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 2);
123
-        add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1);
124
-        add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1);
125
-    }
126
-
127
-
128
-    /**
129
-     * For classes that have Registry as a dependency, this provides a handy way to register script handles for i18n
130
-     * translation handling.
131
-     *
132
-     * @return I18nRegistry
133
-     */
134
-    public function getI18nRegistry()
135
-    {
136
-        return $this->i18n_registry;
137
-    }
138
-
139
-    /**
140
-     * Callback for the WP script actions.
141
-     * Used to register globally accessible core scripts.
142
-     * Also used to add the eejs.data object to the source for any js having eejs-core as a dependency.
143
-     *
144
-     */
145
-    public function scripts()
146
-    {
147
-        global $wp_version;
148
-        wp_register_script(
149
-            'ee-manifest',
150
-            $this->getJsUrl(self::ASSET_NAMESPACE, 'manifest'),
151
-            array(),
152
-            null,
153
-            true
154
-        );
155
-        wp_register_script(
156
-            'eejs-core',
157
-            $this->getJsUrl(self::ASSET_NAMESPACE, 'eejs'),
158
-            array('ee-manifest'),
159
-            null,
160
-            true
161
-        );
162
-        wp_register_script(
163
-            'ee-vendor-react',
164
-            $this->getJsUrl(self::ASSET_NAMESPACE, 'reactVendor'),
165
-            array('eejs-core'),
166
-            null,
167
-            true
168
-        );
169
-        //only run this if WordPress 4.4.0 > is in use.
170
-        if (version_compare($wp_version, '4.4.0', '>')) {
171
-            //js.api
172
-            wp_register_script(
173
-                'eejs-api',
174
-                EE_LIBRARIES_URL . 'rest_api/assets/js/eejs-api.min.js',
175
-                array('underscore', 'eejs-core'),
176
-                EVENT_ESPRESSO_VERSION,
177
-                true
178
-            );
179
-            $this->jsdata['eejs_api_nonce'] = wp_create_nonce('wp_rest');
180
-            $this->jsdata['paths'] = array(
181
-                'rest_route' => rest_url('ee/v4.8.36/'),
182
-                'collection_endpoints' => EED_Core_Rest_Api::getCollectionRoutesIndexedByModelName()
183
-            );
184
-        }
185
-        if (! is_admin()) {
186
-            $this->loadCoreCss();
187
-        }
188
-        $this->registerTranslationsForHandles(array('eejs-core'));
189
-        $this->loadCoreJs();
190
-        $this->loadJqueryValidate();
191
-        $this->loadAccountingJs();
192
-        $this->loadQtipJs();
193
-        $this->registerAdminAssets();
194
-    }
195
-
196
-
197
-
198
-    /**
199
-     * Call back for the script print in frontend and backend.
200
-     * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point.
201
-     *
202
-     * @since 4.9.31.rc.015
203
-     */
204
-    public function enqueueData()
205
-    {
206
-        $this->removeAlreadyRegisteredDataForScriptHandles();
207
-        wp_add_inline_script(
208
-            'eejs-core',
209
-            'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)),
210
-            'before'
211
-        );
212
-        wp_localize_script('espresso_core', 'eei18n', EE_Registry::$i18n_js_strings);
213
-        $this->localizeAccountingJs();
214
-        $this->addRegisteredScriptHandlesWithData('eejs-core');
215
-        $this->addRegisteredScriptHandlesWithData('espresso_core');
216
-    }
217
-
218
-
219
-
220
-    /**
221
-     * Used to add data to eejs.data object.
222
-     * Note:  Overriding existing data is not allowed.
223
-     * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript.
224
-     * If the data you add is something like this:
225
-     *  $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) );
226
-     * It will be exposed in the page source as:
227
-     *  eejs.data.my_plugin_data.foo == gar
228
-     *
229
-     * @param string       $key   Key used to access your data
230
-     * @param string|array $value Value to attach to key
231
-     * @throws InvalidArgumentException
232
-     */
233
-    public function addData($key, $value)
234
-    {
235
-        if ($this->verifyDataNotExisting($key)) {
236
-            $this->jsdata[$key] = $value;
237
-        }
238
-    }
239
-
240
-
241
-
242
-    /**
243
-     * Similar to addData except this allows for users to push values to an existing key where the values on key are
244
-     * elements in an array.
245
-     * When you use this method, the value you include will be appended to the end of an array on $key.
246
-     * So if the $key was 'test' and you added a value of 'my_data' then it would be represented in the javascript
247
-     * object like this, eejs.data.test = [ my_data,
248
-     * ]
249
-     * If there has already been a scalar value attached to the data object given key, then
250
-     * this will throw an exception.
251
-     *
252
-     * @param string       $key   Key to attach data to.
253
-     * @param string|array $value Value being registered.
254
-     * @throws InvalidArgumentException
255
-     */
256
-    public function pushData($key, $value)
257
-    {
258
-        if (isset($this->jsdata[$key])
259
-            && ! is_array($this->jsdata[$key])
260
-        ) {
261
-            throw new invalidArgumentException(
262
-                sprintf(
263
-                    __(
264
-                        'The value for %1$s is already set and it is not an array. The %2$s method can only be used to
30
+	const ASSET_TYPE_CSS = 'css';
31
+	const ASSET_TYPE_JS = 'js';
32
+	const ASSET_NAMESPACE = 'core';
33
+
34
+	/**
35
+	 * @var EE_Template_Config $template_config
36
+	 */
37
+	protected $template_config;
38
+
39
+	/**
40
+	 * @var EE_Currency_Config $currency_config
41
+	 */
42
+	protected $currency_config;
43
+
44
+	/**
45
+	 * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script.
46
+	 *
47
+	 * @var array
48
+	 */
49
+	protected $jsdata = array();
50
+
51
+
52
+	/**
53
+	 * This keeps track of all scripts with registered data.  It is used to prevent duplicate data objects setup in the
54
+	 * page source.
55
+	 * @var array
56
+	 */
57
+	protected $script_handles_with_data = array();
58
+
59
+
60
+	/**
61
+	 * @var DomainInterface
62
+	 */
63
+	protected $domain;
64
+
65
+
66
+	/**
67
+	 * @var I18nRegistry
68
+	 */
69
+	private $i18n_registry;
70
+
71
+
72
+
73
+	/**
74
+	 * Holds the manifest data obtained from registered manifest files.
75
+	 * Manifests are maps of asset chunk name to actual built asset file names.
76
+	 * Shape of this array is:
77
+	 *
78
+	 * array(
79
+	 *  'some_namespace_slug' => array(
80
+	 *      'some_chunk_name' => array(
81
+	 *          'js' => 'filename.js'
82
+	 *          'css' => 'filename.js'
83
+	 *      ),
84
+	 *      'url_base' => 'https://baseurl.com/to/assets
85
+	 *  )
86
+	 * )
87
+	 *
88
+	 * @var array
89
+	 */
90
+	private $manifest_data = array();
91
+
92
+
93
+	/**
94
+	 * Registry constructor.
95
+	 * Hooking into WP actions for script registry.
96
+	 *
97
+	 * @param EE_Template_Config $template_config
98
+	 * @param EE_Currency_Config $currency_config
99
+	 * @param I18nRegistry       $i18n_registry
100
+	 * @param DomainInterface    $domain
101
+	 * @throws InvalidArgumentException
102
+	 * @throws InvalidFilePathException
103
+	 */
104
+	public function __construct(
105
+		EE_Template_Config $template_config,
106
+		EE_Currency_Config $currency_config,
107
+		I18nRegistry $i18n_registry,
108
+		DomainInterface $domain
109
+	) {
110
+		$this->template_config = $template_config;
111
+		$this->currency_config = $currency_config;
112
+		$this->domain = $domain;
113
+		$this->i18n_registry = $i18n_registry;
114
+		$this->registerManifestFile(
115
+			self::ASSET_NAMESPACE,
116
+			$this->domain->distributionAssetsUrl(),
117
+			$this->domain->distributionAssetsPath() . 'build-manifest.json'
118
+		);
119
+		add_action('wp_enqueue_scripts', array($this, 'scripts'), 1);
120
+		add_action('admin_enqueue_scripts', array($this, 'scripts'), 1);
121
+		add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 2);
122
+		add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 2);
123
+		add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1);
124
+		add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1);
125
+	}
126
+
127
+
128
+	/**
129
+	 * For classes that have Registry as a dependency, this provides a handy way to register script handles for i18n
130
+	 * translation handling.
131
+	 *
132
+	 * @return I18nRegistry
133
+	 */
134
+	public function getI18nRegistry()
135
+	{
136
+		return $this->i18n_registry;
137
+	}
138
+
139
+	/**
140
+	 * Callback for the WP script actions.
141
+	 * Used to register globally accessible core scripts.
142
+	 * Also used to add the eejs.data object to the source for any js having eejs-core as a dependency.
143
+	 *
144
+	 */
145
+	public function scripts()
146
+	{
147
+		global $wp_version;
148
+		wp_register_script(
149
+			'ee-manifest',
150
+			$this->getJsUrl(self::ASSET_NAMESPACE, 'manifest'),
151
+			array(),
152
+			null,
153
+			true
154
+		);
155
+		wp_register_script(
156
+			'eejs-core',
157
+			$this->getJsUrl(self::ASSET_NAMESPACE, 'eejs'),
158
+			array('ee-manifest'),
159
+			null,
160
+			true
161
+		);
162
+		wp_register_script(
163
+			'ee-vendor-react',
164
+			$this->getJsUrl(self::ASSET_NAMESPACE, 'reactVendor'),
165
+			array('eejs-core'),
166
+			null,
167
+			true
168
+		);
169
+		//only run this if WordPress 4.4.0 > is in use.
170
+		if (version_compare($wp_version, '4.4.0', '>')) {
171
+			//js.api
172
+			wp_register_script(
173
+				'eejs-api',
174
+				EE_LIBRARIES_URL . 'rest_api/assets/js/eejs-api.min.js',
175
+				array('underscore', 'eejs-core'),
176
+				EVENT_ESPRESSO_VERSION,
177
+				true
178
+			);
179
+			$this->jsdata['eejs_api_nonce'] = wp_create_nonce('wp_rest');
180
+			$this->jsdata['paths'] = array(
181
+				'rest_route' => rest_url('ee/v4.8.36/'),
182
+				'collection_endpoints' => EED_Core_Rest_Api::getCollectionRoutesIndexedByModelName()
183
+			);
184
+		}
185
+		if (! is_admin()) {
186
+			$this->loadCoreCss();
187
+		}
188
+		$this->registerTranslationsForHandles(array('eejs-core'));
189
+		$this->loadCoreJs();
190
+		$this->loadJqueryValidate();
191
+		$this->loadAccountingJs();
192
+		$this->loadQtipJs();
193
+		$this->registerAdminAssets();
194
+	}
195
+
196
+
197
+
198
+	/**
199
+	 * Call back for the script print in frontend and backend.
200
+	 * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point.
201
+	 *
202
+	 * @since 4.9.31.rc.015
203
+	 */
204
+	public function enqueueData()
205
+	{
206
+		$this->removeAlreadyRegisteredDataForScriptHandles();
207
+		wp_add_inline_script(
208
+			'eejs-core',
209
+			'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)),
210
+			'before'
211
+		);
212
+		wp_localize_script('espresso_core', 'eei18n', EE_Registry::$i18n_js_strings);
213
+		$this->localizeAccountingJs();
214
+		$this->addRegisteredScriptHandlesWithData('eejs-core');
215
+		$this->addRegisteredScriptHandlesWithData('espresso_core');
216
+	}
217
+
218
+
219
+
220
+	/**
221
+	 * Used to add data to eejs.data object.
222
+	 * Note:  Overriding existing data is not allowed.
223
+	 * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript.
224
+	 * If the data you add is something like this:
225
+	 *  $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) );
226
+	 * It will be exposed in the page source as:
227
+	 *  eejs.data.my_plugin_data.foo == gar
228
+	 *
229
+	 * @param string       $key   Key used to access your data
230
+	 * @param string|array $value Value to attach to key
231
+	 * @throws InvalidArgumentException
232
+	 */
233
+	public function addData($key, $value)
234
+	{
235
+		if ($this->verifyDataNotExisting($key)) {
236
+			$this->jsdata[$key] = $value;
237
+		}
238
+	}
239
+
240
+
241
+
242
+	/**
243
+	 * Similar to addData except this allows for users to push values to an existing key where the values on key are
244
+	 * elements in an array.
245
+	 * When you use this method, the value you include will be appended to the end of an array on $key.
246
+	 * So if the $key was 'test' and you added a value of 'my_data' then it would be represented in the javascript
247
+	 * object like this, eejs.data.test = [ my_data,
248
+	 * ]
249
+	 * If there has already been a scalar value attached to the data object given key, then
250
+	 * this will throw an exception.
251
+	 *
252
+	 * @param string       $key   Key to attach data to.
253
+	 * @param string|array $value Value being registered.
254
+	 * @throws InvalidArgumentException
255
+	 */
256
+	public function pushData($key, $value)
257
+	{
258
+		if (isset($this->jsdata[$key])
259
+			&& ! is_array($this->jsdata[$key])
260
+		) {
261
+			throw new invalidArgumentException(
262
+				sprintf(
263
+					__(
264
+						'The value for %1$s is already set and it is not an array. The %2$s method can only be used to
265 265
                          push values to this data element when it is an array.',
266
-                        'event_espresso'
267
-                    ),
268
-                    $key,
269
-                    __METHOD__
270
-                )
271
-            );
272
-        }
273
-        $this->jsdata[$key][] = $value;
274
-    }
275
-
276
-
277
-
278
-    /**
279
-     * Used to set content used by javascript for a template.
280
-     * Note: Overrides of existing registered templates are not allowed.
281
-     *
282
-     * @param string $template_reference
283
-     * @param string $template_content
284
-     * @throws InvalidArgumentException
285
-     */
286
-    public function addTemplate($template_reference, $template_content)
287
-    {
288
-        if (! isset($this->jsdata['templates'])) {
289
-            $this->jsdata['templates'] = array();
290
-        }
291
-        //no overrides allowed.
292
-        if (isset($this->jsdata['templates'][$template_reference])) {
293
-            throw new invalidArgumentException(
294
-                sprintf(
295
-                    __(
296
-                        'The %1$s key already exists for the templates array in the js data array.  No overrides are allowed.',
297
-                        'event_espresso'
298
-                    ),
299
-                    $template_reference
300
-                )
301
-            );
302
-        }
303
-        $this->jsdata['templates'][$template_reference] = $template_content;
304
-    }
305
-
306
-
307
-
308
-    /**
309
-     * Retrieve the template content already registered for the given reference.
310
-     *
311
-     * @param string $template_reference
312
-     * @return string
313
-     */
314
-    public function getTemplate($template_reference)
315
-    {
316
-        return isset($this->jsdata['templates'], $this->jsdata['templates'][$template_reference])
317
-            ? $this->jsdata['templates'][$template_reference]
318
-            : '';
319
-    }
320
-
321
-
322
-
323
-    /**
324
-     * Retrieve registered data.
325
-     *
326
-     * @param string $key Name of key to attach data to.
327
-     * @return mixed                If there is no for the given key, then false is returned.
328
-     */
329
-    public function getData($key)
330
-    {
331
-        return isset($this->jsdata[$key])
332
-            ? $this->jsdata[$key]
333
-            : false;
334
-    }
335
-
336
-
337
-    /**
338
-     * Get the actual asset path for asset manifests.
339
-     * If there is no asset path found for the given $chunk_name, then the $chunk_name is returned.
340
-     * @param string $namespace  The namespace associated with the manifest file hosting the map of chunk_name to actual
341
-     *                           asset file location.
342
-     * @param string $chunk_name
343
-     * @param string $asset_type
344
-     * @return string
345
-     * @since 4.9.59.p
346
-     */
347
-    public function getAssetUrl($namespace, $chunk_name, $asset_type)
348
-    {
349
-        $url = isset(
350
-            $this->manifest_data[$namespace][$chunk_name][$asset_type],
351
-            $this->manifest_data[$namespace]['url_base']
352
-        )
353
-            ? $this->manifest_data[$namespace]['url_base']
354
-              . $this->manifest_data[$namespace][$chunk_name][$asset_type]
355
-            : $chunk_name;
356
-        return apply_filters(
357
-            'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl',
358
-            $url,
359
-            $namespace,
360
-            $chunk_name,
361
-            $asset_type
362
-        );
363
-    }
364
-
365
-
366
-    /**
367
-     * Return the url to a js file for the given namespace and chunk name.
368
-     *
369
-     * @param string $namespace
370
-     * @param string $chunk_name
371
-     * @return string
372
-     */
373
-    public function getJsUrl($namespace, $chunk_name)
374
-    {
375
-        return $this->getAssetUrl($namespace, $chunk_name, self::ASSET_TYPE_JS);
376
-    }
377
-
378
-
379
-    /**
380
-     * Return the url to a css file for the given namespace and chunk name.
381
-     *
382
-     * @param string $namespace
383
-     * @param string $chunk_name
384
-     * @return string
385
-     */
386
-    public function getCssUrl($namespace, $chunk_name)
387
-    {
388
-        return $this->getAssetUrl($namespace, $chunk_name, self::ASSET_TYPE_CSS);
389
-    }
390
-
391
-
392
-    /**
393
-     * Used to register a js/css manifest file with the registered_manifest_files property.
394
-     *
395
-     * @param string $namespace     Provided to associate the manifest file with a specific namespace.
396
-     * @param string $url_base      The url base for the manifest file location.
397
-     * @param string $manifest_file The absolute path to the manifest file.
398
-     * @throws InvalidArgumentException
399
-     * @throws InvalidFilePathException
400
-     * @since 4.9.59.p
401
-     */
402
-    public function registerManifestFile($namespace, $url_base, $manifest_file)
403
-    {
404
-        if (isset($this->manifest_data[$namespace])) {
405
-            throw new InvalidArgumentException(
406
-                sprintf(
407
-                    esc_html__(
408
-                        'The namespace for this manifest file has already been registered, choose a namespace other than %s',
409
-                        'event_espresso'
410
-                    ),
411
-                    $namespace
412
-                )
413
-            );
414
-        }
415
-        if (filter_var($url_base, FILTER_VALIDATE_URL) === false) {
416
-            if (is_admin()) {
417
-                EE_Error::add_error(
418
-                    sprintf(
419
-                        esc_html__(
420
-                            'The url given for %1$s assets is invalid.  The url provided was: "%2$s". This usually happens when another plugin or theme on a site is using the "%3$s" filter or has an invalid url set for the "%4$s" constant',
421
-                            'event_espresso'
422
-                        ),
423
-                        'Event Espresso',
424
-                        $url_base,
425
-                        'plugins_url',
426
-                        'WP_PLUGIN_URL'
427
-                    ),
428
-                    __FILE__,
429
-                    __FUNCTION__,
430
-                    __LINE__
431
-                );
432
-            }
433
-            return;
434
-        }
435
-        $this->manifest_data[$namespace] = $this->decodeManifestFile($manifest_file);
436
-        if (! isset($this->manifest_data[$namespace]['url_base'])) {
437
-            $this->manifest_data[$namespace]['url_base'] = trailingslashit($url_base);
438
-        }
439
-    }
440
-
441
-
442
-
443
-    /**
444
-     * Decodes json from the provided manifest file.
445
-     *
446
-     * @since 4.9.59.p
447
-     * @param string $manifest_file Path to manifest file.
448
-     * @return array
449
-     * @throws InvalidFilePathException
450
-     */
451
-    private function decodeManifestFile($manifest_file)
452
-    {
453
-        if (! file_exists($manifest_file)) {
454
-            throw new InvalidFilePathException($manifest_file);
455
-        }
456
-        return json_decode(file_get_contents($manifest_file), true);
457
-    }
458
-
459
-
460
-
461
-    /**
462
-     * Verifies whether the given data exists already on the jsdata array.
463
-     * Overriding data is not allowed.
464
-     *
465
-     * @param string $key Index for data.
466
-     * @return bool        If valid then return true.
467
-     * @throws InvalidArgumentException if data already exists.
468
-     */
469
-    protected function verifyDataNotExisting($key)
470
-    {
471
-        if (isset($this->jsdata[$key])) {
472
-            if (is_array($this->jsdata[$key])) {
473
-                throw new InvalidArgumentException(
474
-                    sprintf(
475
-                        __(
476
-                            'The value for %1$s already exists in the Registry::eejs object.
266
+						'event_espresso'
267
+					),
268
+					$key,
269
+					__METHOD__
270
+				)
271
+			);
272
+		}
273
+		$this->jsdata[$key][] = $value;
274
+	}
275
+
276
+
277
+
278
+	/**
279
+	 * Used to set content used by javascript for a template.
280
+	 * Note: Overrides of existing registered templates are not allowed.
281
+	 *
282
+	 * @param string $template_reference
283
+	 * @param string $template_content
284
+	 * @throws InvalidArgumentException
285
+	 */
286
+	public function addTemplate($template_reference, $template_content)
287
+	{
288
+		if (! isset($this->jsdata['templates'])) {
289
+			$this->jsdata['templates'] = array();
290
+		}
291
+		//no overrides allowed.
292
+		if (isset($this->jsdata['templates'][$template_reference])) {
293
+			throw new invalidArgumentException(
294
+				sprintf(
295
+					__(
296
+						'The %1$s key already exists for the templates array in the js data array.  No overrides are allowed.',
297
+						'event_espresso'
298
+					),
299
+					$template_reference
300
+				)
301
+			);
302
+		}
303
+		$this->jsdata['templates'][$template_reference] = $template_content;
304
+	}
305
+
306
+
307
+
308
+	/**
309
+	 * Retrieve the template content already registered for the given reference.
310
+	 *
311
+	 * @param string $template_reference
312
+	 * @return string
313
+	 */
314
+	public function getTemplate($template_reference)
315
+	{
316
+		return isset($this->jsdata['templates'], $this->jsdata['templates'][$template_reference])
317
+			? $this->jsdata['templates'][$template_reference]
318
+			: '';
319
+	}
320
+
321
+
322
+
323
+	/**
324
+	 * Retrieve registered data.
325
+	 *
326
+	 * @param string $key Name of key to attach data to.
327
+	 * @return mixed                If there is no for the given key, then false is returned.
328
+	 */
329
+	public function getData($key)
330
+	{
331
+		return isset($this->jsdata[$key])
332
+			? $this->jsdata[$key]
333
+			: false;
334
+	}
335
+
336
+
337
+	/**
338
+	 * Get the actual asset path for asset manifests.
339
+	 * If there is no asset path found for the given $chunk_name, then the $chunk_name is returned.
340
+	 * @param string $namespace  The namespace associated with the manifest file hosting the map of chunk_name to actual
341
+	 *                           asset file location.
342
+	 * @param string $chunk_name
343
+	 * @param string $asset_type
344
+	 * @return string
345
+	 * @since 4.9.59.p
346
+	 */
347
+	public function getAssetUrl($namespace, $chunk_name, $asset_type)
348
+	{
349
+		$url = isset(
350
+			$this->manifest_data[$namespace][$chunk_name][$asset_type],
351
+			$this->manifest_data[$namespace]['url_base']
352
+		)
353
+			? $this->manifest_data[$namespace]['url_base']
354
+			  . $this->manifest_data[$namespace][$chunk_name][$asset_type]
355
+			: $chunk_name;
356
+		return apply_filters(
357
+			'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl',
358
+			$url,
359
+			$namespace,
360
+			$chunk_name,
361
+			$asset_type
362
+		);
363
+	}
364
+
365
+
366
+	/**
367
+	 * Return the url to a js file for the given namespace and chunk name.
368
+	 *
369
+	 * @param string $namespace
370
+	 * @param string $chunk_name
371
+	 * @return string
372
+	 */
373
+	public function getJsUrl($namespace, $chunk_name)
374
+	{
375
+		return $this->getAssetUrl($namespace, $chunk_name, self::ASSET_TYPE_JS);
376
+	}
377
+
378
+
379
+	/**
380
+	 * Return the url to a css file for the given namespace and chunk name.
381
+	 *
382
+	 * @param string $namespace
383
+	 * @param string $chunk_name
384
+	 * @return string
385
+	 */
386
+	public function getCssUrl($namespace, $chunk_name)
387
+	{
388
+		return $this->getAssetUrl($namespace, $chunk_name, self::ASSET_TYPE_CSS);
389
+	}
390
+
391
+
392
+	/**
393
+	 * Used to register a js/css manifest file with the registered_manifest_files property.
394
+	 *
395
+	 * @param string $namespace     Provided to associate the manifest file with a specific namespace.
396
+	 * @param string $url_base      The url base for the manifest file location.
397
+	 * @param string $manifest_file The absolute path to the manifest file.
398
+	 * @throws InvalidArgumentException
399
+	 * @throws InvalidFilePathException
400
+	 * @since 4.9.59.p
401
+	 */
402
+	public function registerManifestFile($namespace, $url_base, $manifest_file)
403
+	{
404
+		if (isset($this->manifest_data[$namespace])) {
405
+			throw new InvalidArgumentException(
406
+				sprintf(
407
+					esc_html__(
408
+						'The namespace for this manifest file has already been registered, choose a namespace other than %s',
409
+						'event_espresso'
410
+					),
411
+					$namespace
412
+				)
413
+			);
414
+		}
415
+		if (filter_var($url_base, FILTER_VALIDATE_URL) === false) {
416
+			if (is_admin()) {
417
+				EE_Error::add_error(
418
+					sprintf(
419
+						esc_html__(
420
+							'The url given for %1$s assets is invalid.  The url provided was: "%2$s". This usually happens when another plugin or theme on a site is using the "%3$s" filter or has an invalid url set for the "%4$s" constant',
421
+							'event_espresso'
422
+						),
423
+						'Event Espresso',
424
+						$url_base,
425
+						'plugins_url',
426
+						'WP_PLUGIN_URL'
427
+					),
428
+					__FILE__,
429
+					__FUNCTION__,
430
+					__LINE__
431
+				);
432
+			}
433
+			return;
434
+		}
435
+		$this->manifest_data[$namespace] = $this->decodeManifestFile($manifest_file);
436
+		if (! isset($this->manifest_data[$namespace]['url_base'])) {
437
+			$this->manifest_data[$namespace]['url_base'] = trailingslashit($url_base);
438
+		}
439
+	}
440
+
441
+
442
+
443
+	/**
444
+	 * Decodes json from the provided manifest file.
445
+	 *
446
+	 * @since 4.9.59.p
447
+	 * @param string $manifest_file Path to manifest file.
448
+	 * @return array
449
+	 * @throws InvalidFilePathException
450
+	 */
451
+	private function decodeManifestFile($manifest_file)
452
+	{
453
+		if (! file_exists($manifest_file)) {
454
+			throw new InvalidFilePathException($manifest_file);
455
+		}
456
+		return json_decode(file_get_contents($manifest_file), true);
457
+	}
458
+
459
+
460
+
461
+	/**
462
+	 * Verifies whether the given data exists already on the jsdata array.
463
+	 * Overriding data is not allowed.
464
+	 *
465
+	 * @param string $key Index for data.
466
+	 * @return bool        If valid then return true.
467
+	 * @throws InvalidArgumentException if data already exists.
468
+	 */
469
+	protected function verifyDataNotExisting($key)
470
+	{
471
+		if (isset($this->jsdata[$key])) {
472
+			if (is_array($this->jsdata[$key])) {
473
+				throw new InvalidArgumentException(
474
+					sprintf(
475
+						__(
476
+							'The value for %1$s already exists in the Registry::eejs object.
477 477
                             Overrides are not allowed. Since the value of this data is an array, you may want to use the
478 478
                             %2$s method to push your value to the array.',
479
-                            'event_espresso'
480
-                        ),
481
-                        $key,
482
-                        'pushData()'
483
-                    )
484
-                );
485
-            }
486
-            throw new InvalidArgumentException(
487
-                sprintf(
488
-                    __(
489
-                        'The value for %1$s already exists in the Registry::eejs object. Overrides are not
479
+							'event_espresso'
480
+						),
481
+						$key,
482
+						'pushData()'
483
+					)
484
+				);
485
+			}
486
+			throw new InvalidArgumentException(
487
+				sprintf(
488
+					__(
489
+						'The value for %1$s already exists in the Registry::eejs object. Overrides are not
490 490
                         allowed.  Consider attaching your value to a different key',
491
-                        'event_espresso'
492
-                    ),
493
-                    $key
494
-                )
495
-            );
496
-        }
497
-        return true;
498
-    }
499
-
500
-
501
-
502
-    /**
503
-     * registers core default stylesheets
504
-     */
505
-    private function loadCoreCss()
506
-    {
507
-        if ($this->template_config->enable_default_style) {
508
-            $default_stylesheet_path = is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
509
-                ? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css'
510
-                : EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css';
511
-            wp_register_style(
512
-                'espresso_default',
513
-                $default_stylesheet_path,
514
-                array('dashicons'),
515
-                EVENT_ESPRESSO_VERSION
516
-            );
517
-            //Load custom style sheet if available
518
-            if ($this->template_config->custom_style_sheet !== null) {
519
-                wp_register_style(
520
-                    'espresso_custom_css',
521
-                    EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
522
-                    array('espresso_default'),
523
-                    EVENT_ESPRESSO_VERSION
524
-                );
525
-            }
526
-        }
527
-    }
528
-
529
-
530
-
531
-    /**
532
-     * registers core default javascript
533
-     */
534
-    private function loadCoreJs()
535
-    {
536
-        // load core js
537
-        wp_register_script(
538
-            'espresso_core',
539
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
540
-            array('jquery'),
541
-            EVENT_ESPRESSO_VERSION,
542
-            true
543
-        );
544
-    }
545
-
546
-
547
-
548
-    /**
549
-     * registers jQuery Validate for form validation
550
-     */
551
-    private function loadJqueryValidate()
552
-    {
553
-        // register jQuery Validate and additional methods
554
-        wp_register_script(
555
-            'jquery-validate',
556
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
557
-            array('jquery'),
558
-            '1.15.0',
559
-            true
560
-        );
561
-        wp_register_script(
562
-            'jquery-validate-extra-methods',
563
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
564
-            array('jquery', 'jquery-validate'),
565
-            '1.15.0',
566
-            true
567
-        );
568
-    }
569
-
570
-
571
-
572
-    /**
573
-     * registers accounting.js for performing client-side calculations
574
-     */
575
-    private function loadAccountingJs()
576
-    {
577
-        //accounting.js library
578
-        // @link http://josscrowcroft.github.io/accounting.js/
579
-        wp_register_script(
580
-            'ee-accounting-core',
581
-            EE_THIRD_PARTY_URL . 'accounting/accounting.js',
582
-            array('underscore'),
583
-            '0.3.2',
584
-            true
585
-        );
586
-        wp_register_script(
587
-            'ee-accounting',
588
-            EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js',
589
-            array('ee-accounting-core'),
590
-            EVENT_ESPRESSO_VERSION,
591
-            true
592
-        );
593
-    }
594
-
595
-
596
-
597
-    /**
598
-     * registers accounting.js for performing client-side calculations
599
-     */
600
-    private function localizeAccountingJs()
601
-    {
602
-        wp_localize_script(
603
-            'ee-accounting',
604
-            'EE_ACCOUNTING_CFG',
605
-            array(
606
-                'currency' => array(
607
-                    'symbol'    => $this->currency_config->sign,
608
-                    'format'    => array(
609
-                        'pos'  => $this->currency_config->sign_b4 ? '%s%v' : '%v%s',
610
-                        'neg'  => $this->currency_config->sign_b4 ? '- %s%v' : '- %v%s',
611
-                        'zero' => $this->currency_config->sign_b4 ? '%s--' : '--%s',
612
-                    ),
613
-                    'decimal'   => $this->currency_config->dec_mrk,
614
-                    'thousand'  => $this->currency_config->thsnds,
615
-                    'precision' => $this->currency_config->dec_plc,
616
-                ),
617
-                'number'   => array(
618
-                    'precision' => $this->currency_config->dec_plc,
619
-                    'thousand'  => $this->currency_config->thsnds,
620
-                    'decimal'   => $this->currency_config->dec_mrk,
621
-                ),
622
-            )
623
-        );
624
-        $this->addRegisteredScriptHandlesWithData('ee-accounting');
625
-    }
626
-
627
-
628
-
629
-    /**
630
-     * registers assets for cleaning your ears
631
-     */
632
-    private function loadQtipJs()
633
-    {
634
-        // qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook,
635
-        // can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' );
636
-        if (apply_filters('FHEE_load_qtip', false)) {
637
-            EEH_Qtip_Loader::instance()->register_and_enqueue();
638
-        }
639
-    }
640
-
641
-
642
-    /**
643
-     * This is used to set registered script handles that have data.
644
-     * @param string $script_handle
645
-     */
646
-    private function addRegisteredScriptHandlesWithData($script_handle)
647
-    {
648
-        $this->script_handles_with_data[$script_handle] = $script_handle;
649
-    }
650
-
651
-
652
-    /**i
491
+						'event_espresso'
492
+					),
493
+					$key
494
+				)
495
+			);
496
+		}
497
+		return true;
498
+	}
499
+
500
+
501
+
502
+	/**
503
+	 * registers core default stylesheets
504
+	 */
505
+	private function loadCoreCss()
506
+	{
507
+		if ($this->template_config->enable_default_style) {
508
+			$default_stylesheet_path = is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
509
+				? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css'
510
+				: EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css';
511
+			wp_register_style(
512
+				'espresso_default',
513
+				$default_stylesheet_path,
514
+				array('dashicons'),
515
+				EVENT_ESPRESSO_VERSION
516
+			);
517
+			//Load custom style sheet if available
518
+			if ($this->template_config->custom_style_sheet !== null) {
519
+				wp_register_style(
520
+					'espresso_custom_css',
521
+					EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
522
+					array('espresso_default'),
523
+					EVENT_ESPRESSO_VERSION
524
+				);
525
+			}
526
+		}
527
+	}
528
+
529
+
530
+
531
+	/**
532
+	 * registers core default javascript
533
+	 */
534
+	private function loadCoreJs()
535
+	{
536
+		// load core js
537
+		wp_register_script(
538
+			'espresso_core',
539
+			EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
540
+			array('jquery'),
541
+			EVENT_ESPRESSO_VERSION,
542
+			true
543
+		);
544
+	}
545
+
546
+
547
+
548
+	/**
549
+	 * registers jQuery Validate for form validation
550
+	 */
551
+	private function loadJqueryValidate()
552
+	{
553
+		// register jQuery Validate and additional methods
554
+		wp_register_script(
555
+			'jquery-validate',
556
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
557
+			array('jquery'),
558
+			'1.15.0',
559
+			true
560
+		);
561
+		wp_register_script(
562
+			'jquery-validate-extra-methods',
563
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
564
+			array('jquery', 'jquery-validate'),
565
+			'1.15.0',
566
+			true
567
+		);
568
+	}
569
+
570
+
571
+
572
+	/**
573
+	 * registers accounting.js for performing client-side calculations
574
+	 */
575
+	private function loadAccountingJs()
576
+	{
577
+		//accounting.js library
578
+		// @link http://josscrowcroft.github.io/accounting.js/
579
+		wp_register_script(
580
+			'ee-accounting-core',
581
+			EE_THIRD_PARTY_URL . 'accounting/accounting.js',
582
+			array('underscore'),
583
+			'0.3.2',
584
+			true
585
+		);
586
+		wp_register_script(
587
+			'ee-accounting',
588
+			EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js',
589
+			array('ee-accounting-core'),
590
+			EVENT_ESPRESSO_VERSION,
591
+			true
592
+		);
593
+	}
594
+
595
+
596
+
597
+	/**
598
+	 * registers accounting.js for performing client-side calculations
599
+	 */
600
+	private function localizeAccountingJs()
601
+	{
602
+		wp_localize_script(
603
+			'ee-accounting',
604
+			'EE_ACCOUNTING_CFG',
605
+			array(
606
+				'currency' => array(
607
+					'symbol'    => $this->currency_config->sign,
608
+					'format'    => array(
609
+						'pos'  => $this->currency_config->sign_b4 ? '%s%v' : '%v%s',
610
+						'neg'  => $this->currency_config->sign_b4 ? '- %s%v' : '- %v%s',
611
+						'zero' => $this->currency_config->sign_b4 ? '%s--' : '--%s',
612
+					),
613
+					'decimal'   => $this->currency_config->dec_mrk,
614
+					'thousand'  => $this->currency_config->thsnds,
615
+					'precision' => $this->currency_config->dec_plc,
616
+				),
617
+				'number'   => array(
618
+					'precision' => $this->currency_config->dec_plc,
619
+					'thousand'  => $this->currency_config->thsnds,
620
+					'decimal'   => $this->currency_config->dec_mrk,
621
+				),
622
+			)
623
+		);
624
+		$this->addRegisteredScriptHandlesWithData('ee-accounting');
625
+	}
626
+
627
+
628
+
629
+	/**
630
+	 * registers assets for cleaning your ears
631
+	 */
632
+	private function loadQtipJs()
633
+	{
634
+		// qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook,
635
+		// can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' );
636
+		if (apply_filters('FHEE_load_qtip', false)) {
637
+			EEH_Qtip_Loader::instance()->register_and_enqueue();
638
+		}
639
+	}
640
+
641
+
642
+	/**
643
+	 * This is used to set registered script handles that have data.
644
+	 * @param string $script_handle
645
+	 */
646
+	private function addRegisteredScriptHandlesWithData($script_handle)
647
+	{
648
+		$this->script_handles_with_data[$script_handle] = $script_handle;
649
+	}
650
+
651
+
652
+	/**i
653 653
      * Checks WP_Scripts for all of each script handle registered internally as having data and unsets from the
654 654
      * Dependency stored in WP_Scripts if its set.
655 655
      */
656
-    private function removeAlreadyRegisteredDataForScriptHandles()
657
-    {
658
-        if (empty($this->script_handles_with_data)) {
659
-            return;
660
-        }
661
-        foreach ($this->script_handles_with_data as $script_handle) {
662
-            $this->removeAlreadyRegisteredDataForScriptHandle($script_handle);
663
-        }
664
-    }
665
-
666
-
667
-    /**
668
-     * Removes any data dependency registered in WP_Scripts if its set.
669
-     * @param string $script_handle
670
-     */
671
-    private function removeAlreadyRegisteredDataForScriptHandle($script_handle)
672
-    {
673
-        if (isset($this->script_handles_with_data[$script_handle])) {
674
-            global $wp_scripts;
675
-            $unset_handle = false;
676
-            if ($wp_scripts->get_data($script_handle, 'data')) {
677
-                unset($wp_scripts->registered[$script_handle]->extra['data']);
678
-                $unset_handle = true;
679
-            }
680
-            //deal with inline_scripts
681
-            if ($wp_scripts->get_data($script_handle, 'before')) {
682
-                unset($wp_scripts->registered[$script_handle]->extra['before']);
683
-                $unset_handle = true;
684
-            }
685
-            if ($wp_scripts->get_data($script_handle, 'after')) {
686
-                unset($wp_scripts->registered[$script_handle]->extra['after']);
687
-            }
688
-            if ($unset_handle) {
689
-                unset($this->script_handles_with_data[$script_handle]);
690
-            }
691
-        }
692
-    }
693
-
694
-
695
-    /**
696
-     * Registers assets that are used in the WordPress admin.
697
-     */
698
-    private function registerAdminAssets()
699
-    {
700
-        wp_register_script(
701
-            'ee-wp-plugins-page',
702
-            $this->getJsUrl(self::ASSET_NAMESPACE, 'wp-plugins-page'),
703
-            array(
704
-                'jquery',
705
-                'ee-vendor-react'
706
-            ),
707
-            null,
708
-            true
709
-        );
710
-        wp_register_style(
711
-            'ee-wp-plugins-page',
712
-            $this->getCssUrl(self::ASSET_NAMESPACE, 'wp-plugins-page'),
713
-            array(),
714
-            null
715
-        );
716
-        $this->registerTranslationsForHandles(array('ee-wp-plugins-page'));
717
-    }
718
-
719
-
720
-    /**
721
-     * All handles that are registered via the registry that might have translations have their translations registered
722
-     *
723
-     * @param array $handles_to_register
724
-     */
725
-    private function registerTranslationsForHandles(array $handles_to_register)
726
-    {
727
-        foreach($handles_to_register as $handle) {
728
-            $this->i18n_registry->registerScriptI18n($handle);
729
-        }
730
-    }
656
+	private function removeAlreadyRegisteredDataForScriptHandles()
657
+	{
658
+		if (empty($this->script_handles_with_data)) {
659
+			return;
660
+		}
661
+		foreach ($this->script_handles_with_data as $script_handle) {
662
+			$this->removeAlreadyRegisteredDataForScriptHandle($script_handle);
663
+		}
664
+	}
665
+
666
+
667
+	/**
668
+	 * Removes any data dependency registered in WP_Scripts if its set.
669
+	 * @param string $script_handle
670
+	 */
671
+	private function removeAlreadyRegisteredDataForScriptHandle($script_handle)
672
+	{
673
+		if (isset($this->script_handles_with_data[$script_handle])) {
674
+			global $wp_scripts;
675
+			$unset_handle = false;
676
+			if ($wp_scripts->get_data($script_handle, 'data')) {
677
+				unset($wp_scripts->registered[$script_handle]->extra['data']);
678
+				$unset_handle = true;
679
+			}
680
+			//deal with inline_scripts
681
+			if ($wp_scripts->get_data($script_handle, 'before')) {
682
+				unset($wp_scripts->registered[$script_handle]->extra['before']);
683
+				$unset_handle = true;
684
+			}
685
+			if ($wp_scripts->get_data($script_handle, 'after')) {
686
+				unset($wp_scripts->registered[$script_handle]->extra['after']);
687
+			}
688
+			if ($unset_handle) {
689
+				unset($this->script_handles_with_data[$script_handle]);
690
+			}
691
+		}
692
+	}
693
+
694
+
695
+	/**
696
+	 * Registers assets that are used in the WordPress admin.
697
+	 */
698
+	private function registerAdminAssets()
699
+	{
700
+		wp_register_script(
701
+			'ee-wp-plugins-page',
702
+			$this->getJsUrl(self::ASSET_NAMESPACE, 'wp-plugins-page'),
703
+			array(
704
+				'jquery',
705
+				'ee-vendor-react'
706
+			),
707
+			null,
708
+			true
709
+		);
710
+		wp_register_style(
711
+			'ee-wp-plugins-page',
712
+			$this->getCssUrl(self::ASSET_NAMESPACE, 'wp-plugins-page'),
713
+			array(),
714
+			null
715
+		);
716
+		$this->registerTranslationsForHandles(array('ee-wp-plugins-page'));
717
+	}
718
+
719
+
720
+	/**
721
+	 * All handles that are registered via the registry that might have translations have their translations registered
722
+	 *
723
+	 * @param array $handles_to_register
724
+	 */
725
+	private function registerTranslationsForHandles(array $handles_to_register)
726
+	{
727
+		foreach($handles_to_register as $handle) {
728
+			$this->i18n_registry->registerScriptI18n($handle);
729
+		}
730
+	}
731 731
 }
Please login to merge, or discard this patch.
Spacing   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
         $this->registerManifestFile(
115 115
             self::ASSET_NAMESPACE,
116 116
             $this->domain->distributionAssetsUrl(),
117
-            $this->domain->distributionAssetsPath() . 'build-manifest.json'
117
+            $this->domain->distributionAssetsPath().'build-manifest.json'
118 118
         );
119 119
         add_action('wp_enqueue_scripts', array($this, 'scripts'), 1);
120 120
         add_action('admin_enqueue_scripts', array($this, 'scripts'), 1);
@@ -171,7 +171,7 @@  discard block
 block discarded – undo
171 171
             //js.api
172 172
             wp_register_script(
173 173
                 'eejs-api',
174
-                EE_LIBRARIES_URL . 'rest_api/assets/js/eejs-api.min.js',
174
+                EE_LIBRARIES_URL.'rest_api/assets/js/eejs-api.min.js',
175 175
                 array('underscore', 'eejs-core'),
176 176
                 EVENT_ESPRESSO_VERSION,
177 177
                 true
@@ -182,7 +182,7 @@  discard block
 block discarded – undo
182 182
                 'collection_endpoints' => EED_Core_Rest_Api::getCollectionRoutesIndexedByModelName()
183 183
             );
184 184
         }
185
-        if (! is_admin()) {
185
+        if ( ! is_admin()) {
186 186
             $this->loadCoreCss();
187 187
         }
188 188
         $this->registerTranslationsForHandles(array('eejs-core'));
@@ -206,7 +206,7 @@  discard block
 block discarded – undo
206 206
         $this->removeAlreadyRegisteredDataForScriptHandles();
207 207
         wp_add_inline_script(
208 208
             'eejs-core',
209
-            'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)),
209
+            'var eejsdata='.wp_json_encode(array('data' => $this->jsdata)),
210 210
             'before'
211 211
         );
212 212
         wp_localize_script('espresso_core', 'eei18n', EE_Registry::$i18n_js_strings);
@@ -285,7 +285,7 @@  discard block
 block discarded – undo
285 285
      */
286 286
     public function addTemplate($template_reference, $template_content)
287 287
     {
288
-        if (! isset($this->jsdata['templates'])) {
288
+        if ( ! isset($this->jsdata['templates'])) {
289 289
             $this->jsdata['templates'] = array();
290 290
         }
291 291
         //no overrides allowed.
@@ -433,7 +433,7 @@  discard block
 block discarded – undo
433 433
             return;
434 434
         }
435 435
         $this->manifest_data[$namespace] = $this->decodeManifestFile($manifest_file);
436
-        if (! isset($this->manifest_data[$namespace]['url_base'])) {
436
+        if ( ! isset($this->manifest_data[$namespace]['url_base'])) {
437 437
             $this->manifest_data[$namespace]['url_base'] = trailingslashit($url_base);
438 438
         }
439 439
     }
@@ -450,7 +450,7 @@  discard block
 block discarded – undo
450 450
      */
451 451
     private function decodeManifestFile($manifest_file)
452 452
     {
453
-        if (! file_exists($manifest_file)) {
453
+        if ( ! file_exists($manifest_file)) {
454 454
             throw new InvalidFilePathException($manifest_file);
455 455
         }
456 456
         return json_decode(file_get_contents($manifest_file), true);
@@ -505,9 +505,9 @@  discard block
 block discarded – undo
505 505
     private function loadCoreCss()
506 506
     {
507 507
         if ($this->template_config->enable_default_style) {
508
-            $default_stylesheet_path = is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
508
+            $default_stylesheet_path = is_readable(EVENT_ESPRESSO_UPLOAD_DIR.'css/style.css')
509 509
                 ? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css'
510
-                : EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css';
510
+                : EE_GLOBAL_ASSETS_URL.'css/espresso_default.css';
511 511
             wp_register_style(
512 512
                 'espresso_default',
513 513
                 $default_stylesheet_path,
@@ -518,7 +518,7 @@  discard block
 block discarded – undo
518 518
             if ($this->template_config->custom_style_sheet !== null) {
519 519
                 wp_register_style(
520 520
                     'espresso_custom_css',
521
-                    EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
521
+                    EVENT_ESPRESSO_UPLOAD_URL.'css/'.$this->template_config->custom_style_sheet,
522 522
                     array('espresso_default'),
523 523
                     EVENT_ESPRESSO_VERSION
524 524
                 );
@@ -536,7 +536,7 @@  discard block
 block discarded – undo
536 536
         // load core js
537 537
         wp_register_script(
538 538
             'espresso_core',
539
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
539
+            EE_GLOBAL_ASSETS_URL.'scripts/espresso_core.js',
540 540
             array('jquery'),
541 541
             EVENT_ESPRESSO_VERSION,
542 542
             true
@@ -553,14 +553,14 @@  discard block
 block discarded – undo
553 553
         // register jQuery Validate and additional methods
554 554
         wp_register_script(
555 555
             'jquery-validate',
556
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
556
+            EE_GLOBAL_ASSETS_URL.'scripts/jquery.validate.min.js',
557 557
             array('jquery'),
558 558
             '1.15.0',
559 559
             true
560 560
         );
561 561
         wp_register_script(
562 562
             'jquery-validate-extra-methods',
563
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
563
+            EE_GLOBAL_ASSETS_URL.'scripts/jquery.validate.additional-methods.min.js',
564 564
             array('jquery', 'jquery-validate'),
565 565
             '1.15.0',
566 566
             true
@@ -578,14 +578,14 @@  discard block
 block discarded – undo
578 578
         // @link http://josscrowcroft.github.io/accounting.js/
579 579
         wp_register_script(
580 580
             'ee-accounting-core',
581
-            EE_THIRD_PARTY_URL . 'accounting/accounting.js',
581
+            EE_THIRD_PARTY_URL.'accounting/accounting.js',
582 582
             array('underscore'),
583 583
             '0.3.2',
584 584
             true
585 585
         );
586 586
         wp_register_script(
587 587
             'ee-accounting',
588
-            EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js',
588
+            EE_GLOBAL_ASSETS_URL.'scripts/ee-accounting-config.js',
589 589
             array('ee-accounting-core'),
590 590
             EVENT_ESPRESSO_VERSION,
591 591
             true
@@ -724,7 +724,7 @@  discard block
 block discarded – undo
724 724
      */
725 725
     private function registerTranslationsForHandles(array $handles_to_register)
726 726
     {
727
-        foreach($handles_to_register as $handle) {
727
+        foreach ($handles_to_register as $handle) {
728 728
             $this->i18n_registry->registerScriptI18n($handle);
729 729
         }
730 730
     }
Please login to merge, or discard this patch.
core/EE_Dependency_Map.core.php 1 patch
Indentation   +912 added lines, -912 removed lines patch added patch discarded remove patch
@@ -8,7 +8,7 @@  discard block
 block discarded – undo
8 8
 use EventEspresso\core\services\request\ResponseInterface;
9 9
 
10 10
 if (! defined('EVENT_ESPRESSO_VERSION')) {
11
-    exit('No direct script access allowed');
11
+	exit('No direct script access allowed');
12 12
 }
13 13
 
14 14
 
@@ -25,917 +25,917 @@  discard block
 block discarded – undo
25 25
 class EE_Dependency_Map
26 26
 {
27 27
 
28
-    /**
29
-     * This means that the requested class dependency is not present in the dependency map
30
-     */
31
-    const not_registered = 0;
32
-
33
-    /**
34
-     * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
35
-     */
36
-    const load_new_object = 1;
37
-
38
-    /**
39
-     * This instructs class loaders to return a previously instantiated and cached object for the requested class.
40
-     * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
41
-     */
42
-    const load_from_cache = 2;
43
-
44
-    /**
45
-     * When registering a dependency,
46
-     * this indicates to keep any existing dependencies that already exist,
47
-     * and simply discard any new dependencies declared in the incoming data
48
-     */
49
-    const KEEP_EXISTING_DEPENDENCIES = 0;
50
-
51
-    /**
52
-     * When registering a dependency,
53
-     * this indicates to overwrite any existing dependencies that already exist using the incoming data
54
-     */
55
-    const OVERWRITE_DEPENDENCIES = 1;
56
-
57
-
58
-
59
-    /**
60
-     * @type EE_Dependency_Map $_instance
61
-     */
62
-    protected static $_instance;
63
-
64
-    /**
65
-     * @type RequestInterface $request
66
-     */
67
-    protected $request;
68
-
69
-    /**
70
-     * @type LegacyRequestInterface $legacy_request
71
-     */
72
-    protected $legacy_request;
73
-
74
-    /**
75
-     * @type ResponseInterface $response
76
-     */
77
-    protected $response;
78
-
79
-    /**
80
-     * @type LoaderInterface $loader
81
-     */
82
-    protected $loader;
83
-
84
-    /**
85
-     * @type array $_dependency_map
86
-     */
87
-    protected $_dependency_map = array();
88
-
89
-    /**
90
-     * @type array $_class_loaders
91
-     */
92
-    protected $_class_loaders = array();
93
-
94
-    /**
95
-     * @type array $_aliases
96
-     */
97
-    protected $_aliases = array();
98
-
99
-
100
-
101
-    /**
102
-     * EE_Dependency_Map constructor.
103
-     */
104
-    protected function __construct()
105
-    {
106
-        // add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
107
-        do_action('EE_Dependency_Map____construct');
108
-    }
109
-
110
-
111
-
112
-    /**
113
-     * @throws InvalidDataTypeException
114
-     * @throws InvalidInterfaceException
115
-     * @throws InvalidArgumentException
116
-     */
117
-    public function initialize()
118
-    {
119
-        $this->_register_core_dependencies();
120
-        $this->_register_core_class_loaders();
121
-        $this->_register_core_aliases();
122
-    }
123
-
124
-
125
-
126
-    /**
127
-     * @singleton method used to instantiate class object
128
-     * @return EE_Dependency_Map
129
-     */
130
-    public static function instance() {
131
-        // check if class object is instantiated, and instantiated properly
132
-        if (! self::$_instance instanceof EE_Dependency_Map) {
133
-            self::$_instance = new EE_Dependency_Map(/*$request, $response, $legacy_request*/);
134
-        }
135
-        return self::$_instance;
136
-    }
137
-
138
-
139
-    /**
140
-     * @param RequestInterface $request
141
-     */
142
-    public function setRequest(RequestInterface $request)
143
-    {
144
-        $this->request = $request;
145
-    }
146
-
147
-
148
-    /**
149
-     * @param LegacyRequestInterface $legacy_request
150
-     */
151
-    public function setLegacyRequest(LegacyRequestInterface $legacy_request)
152
-    {
153
-        $this->legacy_request = $legacy_request;
154
-    }
155
-
156
-
157
-    /**
158
-     * @param ResponseInterface $response
159
-     */
160
-    public function setResponse(ResponseInterface $response)
161
-    {
162
-        $this->response = $response;
163
-    }
164
-
165
-
166
-
167
-    /**
168
-     * @param LoaderInterface $loader
169
-     */
170
-    public function setLoader(LoaderInterface $loader)
171
-    {
172
-        $this->loader = $loader;
173
-    }
174
-
175
-
176
-
177
-    /**
178
-     * @param string $class
179
-     * @param array  $dependencies
180
-     * @param int    $overwrite
181
-     * @return bool
182
-     */
183
-    public static function register_dependencies(
184
-        $class,
185
-        array $dependencies,
186
-        $overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
187
-    ) {
188
-        return self::$_instance->registerDependencies($class, $dependencies, $overwrite);
189
-    }
190
-
191
-
192
-
193
-    /**
194
-     * Assigns an array of class names and corresponding load sources (new or cached)
195
-     * to the class specified by the first parameter.
196
-     * IMPORTANT !!!
197
-     * The order of elements in the incoming $dependencies array MUST match
198
-     * the order of the constructor parameters for the class in question.
199
-     * This is especially important when overriding any existing dependencies that are registered.
200
-     * the third parameter controls whether any duplicate dependencies are overwritten or not.
201
-     *
202
-     * @param string $class
203
-     * @param array  $dependencies
204
-     * @param int    $overwrite
205
-     * @return bool
206
-     */
207
-    public function registerDependencies(
208
-        $class,
209
-        array $dependencies,
210
-        $overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
211
-    ) {
212
-        $class = trim($class, '\\');
213
-        $registered = false;
214
-        if (empty(self::$_instance->_dependency_map[ $class ])) {
215
-            self::$_instance->_dependency_map[ $class ] = array();
216
-        }
217
-        // we need to make sure that any aliases used when registering a dependency
218
-        // get resolved to the correct class name
219
-        foreach ($dependencies as $dependency => $load_source) {
220
-            $alias = self::$_instance->get_alias($dependency);
221
-            if (
222
-                $overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
223
-                || ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
224
-            ) {
225
-                unset($dependencies[$dependency]);
226
-                $dependencies[$alias] = $load_source;
227
-                $registered = true;
228
-            }
229
-        }
230
-        // now add our two lists of dependencies together.
231
-        // using Union (+=) favours the arrays in precedence from left to right,
232
-        // so $dependencies is NOT overwritten because it is listed first
233
-        // ie: with A = B + C, entries in B take precedence over duplicate entries in C
234
-        // Union is way faster than array_merge() but should be used with caution...
235
-        // especially with numerically indexed arrays
236
-        $dependencies += self::$_instance->_dependency_map[ $class ];
237
-        // now we need to ensure that the resulting dependencies
238
-        // array only has the entries that are required for the class
239
-        // so first count how many dependencies were originally registered for the class
240
-        $dependency_count = count(self::$_instance->_dependency_map[ $class ]);
241
-        // if that count is non-zero (meaning dependencies were already registered)
242
-        self::$_instance->_dependency_map[ $class ] = $dependency_count
243
-            // then truncate the  final array to match that count
244
-            ? array_slice($dependencies, 0, $dependency_count)
245
-            // otherwise just take the incoming array because nothing previously existed
246
-            : $dependencies;
247
-        return $registered;
248
-    }
249
-
250
-
251
-
252
-    /**
253
-     * @param string $class_name
254
-     * @param string $loader
255
-     * @return bool
256
-     * @throws DomainException
257
-     */
258
-    public static function register_class_loader($class_name, $loader = 'load_core')
259
-    {
260
-        if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
261
-            throw new DomainException(
262
-                esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
263
-            );
264
-        }
265
-        // check that loader is callable or method starts with "load_" and exists in EE_Registry
266
-        if (
267
-            ! is_callable($loader)
268
-            && (
269
-                strpos($loader, 'load_') !== 0
270
-                || ! method_exists('EE_Registry', $loader)
271
-            )
272
-        ) {
273
-            throw new DomainException(
274
-                sprintf(
275
-                    esc_html__(
276
-                        '"%1$s" is not a valid loader method on EE_Registry.',
277
-                        'event_espresso'
278
-                    ),
279
-                    $loader
280
-                )
281
-            );
282
-        }
283
-        $class_name = self::$_instance->get_alias($class_name);
284
-        if (! isset(self::$_instance->_class_loaders[$class_name])) {
285
-            self::$_instance->_class_loaders[$class_name] = $loader;
286
-            return true;
287
-        }
288
-        return false;
289
-    }
290
-
291
-
292
-
293
-    /**
294
-     * @return array
295
-     */
296
-    public function dependency_map()
297
-    {
298
-        return $this->_dependency_map;
299
-    }
300
-
301
-
302
-
303
-    /**
304
-     * returns TRUE if dependency map contains a listing for the provided class name
305
-     *
306
-     * @param string $class_name
307
-     * @return boolean
308
-     */
309
-    public function has($class_name = '')
310
-    {
311
-        // all legacy models have the same dependencies
312
-        if (strpos($class_name, 'EEM_') === 0) {
313
-            $class_name = 'LEGACY_MODELS';
314
-        }
315
-        return isset($this->_dependency_map[$class_name]) ? true : false;
316
-    }
317
-
318
-
319
-
320
-    /**
321
-     * returns TRUE if dependency map contains a listing for the provided class name AND dependency
322
-     *
323
-     * @param string $class_name
324
-     * @param string $dependency
325
-     * @return bool
326
-     */
327
-    public function has_dependency_for_class($class_name = '', $dependency = '')
328
-    {
329
-        // all legacy models have the same dependencies
330
-        if (strpos($class_name, 'EEM_') === 0) {
331
-            $class_name = 'LEGACY_MODELS';
332
-        }
333
-        $dependency = $this->get_alias($dependency);
334
-        return isset($this->_dependency_map[$class_name][$dependency])
335
-            ? true
336
-            : false;
337
-    }
338
-
339
-
340
-
341
-    /**
342
-     * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
343
-     *
344
-     * @param string $class_name
345
-     * @param string $dependency
346
-     * @return int
347
-     */
348
-    public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
349
-    {
350
-        // all legacy models have the same dependencies
351
-        if (strpos($class_name, 'EEM_') === 0) {
352
-            $class_name = 'LEGACY_MODELS';
353
-        }
354
-        $dependency = $this->get_alias($dependency);
355
-        return $this->has_dependency_for_class($class_name, $dependency)
356
-            ? $this->_dependency_map[$class_name][$dependency]
357
-            : EE_Dependency_Map::not_registered;
358
-    }
359
-
360
-
361
-
362
-    /**
363
-     * @param string $class_name
364
-     * @return string | Closure
365
-     */
366
-    public function class_loader($class_name)
367
-    {
368
-        // all legacy models use load_model()
369
-        if(strpos($class_name, 'EEM_') === 0){
370
-            return 'load_model';
371
-        }
372
-        $class_name = $this->get_alias($class_name);
373
-        return isset($this->_class_loaders[$class_name]) ? $this->_class_loaders[$class_name] : '';
374
-    }
375
-
376
-
377
-
378
-    /**
379
-     * @return array
380
-     */
381
-    public function class_loaders()
382
-    {
383
-        return $this->_class_loaders;
384
-    }
385
-
386
-
387
-
388
-    /**
389
-     * adds an alias for a classname
390
-     *
391
-     * @param string $class_name the class name that should be used (concrete class to replace interface)
392
-     * @param string $alias      the class name that would be type hinted for (abstract parent or interface)
393
-     * @param string $for_class  the class that has the dependency (is type hinting for the interface)
394
-     */
395
-    public function add_alias($class_name, $alias, $for_class = '')
396
-    {
397
-        if ($for_class !== '') {
398
-            if (! isset($this->_aliases[$for_class])) {
399
-                $this->_aliases[$for_class] = array();
400
-            }
401
-            $this->_aliases[$for_class][$class_name] = $alias;
402
-        }
403
-        $this->_aliases[$class_name] = $alias;
404
-    }
405
-
406
-
407
-
408
-    /**
409
-     * returns TRUE if the provided class name has an alias
410
-     *
411
-     * @param string $class_name
412
-     * @param string $for_class
413
-     * @return bool
414
-     */
415
-    public function has_alias($class_name = '', $for_class = '')
416
-    {
417
-        return isset($this->_aliases[$for_class][$class_name])
418
-               || (
419
-                   isset($this->_aliases[$class_name])
420
-                   && ! is_array($this->_aliases[$class_name])
421
-               );
422
-    }
423
-
424
-
425
-
426
-    /**
427
-     * returns alias for class name if one exists, otherwise returns the original classname
428
-     * functions recursively, so that multiple aliases can be used to drill down to a classname
429
-     *  for example:
430
-     *      if the following two entries were added to the _aliases array:
431
-     *          array(
432
-     *              'interface_alias'           => 'some\namespace\interface'
433
-     *              'some\namespace\interface'  => 'some\namespace\classname'
434
-     *          )
435
-     *      then one could use EE_Registry::instance()->create( 'interface_alias' )
436
-     *      to load an instance of 'some\namespace\classname'
437
-     *
438
-     * @param string $class_name
439
-     * @param string $for_class
440
-     * @return string
441
-     */
442
-    public function get_alias($class_name = '', $for_class = '')
443
-    {
444
-        if (! $this->has_alias($class_name, $for_class)) {
445
-            return $class_name;
446
-        }
447
-        if ($for_class !== '' && isset($this->_aliases[ $for_class ][ $class_name ])) {
448
-            return $this->get_alias($this->_aliases[$for_class][$class_name], $for_class);
449
-        }
450
-        return $this->get_alias($this->_aliases[$class_name]);
451
-    }
452
-
453
-
454
-
455
-    /**
456
-     * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
457
-     * if one exists, or whether a new object should be generated every time the requested class is loaded.
458
-     * This is done by using the following class constants:
459
-     *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
460
-     *        EE_Dependency_Map::load_new_object - generates a new object every time
461
-     */
462
-    protected function _register_core_dependencies()
463
-    {
464
-        $this->_dependency_map = array(
465
-            'EE_Request_Handler'                                                                                          => array(
466
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
467
-            ),
468
-            'EE_System'                                                                                                   => array(
469
-                'EE_Registry'                                 => EE_Dependency_Map::load_from_cache,
470
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
471
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
472
-                'EE_Maintenance_Mode'                         => EE_Dependency_Map::load_from_cache,
473
-            ),
474
-            'EE_Session'                                                                                                  => array(
475
-                'EventEspresso\core\services\cache\TransientCacheStorage'  => EE_Dependency_Map::load_from_cache,
476
-                'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
477
-                'EventEspresso\core\services\request\Request'              => EE_Dependency_Map::load_from_cache,
478
-                'EE_Encryption'                                            => EE_Dependency_Map::load_from_cache,
479
-            ),
480
-            'EE_Cart'                                                                                                     => array(
481
-                'EE_Session' => EE_Dependency_Map::load_from_cache,
482
-            ),
483
-            'EE_Front_Controller'                                                                                         => array(
484
-                'EE_Registry'              => EE_Dependency_Map::load_from_cache,
485
-                'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
486
-                'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
487
-            ),
488
-            'EE_Messenger_Collection_Loader'                                                                              => array(
489
-                'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
490
-            ),
491
-            'EE_Message_Type_Collection_Loader'                                                                           => array(
492
-                'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
493
-            ),
494
-            'EE_Message_Resource_Manager'                                                                                 => array(
495
-                'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
496
-                'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
497
-                'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
498
-            ),
499
-            'EE_Message_Factory'                                                                                          => array(
500
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
501
-            ),
502
-            'EE_messages'                                                                                                 => array(
503
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
504
-            ),
505
-            'EE_Messages_Generator'                                                                                       => array(
506
-                'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
507
-                'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
508
-                'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
509
-                'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
510
-            ),
511
-            'EE_Messages_Processor'                                                                                       => array(
512
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
513
-            ),
514
-            'EE_Messages_Queue'                                                                                           => array(
515
-                'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
516
-            ),
517
-            'EE_Messages_Template_Defaults'                                                                               => array(
518
-                'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
519
-                'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
520
-            ),
521
-            'EE_Message_To_Generate_From_Request'                                                                         => array(
522
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
523
-                'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
524
-            ),
525
-            'EventEspresso\core\services\commands\CommandBus'                                                             => array(
526
-                'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
527
-            ),
528
-            'EventEspresso\services\commands\CommandHandler'                                                              => array(
529
-                'EE_Registry'         => EE_Dependency_Map::load_from_cache,
530
-                'CommandBusInterface' => EE_Dependency_Map::load_from_cache,
531
-            ),
532
-            'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
533
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
534
-            ),
535
-            'EventEspresso\core\services\commands\CompositeCommandHandler'                                                => array(
536
-                'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
537
-                'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
538
-            ),
539
-            'EventEspresso\core\services\commands\CommandFactory'                                                         => array(
540
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
541
-            ),
542
-            'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
543
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
544
-            ),
545
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
546
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
547
-            ),
548
-            'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
549
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
550
-            ),
551
-            'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
552
-                'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
553
-            ),
554
-            'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
555
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
556
-            ),
557
-            'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
558
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
559
-            ),
560
-            'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
561
-                'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
562
-            ),
563
-            'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
564
-                'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
565
-            ),
566
-            'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
567
-                'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
568
-            ),
569
-            'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
570
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
571
-            ),
572
-            'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
573
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
574
-            ),
575
-            'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
576
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
577
-            ),
578
-            'EventEspresso\core\services\database\TableManager'                                                           => array(
579
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
580
-            ),
581
-            'EE_Data_Migration_Class_Base'                                                                                => array(
582
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
583
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
584
-            ),
585
-            'EE_DMS_Core_4_1_0'                                                                                           => array(
586
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
587
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
588
-            ),
589
-            'EE_DMS_Core_4_2_0'                                                                                           => array(
590
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
591
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
592
-            ),
593
-            'EE_DMS_Core_4_3_0'                                                                                           => array(
594
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
595
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
596
-            ),
597
-            'EE_DMS_Core_4_4_0'                                                                                           => array(
598
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
599
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
600
-            ),
601
-            'EE_DMS_Core_4_5_0'                                                                                           => array(
602
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
603
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
604
-            ),
605
-            'EE_DMS_Core_4_6_0'                                                                                           => array(
606
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
607
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
608
-            ),
609
-            'EE_DMS_Core_4_7_0'                                                                                           => array(
610
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
611
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
612
-            ),
613
-            'EE_DMS_Core_4_8_0'                                                                                           => array(
614
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
615
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
616
-            ),
617
-            'EE_DMS_Core_4_9_0'                                                                                           => array(
618
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
619
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
620
-            ),
621
-            'EventEspresso\core\services\assets\I18nRegistry' => array(
622
-                array(),
623
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache
624
-            ),
625
-            'EventEspresso\core\services\assets\Registry'                                                                 => array(
626
-                'EE_Template_Config' => EE_Dependency_Map::load_from_cache,
627
-                'EE_Currency_Config' => EE_Dependency_Map::load_from_cache,
628
-                'EventEspresso\core\services\assets\I18nRegistry' => EE_Dependency_Map::load_from_cache,
629
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache
630
-            ),
631
-            'EventEspresso\core\domain\entities\shortcodes\EspressoCancelled'                                             => array(
632
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
633
-            ),
634
-            'EventEspresso\core\domain\entities\shortcodes\EspressoCheckout'                                              => array(
635
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
636
-            ),
637
-            'EventEspresso\core\domain\entities\shortcodes\EspressoEventAttendees'                                        => array(
638
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
639
-            ),
640
-            'EventEspresso\core\domain\entities\shortcodes\EspressoEvents'                                                => array(
641
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
642
-            ),
643
-            'EventEspresso\core\domain\entities\shortcodes\EspressoThankYou'                                              => array(
644
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
645
-            ),
646
-            'EventEspresso\core\domain\entities\shortcodes\EspressoTicketSelector'                                        => array(
647
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
648
-            ),
649
-            'EventEspresso\core\domain\entities\shortcodes\EspressoTxnPage'                                               => array(
650
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
651
-            ),
652
-            'EventEspresso\core\services\cache\BasicCacheManager'                        => array(
653
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
654
-            ),
655
-            'EventEspresso\core\services\cache\PostRelatedCacheManager'                  => array(
656
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
657
-            ),
658
-            'EventEspresso\core\domain\services\validation\email\EmailValidationService' => array(
659
-                'EE_Registration_Config'                                  => EE_Dependency_Map::load_from_cache,
660
-                'EventEspresso\core\services\loaders\Loader'              => EE_Dependency_Map::load_from_cache,
661
-            ),
662
-            'EventEspresso\core\domain\values\EmailAddress'                              => array(
663
-                null,
664
-                'EventEspresso\core\domain\services\validation\email\EmailValidationService' => EE_Dependency_Map::load_from_cache,
665
-            ),
666
-            'EventEspresso\core\services\orm\ModelFieldFactory' => array(
667
-                'EventEspresso\core\services\loaders\Loader'              => EE_Dependency_Map::load_from_cache,
668
-            ),
669
-            'LEGACY_MODELS'                                                   => array(
670
-                null,
671
-                'EventEspresso\core\services\database\ModelFieldFactory' => EE_Dependency_Map::load_from_cache,
672
-            ),
673
-            'EE_Module_Request_Router'                                               => array(
674
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
675
-            ),
676
-            'EE_Registration_Processor'                                              => array(
677
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
678
-            ),
679
-            'EventEspresso\core\services\notifications\PersistentAdminNoticeManager' => array(
680
-                null,
681
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
682
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
683
-            ),
684
-            'EventEspresso\core\services\editor\EditorBlockRegistrationManager'      => array(
685
-                'EventEspresso\core\domain\entities\editor\EditorBlockCollection' => EE_Dependency_Map::load_from_cache,
686
-                'EE_Request'                                                      => EE_Dependency_Map::load_from_cache,
687
-                'EventEspresso\core\domain\Domain'                                => EE_Dependency_Map::load_from_cache,
688
-                'EventEspresso\core\services\assets\Registry' => EE_Dependency_Map::load_from_cache
689
-            ),
690
-            'EE_Admin_Transactions_List_Table' => array(
691
-                null,
692
-                'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
693
-            ),
694
-            'EventEspresso\core\services\licensing\LicenseService' => array(
695
-                'EventEspresso\core\domain\services\pue\Stats' => EE_Dependency_Map::load_from_cache,
696
-                'EventEspresso\core\domain\services\pue\Config' => EE_Dependency_Map::load_from_cache
697
-            ),
698
-            'EventEspresso\core\domain\services\pue\Stats' => array(
699
-                'EventEspresso\core\domain\services\pue\Config' => EE_Dependency_Map::load_from_cache,
700
-                'EE_Maintenance_Mode' => EE_Dependency_Map::load_from_cache,
701
-                'EventEspresso\core\domain\services\pue\StatsGatherer' => EE_Dependency_Map::load_from_cache
702
-            ),
703
-            'EventEspresso\core\domain\services\pue\Config' => array(
704
-                'EE_Network_Config' => EE_Dependency_Map::load_from_cache,
705
-                'EE_Config' => EE_Dependency_Map::load_from_cache
706
-            ),
707
-            'EventEspresso\core\domain\services\pue\StatsGatherer' => array(
708
-                'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
709
-                'EEM_Event' => EE_Dependency_Map::load_from_cache,
710
-                'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
711
-                'EEM_Ticket' => EE_Dependency_Map::load_from_cache,
712
-                'EEM_Registration' => EE_Dependency_Map::load_from_cache,
713
-                'EEM_Transaction' => EE_Dependency_Map::load_from_cache,
714
-                'EE_Config' => EE_Dependency_Map::load_from_cache
715
-            ),
716
-            'EventEspresso\core\domain\services\admin\ExitModal' => array(
717
-                'EventEspresso\core\services\assets\Registry' => EE_Dependency_Map::load_from_cache
718
-            ),
719
-            'EventEspresso\core\domain\services\admin\PluginUpsells' => array(
720
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache
721
-            ),
722
-            'EventEspresso\caffeinated\modules\recaptcha_invisible\InvisibleRecaptcha' => array(
723
-                'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
724
-                'EE_Session'             => EE_Dependency_Map::load_from_cache,
725
-            ),
726
-            'EventEspresso\caffeinated\modules\recaptcha_invisible\RecaptchaAdminSettings' => array(
727
-                'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
728
-            ),
729
-            'EventEspresso\modules\ticket_selector\ProcessTicketSelector' => array(
730
-                'EE_Core_Config' => EE_Dependency_Map::load_from_cache,
731
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
732
-                'EE_Session' => EE_Dependency_Map::load_from_cache,
733
-                'EEM_Ticket' => EE_Dependency_Map::load_from_cache,
734
-                'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker' => EE_Dependency_Map::load_from_cache,
735
-            ),
736
-            'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker' => array(
737
-                'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
738
-            ),
739
-            'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => array(
740
-                'EE_Core_Config' => EE_Dependency_Map::load_from_cache,
741
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
742
-            ),
743
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'   => array(
744
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
745
-            ),
746
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'   => array(
747
-                'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
748
-            ),
749
-            'EE_CPT_Strategy'   => array(
750
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
751
-                'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
752
-            ),
753
-        );
754
-    }
755
-
756
-
757
-
758
-    /**
759
-     * Registers how core classes are loaded.
760
-     * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
761
-     *        'EE_Request_Handler' => 'load_core'
762
-     *        'EE_Messages_Queue'  => 'load_lib'
763
-     *        'EEH_Debug_Tools'    => 'load_helper'
764
-     * or, if greater control is required, by providing a custom closure. For example:
765
-     *        'Some_Class' => function () {
766
-     *            return new Some_Class();
767
-     *        },
768
-     * This is required for instantiating dependencies
769
-     * where an interface has been type hinted in a class constructor. For example:
770
-     *        'Required_Interface' => function () {
771
-     *            return new A_Class_That_Implements_Required_Interface();
772
-     *        },
773
-     *
774
-     * @throws InvalidInterfaceException
775
-     * @throws InvalidDataTypeException
776
-     * @throws InvalidArgumentException
777
-     */
778
-    protected function _register_core_class_loaders()
779
-    {
780
-        //for PHP5.3 compat, we need to register any properties called here in a variable because `$this` cannot
781
-        //be used in a closure.
782
-        $request = &$this->request;
783
-        $response = &$this->response;
784
-        $legacy_request = &$this->legacy_request;
785
-        // $loader = &$this->loader;
786
-        $this->_class_loaders = array(
787
-            //load_core
788
-            'EE_Capabilities'          => 'load_core',
789
-            'EE_Encryption'            => 'load_core',
790
-            'EE_Front_Controller'      => 'load_core',
791
-            'EE_Module_Request_Router' => 'load_core',
792
-            'EE_Registry'              => 'load_core',
793
-            'EE_Request'               => function () use (&$legacy_request) {
794
-                return $legacy_request;
795
-            },
796
-            'EventEspresso\core\services\request\Request' => function () use (&$request) {
797
-                return $request;
798
-            },
799
-            'EventEspresso\core\services\request\Response' => function () use (&$response) {
800
-                return $response;
801
-            },
802
-            'EE_Request_Handler'       => 'load_core',
803
-            'EE_Session'               => 'load_core',
804
-            'EE_Cron_Tasks'            => 'load_core',
805
-            'EE_System'                => 'load_core',
806
-            'EE_Maintenance_Mode'      => 'load_core',
807
-            'EE_Register_CPTs'         => 'load_core',
808
-            'EE_Admin'                 => 'load_core',
809
-            'EE_CPT_Strategy'          => 'load_core',
810
-            //load_lib
811
-            'EE_Message_Resource_Manager'          => 'load_lib',
812
-            'EE_Message_Type_Collection'           => 'load_lib',
813
-            'EE_Message_Type_Collection_Loader'    => 'load_lib',
814
-            'EE_Messenger_Collection'              => 'load_lib',
815
-            'EE_Messenger_Collection_Loader'       => 'load_lib',
816
-            'EE_Messages_Processor'                => 'load_lib',
817
-            'EE_Message_Repository'                => 'load_lib',
818
-            'EE_Messages_Queue'                    => 'load_lib',
819
-            'EE_Messages_Data_Handler_Collection'  => 'load_lib',
820
-            'EE_Message_Template_Group_Collection' => 'load_lib',
821
-            'EE_Payment_Method_Manager'            => 'load_lib',
822
-            'EE_Messages_Generator'                => function () {
823
-                return EE_Registry::instance()->load_lib(
824
-                    'Messages_Generator',
825
-                    array(),
826
-                    false,
827
-                    false
828
-                );
829
-            },
830
-            'EE_Messages_Template_Defaults'        => function ($arguments = array()) {
831
-                return EE_Registry::instance()->load_lib(
832
-                    'Messages_Template_Defaults',
833
-                    $arguments,
834
-                    false,
835
-                    false
836
-                );
837
-            },
838
-            //load_helper
839
-            'EEH_Parse_Shortcodes'                 => function () {
840
-                if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
841
-                    return new EEH_Parse_Shortcodes();
842
-                }
843
-                return null;
844
-            },
845
-            'EE_Template_Config'                   => function () {
846
-                return EE_Config::instance()->template_settings;
847
-            },
848
-            'EE_Currency_Config'                   => function () {
849
-                return EE_Config::instance()->currency;
850
-            },
851
-            'EE_Registration_Config'                   => function () {
852
-                return EE_Config::instance()->registration;
853
-            },
854
-            'EE_Core_Config'                   => function () {
855
-                return EE_Config::instance()->core;
856
-            },
857
-            'EventEspresso\core\services\loaders\Loader' => function () {
858
-                return LoaderFactory::getLoader();
859
-            },
860
-            'EE_Network_Config' => function() {
861
-                return EE_Network_Config::instance();
862
-            },
863
-            'EE_Config' => function () {
864
-                return EE_Config::instance();
865
-            }
866
-        );
867
-    }
868
-
869
-
870
-
871
-    /**
872
-     * can be used for supplying alternate names for classes,
873
-     * or for connecting interface names to instantiable classes
874
-     */
875
-    protected function _register_core_aliases()
876
-    {
877
-        $this->_aliases = array(
878
-            'CommandBusInterface'                                                          => 'EventEspresso\core\services\commands\CommandBusInterface',
879
-            'EventEspresso\core\services\commands\CommandBusInterface'                     => 'EventEspresso\core\services\commands\CommandBus',
880
-            'CommandHandlerManagerInterface'                                               => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
881
-            'EventEspresso\core\services\commands\CommandHandlerManagerInterface'          => 'EventEspresso\core\services\commands\CommandHandlerManager',
882
-            'CapChecker'                                                                   => 'EventEspresso\core\services\commands\middleware\CapChecker',
883
-            'AddActionHook'                                                                => 'EventEspresso\core\services\commands\middleware\AddActionHook',
884
-            'CapabilitiesChecker'                                                          => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
885
-            'CapabilitiesCheckerInterface'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
886
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
887
-            'CreateRegistrationService'                                                    => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
888
-            'CreateRegCodeCommandHandler'                                                  => 'EventEspresso\core\services\commands\registration\CreateRegCodeCommand',
889
-            'CreateRegUrlLinkCommandHandler'                                               => 'EventEspresso\core\services\commands\registration\CreateRegUrlLinkCommand',
890
-            'CreateRegistrationCommandHandler'                                             => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
891
-            'CopyRegistrationDetailsCommandHandler'                                        => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
892
-            'CopyRegistrationPaymentsCommandHandler'                                       => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
893
-            'CancelRegistrationAndTicketLineItemCommandHandler'                            => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
894
-            'UpdateRegistrationAndTransactionAfterChangeCommandHandler'                    => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
895
-            'CreateTicketLineItemCommandHandler'                                           => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
896
-            'CreateTransactionCommandHandler'                                     => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
897
-            'CreateAttendeeCommandHandler'                                        => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
898
-            'TableManager'                                                                 => 'EventEspresso\core\services\database\TableManager',
899
-            'TableAnalysis'                                                                => 'EventEspresso\core\services\database\TableAnalysis',
900
-            'EspressoShortcode'                                                            => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
901
-            'ShortcodeInterface'                                                           => 'EventEspresso\core\services\shortcodes\ShortcodeInterface',
902
-            'EventEspresso\core\services\shortcodes\ShortcodeInterface'                    => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
903
-            'EventEspresso\core\services\cache\CacheStorageInterface'                      => 'EventEspresso\core\services\cache\TransientCacheStorage',
904
-            'LoaderInterface'                                                              => 'EventEspresso\core\services\loaders\LoaderInterface',
905
-            'EventEspresso\core\services\loaders\LoaderInterface'                          => 'EventEspresso\core\services\loaders\Loader',
906
-            'CommandFactoryInterface'                                                     => 'EventEspresso\core\services\commands\CommandFactoryInterface',
907
-            'EventEspresso\core\services\commands\CommandFactoryInterface'                => 'EventEspresso\core\services\commands\CommandFactory',
908
-            'EventEspresso\core\domain\services\session\SessionIdentifierInterface'       => 'EE_Session',
909
-            'EmailValidatorInterface'                                                     => 'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface',
910
-            'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface' => 'EventEspresso\core\domain\services\validation\email\EmailValidationService',
911
-            'NoticeConverterInterface'                                            => 'EventEspresso\core\services\notices\NoticeConverterInterface',
912
-            'EventEspresso\core\services\notices\NoticeConverterInterface'        => 'EventEspresso\core\services\notices\ConvertNoticesToEeErrors',
913
-            'NoticesContainerInterface'                                           => 'EventEspresso\core\services\notices\NoticesContainerInterface',
914
-            'EventEspresso\core\services\notices\NoticesContainerInterface'       => 'EventEspresso\core\services\notices\NoticesContainer',
915
-            'EventEspresso\core\services\request\RequestInterface'                => 'EventEspresso\core\services\request\Request',
916
-            'EventEspresso\core\services\request\ResponseInterface'               => 'EventEspresso\core\services\request\Response',
917
-            'EventEspresso\core\domain\DomainInterface'                           => 'EventEspresso\core\domain\Domain',
918
-        );
919
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
920
-            $this->_aliases['EventEspresso\core\services\notices\NoticeConverterInterface'] = 'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices';
921
-        }
922
-    }
923
-
924
-
925
-
926
-    /**
927
-     * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
928
-     * request Primarily used by unit tests.
929
-     *
930
-     * @throws InvalidDataTypeException
931
-     * @throws InvalidInterfaceException
932
-     * @throws InvalidArgumentException
933
-     */
934
-    public function reset()
935
-    {
936
-        $this->_register_core_class_loaders();
937
-        $this->_register_core_dependencies();
938
-    }
28
+	/**
29
+	 * This means that the requested class dependency is not present in the dependency map
30
+	 */
31
+	const not_registered = 0;
32
+
33
+	/**
34
+	 * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
35
+	 */
36
+	const load_new_object = 1;
37
+
38
+	/**
39
+	 * This instructs class loaders to return a previously instantiated and cached object for the requested class.
40
+	 * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
41
+	 */
42
+	const load_from_cache = 2;
43
+
44
+	/**
45
+	 * When registering a dependency,
46
+	 * this indicates to keep any existing dependencies that already exist,
47
+	 * and simply discard any new dependencies declared in the incoming data
48
+	 */
49
+	const KEEP_EXISTING_DEPENDENCIES = 0;
50
+
51
+	/**
52
+	 * When registering a dependency,
53
+	 * this indicates to overwrite any existing dependencies that already exist using the incoming data
54
+	 */
55
+	const OVERWRITE_DEPENDENCIES = 1;
56
+
57
+
58
+
59
+	/**
60
+	 * @type EE_Dependency_Map $_instance
61
+	 */
62
+	protected static $_instance;
63
+
64
+	/**
65
+	 * @type RequestInterface $request
66
+	 */
67
+	protected $request;
68
+
69
+	/**
70
+	 * @type LegacyRequestInterface $legacy_request
71
+	 */
72
+	protected $legacy_request;
73
+
74
+	/**
75
+	 * @type ResponseInterface $response
76
+	 */
77
+	protected $response;
78
+
79
+	/**
80
+	 * @type LoaderInterface $loader
81
+	 */
82
+	protected $loader;
83
+
84
+	/**
85
+	 * @type array $_dependency_map
86
+	 */
87
+	protected $_dependency_map = array();
88
+
89
+	/**
90
+	 * @type array $_class_loaders
91
+	 */
92
+	protected $_class_loaders = array();
93
+
94
+	/**
95
+	 * @type array $_aliases
96
+	 */
97
+	protected $_aliases = array();
98
+
99
+
100
+
101
+	/**
102
+	 * EE_Dependency_Map constructor.
103
+	 */
104
+	protected function __construct()
105
+	{
106
+		// add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
107
+		do_action('EE_Dependency_Map____construct');
108
+	}
109
+
110
+
111
+
112
+	/**
113
+	 * @throws InvalidDataTypeException
114
+	 * @throws InvalidInterfaceException
115
+	 * @throws InvalidArgumentException
116
+	 */
117
+	public function initialize()
118
+	{
119
+		$this->_register_core_dependencies();
120
+		$this->_register_core_class_loaders();
121
+		$this->_register_core_aliases();
122
+	}
123
+
124
+
125
+
126
+	/**
127
+	 * @singleton method used to instantiate class object
128
+	 * @return EE_Dependency_Map
129
+	 */
130
+	public static function instance() {
131
+		// check if class object is instantiated, and instantiated properly
132
+		if (! self::$_instance instanceof EE_Dependency_Map) {
133
+			self::$_instance = new EE_Dependency_Map(/*$request, $response, $legacy_request*/);
134
+		}
135
+		return self::$_instance;
136
+	}
137
+
138
+
139
+	/**
140
+	 * @param RequestInterface $request
141
+	 */
142
+	public function setRequest(RequestInterface $request)
143
+	{
144
+		$this->request = $request;
145
+	}
146
+
147
+
148
+	/**
149
+	 * @param LegacyRequestInterface $legacy_request
150
+	 */
151
+	public function setLegacyRequest(LegacyRequestInterface $legacy_request)
152
+	{
153
+		$this->legacy_request = $legacy_request;
154
+	}
155
+
156
+
157
+	/**
158
+	 * @param ResponseInterface $response
159
+	 */
160
+	public function setResponse(ResponseInterface $response)
161
+	{
162
+		$this->response = $response;
163
+	}
164
+
165
+
166
+
167
+	/**
168
+	 * @param LoaderInterface $loader
169
+	 */
170
+	public function setLoader(LoaderInterface $loader)
171
+	{
172
+		$this->loader = $loader;
173
+	}
174
+
175
+
176
+
177
+	/**
178
+	 * @param string $class
179
+	 * @param array  $dependencies
180
+	 * @param int    $overwrite
181
+	 * @return bool
182
+	 */
183
+	public static function register_dependencies(
184
+		$class,
185
+		array $dependencies,
186
+		$overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
187
+	) {
188
+		return self::$_instance->registerDependencies($class, $dependencies, $overwrite);
189
+	}
190
+
191
+
192
+
193
+	/**
194
+	 * Assigns an array of class names and corresponding load sources (new or cached)
195
+	 * to the class specified by the first parameter.
196
+	 * IMPORTANT !!!
197
+	 * The order of elements in the incoming $dependencies array MUST match
198
+	 * the order of the constructor parameters for the class in question.
199
+	 * This is especially important when overriding any existing dependencies that are registered.
200
+	 * the third parameter controls whether any duplicate dependencies are overwritten or not.
201
+	 *
202
+	 * @param string $class
203
+	 * @param array  $dependencies
204
+	 * @param int    $overwrite
205
+	 * @return bool
206
+	 */
207
+	public function registerDependencies(
208
+		$class,
209
+		array $dependencies,
210
+		$overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
211
+	) {
212
+		$class = trim($class, '\\');
213
+		$registered = false;
214
+		if (empty(self::$_instance->_dependency_map[ $class ])) {
215
+			self::$_instance->_dependency_map[ $class ] = array();
216
+		}
217
+		// we need to make sure that any aliases used when registering a dependency
218
+		// get resolved to the correct class name
219
+		foreach ($dependencies as $dependency => $load_source) {
220
+			$alias = self::$_instance->get_alias($dependency);
221
+			if (
222
+				$overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
223
+				|| ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
224
+			) {
225
+				unset($dependencies[$dependency]);
226
+				$dependencies[$alias] = $load_source;
227
+				$registered = true;
228
+			}
229
+		}
230
+		// now add our two lists of dependencies together.
231
+		// using Union (+=) favours the arrays in precedence from left to right,
232
+		// so $dependencies is NOT overwritten because it is listed first
233
+		// ie: with A = B + C, entries in B take precedence over duplicate entries in C
234
+		// Union is way faster than array_merge() but should be used with caution...
235
+		// especially with numerically indexed arrays
236
+		$dependencies += self::$_instance->_dependency_map[ $class ];
237
+		// now we need to ensure that the resulting dependencies
238
+		// array only has the entries that are required for the class
239
+		// so first count how many dependencies were originally registered for the class
240
+		$dependency_count = count(self::$_instance->_dependency_map[ $class ]);
241
+		// if that count is non-zero (meaning dependencies were already registered)
242
+		self::$_instance->_dependency_map[ $class ] = $dependency_count
243
+			// then truncate the  final array to match that count
244
+			? array_slice($dependencies, 0, $dependency_count)
245
+			// otherwise just take the incoming array because nothing previously existed
246
+			: $dependencies;
247
+		return $registered;
248
+	}
249
+
250
+
251
+
252
+	/**
253
+	 * @param string $class_name
254
+	 * @param string $loader
255
+	 * @return bool
256
+	 * @throws DomainException
257
+	 */
258
+	public static function register_class_loader($class_name, $loader = 'load_core')
259
+	{
260
+		if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
261
+			throw new DomainException(
262
+				esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
263
+			);
264
+		}
265
+		// check that loader is callable or method starts with "load_" and exists in EE_Registry
266
+		if (
267
+			! is_callable($loader)
268
+			&& (
269
+				strpos($loader, 'load_') !== 0
270
+				|| ! method_exists('EE_Registry', $loader)
271
+			)
272
+		) {
273
+			throw new DomainException(
274
+				sprintf(
275
+					esc_html__(
276
+						'"%1$s" is not a valid loader method on EE_Registry.',
277
+						'event_espresso'
278
+					),
279
+					$loader
280
+				)
281
+			);
282
+		}
283
+		$class_name = self::$_instance->get_alias($class_name);
284
+		if (! isset(self::$_instance->_class_loaders[$class_name])) {
285
+			self::$_instance->_class_loaders[$class_name] = $loader;
286
+			return true;
287
+		}
288
+		return false;
289
+	}
290
+
291
+
292
+
293
+	/**
294
+	 * @return array
295
+	 */
296
+	public function dependency_map()
297
+	{
298
+		return $this->_dependency_map;
299
+	}
300
+
301
+
302
+
303
+	/**
304
+	 * returns TRUE if dependency map contains a listing for the provided class name
305
+	 *
306
+	 * @param string $class_name
307
+	 * @return boolean
308
+	 */
309
+	public function has($class_name = '')
310
+	{
311
+		// all legacy models have the same dependencies
312
+		if (strpos($class_name, 'EEM_') === 0) {
313
+			$class_name = 'LEGACY_MODELS';
314
+		}
315
+		return isset($this->_dependency_map[$class_name]) ? true : false;
316
+	}
317
+
318
+
319
+
320
+	/**
321
+	 * returns TRUE if dependency map contains a listing for the provided class name AND dependency
322
+	 *
323
+	 * @param string $class_name
324
+	 * @param string $dependency
325
+	 * @return bool
326
+	 */
327
+	public function has_dependency_for_class($class_name = '', $dependency = '')
328
+	{
329
+		// all legacy models have the same dependencies
330
+		if (strpos($class_name, 'EEM_') === 0) {
331
+			$class_name = 'LEGACY_MODELS';
332
+		}
333
+		$dependency = $this->get_alias($dependency);
334
+		return isset($this->_dependency_map[$class_name][$dependency])
335
+			? true
336
+			: false;
337
+	}
338
+
339
+
340
+
341
+	/**
342
+	 * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
343
+	 *
344
+	 * @param string $class_name
345
+	 * @param string $dependency
346
+	 * @return int
347
+	 */
348
+	public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
349
+	{
350
+		// all legacy models have the same dependencies
351
+		if (strpos($class_name, 'EEM_') === 0) {
352
+			$class_name = 'LEGACY_MODELS';
353
+		}
354
+		$dependency = $this->get_alias($dependency);
355
+		return $this->has_dependency_for_class($class_name, $dependency)
356
+			? $this->_dependency_map[$class_name][$dependency]
357
+			: EE_Dependency_Map::not_registered;
358
+	}
359
+
360
+
361
+
362
+	/**
363
+	 * @param string $class_name
364
+	 * @return string | Closure
365
+	 */
366
+	public function class_loader($class_name)
367
+	{
368
+		// all legacy models use load_model()
369
+		if(strpos($class_name, 'EEM_') === 0){
370
+			return 'load_model';
371
+		}
372
+		$class_name = $this->get_alias($class_name);
373
+		return isset($this->_class_loaders[$class_name]) ? $this->_class_loaders[$class_name] : '';
374
+	}
375
+
376
+
377
+
378
+	/**
379
+	 * @return array
380
+	 */
381
+	public function class_loaders()
382
+	{
383
+		return $this->_class_loaders;
384
+	}
385
+
386
+
387
+
388
+	/**
389
+	 * adds an alias for a classname
390
+	 *
391
+	 * @param string $class_name the class name that should be used (concrete class to replace interface)
392
+	 * @param string $alias      the class name that would be type hinted for (abstract parent or interface)
393
+	 * @param string $for_class  the class that has the dependency (is type hinting for the interface)
394
+	 */
395
+	public function add_alias($class_name, $alias, $for_class = '')
396
+	{
397
+		if ($for_class !== '') {
398
+			if (! isset($this->_aliases[$for_class])) {
399
+				$this->_aliases[$for_class] = array();
400
+			}
401
+			$this->_aliases[$for_class][$class_name] = $alias;
402
+		}
403
+		$this->_aliases[$class_name] = $alias;
404
+	}
405
+
406
+
407
+
408
+	/**
409
+	 * returns TRUE if the provided class name has an alias
410
+	 *
411
+	 * @param string $class_name
412
+	 * @param string $for_class
413
+	 * @return bool
414
+	 */
415
+	public function has_alias($class_name = '', $for_class = '')
416
+	{
417
+		return isset($this->_aliases[$for_class][$class_name])
418
+			   || (
419
+				   isset($this->_aliases[$class_name])
420
+				   && ! is_array($this->_aliases[$class_name])
421
+			   );
422
+	}
423
+
424
+
425
+
426
+	/**
427
+	 * returns alias for class name if one exists, otherwise returns the original classname
428
+	 * functions recursively, so that multiple aliases can be used to drill down to a classname
429
+	 *  for example:
430
+	 *      if the following two entries were added to the _aliases array:
431
+	 *          array(
432
+	 *              'interface_alias'           => 'some\namespace\interface'
433
+	 *              'some\namespace\interface'  => 'some\namespace\classname'
434
+	 *          )
435
+	 *      then one could use EE_Registry::instance()->create( 'interface_alias' )
436
+	 *      to load an instance of 'some\namespace\classname'
437
+	 *
438
+	 * @param string $class_name
439
+	 * @param string $for_class
440
+	 * @return string
441
+	 */
442
+	public function get_alias($class_name = '', $for_class = '')
443
+	{
444
+		if (! $this->has_alias($class_name, $for_class)) {
445
+			return $class_name;
446
+		}
447
+		if ($for_class !== '' && isset($this->_aliases[ $for_class ][ $class_name ])) {
448
+			return $this->get_alias($this->_aliases[$for_class][$class_name], $for_class);
449
+		}
450
+		return $this->get_alias($this->_aliases[$class_name]);
451
+	}
452
+
453
+
454
+
455
+	/**
456
+	 * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
457
+	 * if one exists, or whether a new object should be generated every time the requested class is loaded.
458
+	 * This is done by using the following class constants:
459
+	 *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
460
+	 *        EE_Dependency_Map::load_new_object - generates a new object every time
461
+	 */
462
+	protected function _register_core_dependencies()
463
+	{
464
+		$this->_dependency_map = array(
465
+			'EE_Request_Handler'                                                                                          => array(
466
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
467
+			),
468
+			'EE_System'                                                                                                   => array(
469
+				'EE_Registry'                                 => EE_Dependency_Map::load_from_cache,
470
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
471
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
472
+				'EE_Maintenance_Mode'                         => EE_Dependency_Map::load_from_cache,
473
+			),
474
+			'EE_Session'                                                                                                  => array(
475
+				'EventEspresso\core\services\cache\TransientCacheStorage'  => EE_Dependency_Map::load_from_cache,
476
+				'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
477
+				'EventEspresso\core\services\request\Request'              => EE_Dependency_Map::load_from_cache,
478
+				'EE_Encryption'                                            => EE_Dependency_Map::load_from_cache,
479
+			),
480
+			'EE_Cart'                                                                                                     => array(
481
+				'EE_Session' => EE_Dependency_Map::load_from_cache,
482
+			),
483
+			'EE_Front_Controller'                                                                                         => array(
484
+				'EE_Registry'              => EE_Dependency_Map::load_from_cache,
485
+				'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
486
+				'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
487
+			),
488
+			'EE_Messenger_Collection_Loader'                                                                              => array(
489
+				'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
490
+			),
491
+			'EE_Message_Type_Collection_Loader'                                                                           => array(
492
+				'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
493
+			),
494
+			'EE_Message_Resource_Manager'                                                                                 => array(
495
+				'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
496
+				'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
497
+				'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
498
+			),
499
+			'EE_Message_Factory'                                                                                          => array(
500
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
501
+			),
502
+			'EE_messages'                                                                                                 => array(
503
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
504
+			),
505
+			'EE_Messages_Generator'                                                                                       => array(
506
+				'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
507
+				'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
508
+				'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
509
+				'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
510
+			),
511
+			'EE_Messages_Processor'                                                                                       => array(
512
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
513
+			),
514
+			'EE_Messages_Queue'                                                                                           => array(
515
+				'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
516
+			),
517
+			'EE_Messages_Template_Defaults'                                                                               => array(
518
+				'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
519
+				'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
520
+			),
521
+			'EE_Message_To_Generate_From_Request'                                                                         => array(
522
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
523
+				'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
524
+			),
525
+			'EventEspresso\core\services\commands\CommandBus'                                                             => array(
526
+				'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
527
+			),
528
+			'EventEspresso\services\commands\CommandHandler'                                                              => array(
529
+				'EE_Registry'         => EE_Dependency_Map::load_from_cache,
530
+				'CommandBusInterface' => EE_Dependency_Map::load_from_cache,
531
+			),
532
+			'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
533
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
534
+			),
535
+			'EventEspresso\core\services\commands\CompositeCommandHandler'                                                => array(
536
+				'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
537
+				'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
538
+			),
539
+			'EventEspresso\core\services\commands\CommandFactory'                                                         => array(
540
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
541
+			),
542
+			'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
543
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
544
+			),
545
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
546
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
547
+			),
548
+			'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
549
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
550
+			),
551
+			'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
552
+				'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
553
+			),
554
+			'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
555
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
556
+			),
557
+			'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
558
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
559
+			),
560
+			'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
561
+				'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
562
+			),
563
+			'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
564
+				'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
565
+			),
566
+			'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
567
+				'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
568
+			),
569
+			'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
570
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
571
+			),
572
+			'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
573
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
574
+			),
575
+			'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
576
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
577
+			),
578
+			'EventEspresso\core\services\database\TableManager'                                                           => array(
579
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
580
+			),
581
+			'EE_Data_Migration_Class_Base'                                                                                => array(
582
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
583
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
584
+			),
585
+			'EE_DMS_Core_4_1_0'                                                                                           => array(
586
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
587
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
588
+			),
589
+			'EE_DMS_Core_4_2_0'                                                                                           => array(
590
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
591
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
592
+			),
593
+			'EE_DMS_Core_4_3_0'                                                                                           => array(
594
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
595
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
596
+			),
597
+			'EE_DMS_Core_4_4_0'                                                                                           => array(
598
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
599
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
600
+			),
601
+			'EE_DMS_Core_4_5_0'                                                                                           => array(
602
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
603
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
604
+			),
605
+			'EE_DMS_Core_4_6_0'                                                                                           => array(
606
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
607
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
608
+			),
609
+			'EE_DMS_Core_4_7_0'                                                                                           => array(
610
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
611
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
612
+			),
613
+			'EE_DMS_Core_4_8_0'                                                                                           => array(
614
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
615
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
616
+			),
617
+			'EE_DMS_Core_4_9_0'                                                                                           => array(
618
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
619
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
620
+			),
621
+			'EventEspresso\core\services\assets\I18nRegistry' => array(
622
+				array(),
623
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache
624
+			),
625
+			'EventEspresso\core\services\assets\Registry'                                                                 => array(
626
+				'EE_Template_Config' => EE_Dependency_Map::load_from_cache,
627
+				'EE_Currency_Config' => EE_Dependency_Map::load_from_cache,
628
+				'EventEspresso\core\services\assets\I18nRegistry' => EE_Dependency_Map::load_from_cache,
629
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache
630
+			),
631
+			'EventEspresso\core\domain\entities\shortcodes\EspressoCancelled'                                             => array(
632
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
633
+			),
634
+			'EventEspresso\core\domain\entities\shortcodes\EspressoCheckout'                                              => array(
635
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
636
+			),
637
+			'EventEspresso\core\domain\entities\shortcodes\EspressoEventAttendees'                                        => array(
638
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
639
+			),
640
+			'EventEspresso\core\domain\entities\shortcodes\EspressoEvents'                                                => array(
641
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
642
+			),
643
+			'EventEspresso\core\domain\entities\shortcodes\EspressoThankYou'                                              => array(
644
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
645
+			),
646
+			'EventEspresso\core\domain\entities\shortcodes\EspressoTicketSelector'                                        => array(
647
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
648
+			),
649
+			'EventEspresso\core\domain\entities\shortcodes\EspressoTxnPage'                                               => array(
650
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
651
+			),
652
+			'EventEspresso\core\services\cache\BasicCacheManager'                        => array(
653
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
654
+			),
655
+			'EventEspresso\core\services\cache\PostRelatedCacheManager'                  => array(
656
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
657
+			),
658
+			'EventEspresso\core\domain\services\validation\email\EmailValidationService' => array(
659
+				'EE_Registration_Config'                                  => EE_Dependency_Map::load_from_cache,
660
+				'EventEspresso\core\services\loaders\Loader'              => EE_Dependency_Map::load_from_cache,
661
+			),
662
+			'EventEspresso\core\domain\values\EmailAddress'                              => array(
663
+				null,
664
+				'EventEspresso\core\domain\services\validation\email\EmailValidationService' => EE_Dependency_Map::load_from_cache,
665
+			),
666
+			'EventEspresso\core\services\orm\ModelFieldFactory' => array(
667
+				'EventEspresso\core\services\loaders\Loader'              => EE_Dependency_Map::load_from_cache,
668
+			),
669
+			'LEGACY_MODELS'                                                   => array(
670
+				null,
671
+				'EventEspresso\core\services\database\ModelFieldFactory' => EE_Dependency_Map::load_from_cache,
672
+			),
673
+			'EE_Module_Request_Router'                                               => array(
674
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
675
+			),
676
+			'EE_Registration_Processor'                                              => array(
677
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
678
+			),
679
+			'EventEspresso\core\services\notifications\PersistentAdminNoticeManager' => array(
680
+				null,
681
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
682
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
683
+			),
684
+			'EventEspresso\core\services\editor\EditorBlockRegistrationManager'      => array(
685
+				'EventEspresso\core\domain\entities\editor\EditorBlockCollection' => EE_Dependency_Map::load_from_cache,
686
+				'EE_Request'                                                      => EE_Dependency_Map::load_from_cache,
687
+				'EventEspresso\core\domain\Domain'                                => EE_Dependency_Map::load_from_cache,
688
+				'EventEspresso\core\services\assets\Registry' => EE_Dependency_Map::load_from_cache
689
+			),
690
+			'EE_Admin_Transactions_List_Table' => array(
691
+				null,
692
+				'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
693
+			),
694
+			'EventEspresso\core\services\licensing\LicenseService' => array(
695
+				'EventEspresso\core\domain\services\pue\Stats' => EE_Dependency_Map::load_from_cache,
696
+				'EventEspresso\core\domain\services\pue\Config' => EE_Dependency_Map::load_from_cache
697
+			),
698
+			'EventEspresso\core\domain\services\pue\Stats' => array(
699
+				'EventEspresso\core\domain\services\pue\Config' => EE_Dependency_Map::load_from_cache,
700
+				'EE_Maintenance_Mode' => EE_Dependency_Map::load_from_cache,
701
+				'EventEspresso\core\domain\services\pue\StatsGatherer' => EE_Dependency_Map::load_from_cache
702
+			),
703
+			'EventEspresso\core\domain\services\pue\Config' => array(
704
+				'EE_Network_Config' => EE_Dependency_Map::load_from_cache,
705
+				'EE_Config' => EE_Dependency_Map::load_from_cache
706
+			),
707
+			'EventEspresso\core\domain\services\pue\StatsGatherer' => array(
708
+				'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
709
+				'EEM_Event' => EE_Dependency_Map::load_from_cache,
710
+				'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
711
+				'EEM_Ticket' => EE_Dependency_Map::load_from_cache,
712
+				'EEM_Registration' => EE_Dependency_Map::load_from_cache,
713
+				'EEM_Transaction' => EE_Dependency_Map::load_from_cache,
714
+				'EE_Config' => EE_Dependency_Map::load_from_cache
715
+			),
716
+			'EventEspresso\core\domain\services\admin\ExitModal' => array(
717
+				'EventEspresso\core\services\assets\Registry' => EE_Dependency_Map::load_from_cache
718
+			),
719
+			'EventEspresso\core\domain\services\admin\PluginUpsells' => array(
720
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache
721
+			),
722
+			'EventEspresso\caffeinated\modules\recaptcha_invisible\InvisibleRecaptcha' => array(
723
+				'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
724
+				'EE_Session'             => EE_Dependency_Map::load_from_cache,
725
+			),
726
+			'EventEspresso\caffeinated\modules\recaptcha_invisible\RecaptchaAdminSettings' => array(
727
+				'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
728
+			),
729
+			'EventEspresso\modules\ticket_selector\ProcessTicketSelector' => array(
730
+				'EE_Core_Config' => EE_Dependency_Map::load_from_cache,
731
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
732
+				'EE_Session' => EE_Dependency_Map::load_from_cache,
733
+				'EEM_Ticket' => EE_Dependency_Map::load_from_cache,
734
+				'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker' => EE_Dependency_Map::load_from_cache,
735
+			),
736
+			'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker' => array(
737
+				'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
738
+			),
739
+			'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => array(
740
+				'EE_Core_Config' => EE_Dependency_Map::load_from_cache,
741
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
742
+			),
743
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'   => array(
744
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
745
+			),
746
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'   => array(
747
+				'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
748
+			),
749
+			'EE_CPT_Strategy'   => array(
750
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
751
+				'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
752
+			),
753
+		);
754
+	}
755
+
756
+
757
+
758
+	/**
759
+	 * Registers how core classes are loaded.
760
+	 * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
761
+	 *        'EE_Request_Handler' => 'load_core'
762
+	 *        'EE_Messages_Queue'  => 'load_lib'
763
+	 *        'EEH_Debug_Tools'    => 'load_helper'
764
+	 * or, if greater control is required, by providing a custom closure. For example:
765
+	 *        'Some_Class' => function () {
766
+	 *            return new Some_Class();
767
+	 *        },
768
+	 * This is required for instantiating dependencies
769
+	 * where an interface has been type hinted in a class constructor. For example:
770
+	 *        'Required_Interface' => function () {
771
+	 *            return new A_Class_That_Implements_Required_Interface();
772
+	 *        },
773
+	 *
774
+	 * @throws InvalidInterfaceException
775
+	 * @throws InvalidDataTypeException
776
+	 * @throws InvalidArgumentException
777
+	 */
778
+	protected function _register_core_class_loaders()
779
+	{
780
+		//for PHP5.3 compat, we need to register any properties called here in a variable because `$this` cannot
781
+		//be used in a closure.
782
+		$request = &$this->request;
783
+		$response = &$this->response;
784
+		$legacy_request = &$this->legacy_request;
785
+		// $loader = &$this->loader;
786
+		$this->_class_loaders = array(
787
+			//load_core
788
+			'EE_Capabilities'          => 'load_core',
789
+			'EE_Encryption'            => 'load_core',
790
+			'EE_Front_Controller'      => 'load_core',
791
+			'EE_Module_Request_Router' => 'load_core',
792
+			'EE_Registry'              => 'load_core',
793
+			'EE_Request'               => function () use (&$legacy_request) {
794
+				return $legacy_request;
795
+			},
796
+			'EventEspresso\core\services\request\Request' => function () use (&$request) {
797
+				return $request;
798
+			},
799
+			'EventEspresso\core\services\request\Response' => function () use (&$response) {
800
+				return $response;
801
+			},
802
+			'EE_Request_Handler'       => 'load_core',
803
+			'EE_Session'               => 'load_core',
804
+			'EE_Cron_Tasks'            => 'load_core',
805
+			'EE_System'                => 'load_core',
806
+			'EE_Maintenance_Mode'      => 'load_core',
807
+			'EE_Register_CPTs'         => 'load_core',
808
+			'EE_Admin'                 => 'load_core',
809
+			'EE_CPT_Strategy'          => 'load_core',
810
+			//load_lib
811
+			'EE_Message_Resource_Manager'          => 'load_lib',
812
+			'EE_Message_Type_Collection'           => 'load_lib',
813
+			'EE_Message_Type_Collection_Loader'    => 'load_lib',
814
+			'EE_Messenger_Collection'              => 'load_lib',
815
+			'EE_Messenger_Collection_Loader'       => 'load_lib',
816
+			'EE_Messages_Processor'                => 'load_lib',
817
+			'EE_Message_Repository'                => 'load_lib',
818
+			'EE_Messages_Queue'                    => 'load_lib',
819
+			'EE_Messages_Data_Handler_Collection'  => 'load_lib',
820
+			'EE_Message_Template_Group_Collection' => 'load_lib',
821
+			'EE_Payment_Method_Manager'            => 'load_lib',
822
+			'EE_Messages_Generator'                => function () {
823
+				return EE_Registry::instance()->load_lib(
824
+					'Messages_Generator',
825
+					array(),
826
+					false,
827
+					false
828
+				);
829
+			},
830
+			'EE_Messages_Template_Defaults'        => function ($arguments = array()) {
831
+				return EE_Registry::instance()->load_lib(
832
+					'Messages_Template_Defaults',
833
+					$arguments,
834
+					false,
835
+					false
836
+				);
837
+			},
838
+			//load_helper
839
+			'EEH_Parse_Shortcodes'                 => function () {
840
+				if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
841
+					return new EEH_Parse_Shortcodes();
842
+				}
843
+				return null;
844
+			},
845
+			'EE_Template_Config'                   => function () {
846
+				return EE_Config::instance()->template_settings;
847
+			},
848
+			'EE_Currency_Config'                   => function () {
849
+				return EE_Config::instance()->currency;
850
+			},
851
+			'EE_Registration_Config'                   => function () {
852
+				return EE_Config::instance()->registration;
853
+			},
854
+			'EE_Core_Config'                   => function () {
855
+				return EE_Config::instance()->core;
856
+			},
857
+			'EventEspresso\core\services\loaders\Loader' => function () {
858
+				return LoaderFactory::getLoader();
859
+			},
860
+			'EE_Network_Config' => function() {
861
+				return EE_Network_Config::instance();
862
+			},
863
+			'EE_Config' => function () {
864
+				return EE_Config::instance();
865
+			}
866
+		);
867
+	}
868
+
869
+
870
+
871
+	/**
872
+	 * can be used for supplying alternate names for classes,
873
+	 * or for connecting interface names to instantiable classes
874
+	 */
875
+	protected function _register_core_aliases()
876
+	{
877
+		$this->_aliases = array(
878
+			'CommandBusInterface'                                                          => 'EventEspresso\core\services\commands\CommandBusInterface',
879
+			'EventEspresso\core\services\commands\CommandBusInterface'                     => 'EventEspresso\core\services\commands\CommandBus',
880
+			'CommandHandlerManagerInterface'                                               => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
881
+			'EventEspresso\core\services\commands\CommandHandlerManagerInterface'          => 'EventEspresso\core\services\commands\CommandHandlerManager',
882
+			'CapChecker'                                                                   => 'EventEspresso\core\services\commands\middleware\CapChecker',
883
+			'AddActionHook'                                                                => 'EventEspresso\core\services\commands\middleware\AddActionHook',
884
+			'CapabilitiesChecker'                                                          => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
885
+			'CapabilitiesCheckerInterface'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
886
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
887
+			'CreateRegistrationService'                                                    => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
888
+			'CreateRegCodeCommandHandler'                                                  => 'EventEspresso\core\services\commands\registration\CreateRegCodeCommand',
889
+			'CreateRegUrlLinkCommandHandler'                                               => 'EventEspresso\core\services\commands\registration\CreateRegUrlLinkCommand',
890
+			'CreateRegistrationCommandHandler'                                             => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
891
+			'CopyRegistrationDetailsCommandHandler'                                        => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
892
+			'CopyRegistrationPaymentsCommandHandler'                                       => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
893
+			'CancelRegistrationAndTicketLineItemCommandHandler'                            => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
894
+			'UpdateRegistrationAndTransactionAfterChangeCommandHandler'                    => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
895
+			'CreateTicketLineItemCommandHandler'                                           => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
896
+			'CreateTransactionCommandHandler'                                     => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
897
+			'CreateAttendeeCommandHandler'                                        => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
898
+			'TableManager'                                                                 => 'EventEspresso\core\services\database\TableManager',
899
+			'TableAnalysis'                                                                => 'EventEspresso\core\services\database\TableAnalysis',
900
+			'EspressoShortcode'                                                            => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
901
+			'ShortcodeInterface'                                                           => 'EventEspresso\core\services\shortcodes\ShortcodeInterface',
902
+			'EventEspresso\core\services\shortcodes\ShortcodeInterface'                    => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
903
+			'EventEspresso\core\services\cache\CacheStorageInterface'                      => 'EventEspresso\core\services\cache\TransientCacheStorage',
904
+			'LoaderInterface'                                                              => 'EventEspresso\core\services\loaders\LoaderInterface',
905
+			'EventEspresso\core\services\loaders\LoaderInterface'                          => 'EventEspresso\core\services\loaders\Loader',
906
+			'CommandFactoryInterface'                                                     => 'EventEspresso\core\services\commands\CommandFactoryInterface',
907
+			'EventEspresso\core\services\commands\CommandFactoryInterface'                => 'EventEspresso\core\services\commands\CommandFactory',
908
+			'EventEspresso\core\domain\services\session\SessionIdentifierInterface'       => 'EE_Session',
909
+			'EmailValidatorInterface'                                                     => 'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface',
910
+			'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface' => 'EventEspresso\core\domain\services\validation\email\EmailValidationService',
911
+			'NoticeConverterInterface'                                            => 'EventEspresso\core\services\notices\NoticeConverterInterface',
912
+			'EventEspresso\core\services\notices\NoticeConverterInterface'        => 'EventEspresso\core\services\notices\ConvertNoticesToEeErrors',
913
+			'NoticesContainerInterface'                                           => 'EventEspresso\core\services\notices\NoticesContainerInterface',
914
+			'EventEspresso\core\services\notices\NoticesContainerInterface'       => 'EventEspresso\core\services\notices\NoticesContainer',
915
+			'EventEspresso\core\services\request\RequestInterface'                => 'EventEspresso\core\services\request\Request',
916
+			'EventEspresso\core\services\request\ResponseInterface'               => 'EventEspresso\core\services\request\Response',
917
+			'EventEspresso\core\domain\DomainInterface'                           => 'EventEspresso\core\domain\Domain',
918
+		);
919
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
920
+			$this->_aliases['EventEspresso\core\services\notices\NoticeConverterInterface'] = 'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices';
921
+		}
922
+	}
923
+
924
+
925
+
926
+	/**
927
+	 * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
928
+	 * request Primarily used by unit tests.
929
+	 *
930
+	 * @throws InvalidDataTypeException
931
+	 * @throws InvalidInterfaceException
932
+	 * @throws InvalidArgumentException
933
+	 */
934
+	public function reset()
935
+	{
936
+		$this->_register_core_class_loaders();
937
+		$this->_register_core_dependencies();
938
+	}
939 939
 
940 940
 
941 941
 }
Please login to merge, or discard this patch.
modules/core_rest_api/EED_Core_Rest_Api.module.php 2 patches
Indentation   +1272 added lines, -1272 removed lines patch added patch discarded remove patch
@@ -26,1279 +26,1279 @@
 block discarded – undo
26 26
 class EED_Core_Rest_Api extends \EED_Module
27 27
 {
28 28
 
29
-    const ee_api_namespace           = Domain::API_NAMESPACE;
29
+	const ee_api_namespace           = Domain::API_NAMESPACE;
30 30
 
31
-    const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/';
32
-
33
-    const saved_routes_option_names  = 'ee_core_routes';
34
-
35
-    /**
36
-     * string used in _links response bodies to make them globally unique.
37
-     *
38
-     * @see http://v2.wp-api.org/extending/linking/
39
-     */
40
-    const ee_api_link_namespace = 'https://api.eventespresso.com/';
41
-
42
-    /**
43
-     * @var CalculatedModelFields
44
-     */
45
-    protected static $_field_calculator;
46
-
47
-
48
-
49
-    /**
50
-     * @return EED_Core_Rest_Api|EED_Module
51
-     */
52
-    public static function instance()
53
-    {
54
-        self::$_field_calculator = new CalculatedModelFields();
55
-        return parent::get_instance(__CLASS__);
56
-    }
57
-
58
-
59
-
60
-    /**
61
-     *    set_hooks - for hooking into EE Core, other modules, etc
62
-     *
63
-     * @access    public
64
-     * @return    void
65
-     */
66
-    public static function set_hooks()
67
-    {
68
-        self::set_hooks_both();
69
-    }
70
-
71
-
72
-
73
-    /**
74
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
75
-     *
76
-     * @access    public
77
-     * @return    void
78
-     */
79
-    public static function set_hooks_admin()
80
-    {
81
-        self::set_hooks_both();
82
-    }
83
-
84
-
85
-
86
-    public static function set_hooks_both()
87
-    {
88
-        add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10);
89
-        add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5);
90
-        add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2);
91
-        add_filter('rest_index',
92
-            array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex'));
93
-        EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change();
94
-    }
95
-
96
-
97
-
98
-    /**
99
-     * sets up hooks which only need to be included as part of REST API requests;
100
-     * other requests like to the frontend or admin etc don't need them
101
-     *
102
-     * @throws \EE_Error
103
-     */
104
-    public static function set_hooks_rest_api()
105
-    {
106
-        //set hooks which account for changes made to the API
107
-        EED_Core_Rest_Api::_set_hooks_for_changes();
108
-    }
109
-
110
-
111
-
112
-    /**
113
-     * public wrapper of _set_hooks_for_changes.
114
-     * Loads all the hooks which make requests to old versions of the API
115
-     * appear the same as they always did
116
-     *
117
-     * @throws EE_Error
118
-     */
119
-    public static function set_hooks_for_changes()
120
-    {
121
-        self::_set_hooks_for_changes();
122
-    }
123
-
124
-
125
-
126
-    /**
127
-     * Loads all the hooks which make requests to old versions of the API
128
-     * appear the same as they always did
129
-     *
130
-     * @throws EE_Error
131
-     */
132
-    protected static function _set_hooks_for_changes()
133
-    {
134
-        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
135
-        foreach ($folder_contents as $classname_in_namespace => $filepath) {
136
-            //ignore the base parent class
137
-            //and legacy named classes
138
-            if ($classname_in_namespace === 'ChangesInBase'
139
-                || strpos($classname_in_namespace, 'Changes_In_') === 0
140
-            ) {
141
-                continue;
142
-            }
143
-            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
144
-            if (class_exists($full_classname)) {
145
-                $instance_of_class = new $full_classname;
146
-                if ($instance_of_class instanceof ChangesInBase) {
147
-                    $instance_of_class->setHooks();
148
-                }
149
-            }
150
-        }
151
-    }
152
-
153
-
154
-
155
-    /**
156
-     * Filters the WP routes to add our EE-related ones. This takes a bit of time
157
-     * so we actually prefer to only do it when an EE plugin is activated or upgraded
158
-     *
159
-     * @throws \EE_Error
160
-     */
161
-    public static function register_routes()
162
-    {
163
-        foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) {
164
-            foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) {
165
-                /**
166
-                 * @var array $data_for_multiple_endpoints numerically indexed array
167
-                 *                                         but can also contain route options like {
168
-                 * @type array    $schema                      {
169
-                 * @type callable $schema_callback
170
-                 * @type array    $callback_args               arguments that will be passed to the callback, after the
171
-                 * WP_REST_Request of course
172
-                 * }
173
-                 * }
174
-                 */
175
-                //when registering routes, register all the endpoints' data at the same time
176
-                $multiple_endpoint_args = array();
177
-                foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) {
178
-                    /**
179
-                     * @var array     $data_for_single_endpoint {
180
-                     * @type callable $callback
181
-                     * @type string methods
182
-                     * @type array args
183
-                     * @type array _links
184
-                     * @type array    $callback_args            arguments that will be passed to the callback, after the
185
-                     * WP_REST_Request of course
186
-                     * }
187
-                     */
188
-                    //skip route options
189
-                    if (! is_numeric($endpoint_key)) {
190
-                        continue;
191
-                    }
192
-                    if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
193
-                        throw new EE_Error(
194
-                            esc_html__(
195
-                                // @codingStandardsIgnoreStart
196
-                                'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).',
197
-                                // @codingStandardsIgnoreEnd
198
-                                'event_espresso')
199
-                        );
200
-                    }
201
-                    $callback = $data_for_single_endpoint['callback'];
202
-                    $single_endpoint_args = array(
203
-                        'methods' => $data_for_single_endpoint['methods'],
204
-                        'args'    => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args']
205
-                            : array(),
206
-                    );
207
-                    if (isset($data_for_single_endpoint['_links'])) {
208
-                        $single_endpoint_args['_links'] = $data_for_single_endpoint['_links'];
209
-                    }
210
-                    if (isset($data_for_single_endpoint['callback_args'])) {
211
-                        $callback_args = $data_for_single_endpoint['callback_args'];
212
-                        $single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
213
-                            $callback,
214
-                            $callback_args
215
-                        ) {
216
-                            array_unshift($callback_args, $request);
217
-                            return call_user_func_array(
218
-                                $callback,
219
-                                $callback_args
220
-                            );
221
-                        };
222
-                    } else {
223
-                        $single_endpoint_args['callback'] = $data_for_single_endpoint['callback'];
224
-                    }
225
-                    $multiple_endpoint_args[] = $single_endpoint_args;
226
-                }
227
-                if (isset($data_for_multiple_endpoints['schema'])) {
228
-                    $schema_route_data = $data_for_multiple_endpoints['schema'];
229
-                    $schema_callback = $schema_route_data['schema_callback'];
230
-                    $callback_args = $schema_route_data['callback_args'];
231
-                    $multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
232
-                        return call_user_func_array(
233
-                            $schema_callback,
234
-                            $callback_args
235
-                        );
236
-                    };
237
-                }
238
-                register_rest_route(
239
-                    $namespace,
240
-                    $relative_route,
241
-                    $multiple_endpoint_args
242
-                );
243
-            }
244
-        }
245
-    }
246
-
247
-
248
-
249
-    /**
250
-     * Checks if there was a version change or something that merits invalidating the cached
251
-     * route data. If so, invalidates the cached route data so that it gets refreshed
252
-     * next time the WP API is used
253
-     */
254
-    public static function invalidate_cached_route_data_on_version_change()
255
-    {
256
-        if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) {
257
-            EED_Core_Rest_Api::invalidate_cached_route_data();
258
-        }
259
-        foreach (EE_Registry::instance()->addons as $addon) {
260
-            if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) {
261
-                EED_Core_Rest_Api::invalidate_cached_route_data();
262
-            }
263
-        }
264
-    }
265
-
266
-
267
-
268
-    /**
269
-     * Removes the cached route data so it will get refreshed next time the WP API is used
270
-     */
271
-    public static function invalidate_cached_route_data()
272
-    {
273
-        //delete the saved EE REST API routes
274
-        foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
275
-            delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
276
-        }
277
-    }
278
-
279
-
280
-
281
-    /**
282
-     * Gets the EE route data
283
-     *
284
-     * @return array top-level key is the namespace, next-level key is the route and its value is array{
285
-     * @throws \EE_Error
286
-     * @type string|array $callback
287
-     * @type string       $methods
288
-     * @type boolean      $hidden_endpoint
289
-     * }
290
-     */
291
-    public static function get_ee_route_data()
292
-    {
293
-        $ee_routes = array();
294
-        foreach (self::versions_served() as $version => $hidden_endpoints) {
295
-            $ee_routes[self::ee_api_namespace . $version] = self::_get_ee_route_data_for_version(
296
-                $version,
297
-                $hidden_endpoints
298
-            );
299
-        }
300
-        return $ee_routes;
301
-    }
302
-
303
-
304
-
305
-    /**
306
-     * Gets the EE route data from the wp options if it exists already,
307
-     * otherwise re-generates it and saves it to the option
308
-     *
309
-     * @param string  $version
310
-     * @param boolean $hidden_endpoints
311
-     * @return array
312
-     * @throws \EE_Error
313
-     */
314
-    protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
315
-    {
316
-        $ee_routes = get_option(self::saved_routes_option_names . $version, null);
317
-        if (! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) {
318
-            $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
319
-        }
320
-        return $ee_routes;
321
-    }
322
-
323
-
324
-
325
-    /**
326
-     * Saves the EE REST API route data to a wp option and returns it
327
-     *
328
-     * @param string  $version
329
-     * @param boolean $hidden_endpoints
330
-     * @return mixed|null
331
-     * @throws \EE_Error
332
-     */
333
-    protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false)
334
-    {
335
-        $instance = self::instance();
336
-        $routes = apply_filters(
337
-            'EED_Core_Rest_Api__save_ee_route_data_for_version__routes',
338
-            array_replace_recursive(
339
-                $instance->_get_config_route_data_for_version($version, $hidden_endpoints),
340
-                $instance->_get_meta_route_data_for_version($version, $hidden_endpoints),
341
-                $instance->_get_model_route_data_for_version($version, $hidden_endpoints),
342
-                $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
343
-            )
344
-        );
345
-        $option_name = self::saved_routes_option_names . $version;
346
-        if (get_option($option_name)) {
347
-            update_option($option_name, $routes, true);
348
-        } else {
349
-            add_option($option_name, $routes, null, 'no');
350
-        }
351
-        return $routes;
352
-    }
353
-
354
-
355
-
356
-    /**
357
-     * Calculates all the EE routes and saves it to a WordPress option so we don't
358
-     * need to calculate it on every request
359
-     *
360
-     * @deprecated since version 4.9.1
361
-     * @return void
362
-     */
363
-    public static function save_ee_routes()
364
-    {
365
-        if (EE_Maintenance_Mode::instance()->models_can_query()) {
366
-            $instance = self::instance();
367
-            $routes = apply_filters(
368
-                'EED_Core_Rest_Api__save_ee_routes__routes',
369
-                array_replace_recursive(
370
-                    $instance->_register_config_routes(),
371
-                    $instance->_register_meta_routes(),
372
-                    $instance->_register_model_routes(),
373
-                    $instance->_register_rpc_routes()
374
-                )
375
-            );
376
-            update_option(self::saved_routes_option_names, $routes, true);
377
-        }
378
-    }
379
-
380
-
381
-
382
-    /**
383
-     * Gets all the route information relating to EE models
384
-     *
385
-     * @return array @see get_ee_route_data
386
-     * @deprecated since version 4.9.1
387
-     */
388
-    protected function _register_model_routes()
389
-    {
390
-        $model_routes = array();
391
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
392
-            $model_routes[EED_Core_Rest_Api::ee_api_namespace
393
-                          . $version] = $this->_get_config_route_data_for_version($version, $hidden_endpoint);
394
-        }
395
-        return $model_routes;
396
-    }
397
-
398
-
399
-
400
-    /**
401
-     * Decides whether or not to add write endpoints for this model.
402
-     *
403
-     * Currently, this defaults to exclude all global tables and models
404
-     * which would allow inserting WP core data (we don't want to duplicate
405
-     * what WP API does, as it's unnecessary, extra work, and potentially extra bugs)
406
-     * @param EEM_Base $model
407
-     * @return bool
408
-     */
409
-    public static function should_have_write_endpoints(EEM_Base $model)
410
-    {
411
-        if ($model->is_wp_core_model()){
412
-            return false;
413
-        }
414
-        foreach($model->get_tables() as $table){
415
-            if( $table->is_global()){
416
-                return false;
417
-            }
418
-        }
419
-        return true;
420
-    }
421
-
422
-
423
-
424
-    /**
425
-     * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`)
426
-     * in this versioned namespace of EE4
427
-     * @param $version
428
-     * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
429
-     */
430
-    public static function model_names_with_plural_routes($version){
431
-        $model_version_info = new ModelVersionInfo($version);
432
-        $models_to_register = $model_version_info->modelsForRequestedVersion();
433
-        //let's not bother having endpoints for extra metas
434
-        unset(
435
-            $models_to_register['Extra_Meta'],
436
-            $models_to_register['Extra_Join'],
437
-            $models_to_register['Post_Meta']
438
-        );
439
-        return apply_filters(
440
-            'FHEE__EED_Core_REST_API___register_model_routes',
441
-            $models_to_register
442
-        );
443
-    }
444
-
445
-
446
-
447
-    /**
448
-     * Gets the route data for EE models in the specified version
449
-     *
450
-     * @param string  $version
451
-     * @param boolean $hidden_endpoint
452
-     * @return array
453
-     * @throws EE_Error
454
-     */
455
-    protected function _get_model_route_data_for_version($version, $hidden_endpoint = false)
456
-    {
457
-        $model_routes = array();
458
-        $model_version_info = new ModelVersionInfo($version);
459
-        foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
460
-            $model = \EE_Registry::instance()->load_model($model_name);
461
-            //if this isn't a valid model then let's skip iterate to the next item in the loop.
462
-            if (! $model instanceof EEM_Base) {
463
-                continue;
464
-            }
465
-            //yes we could just register one route for ALL models, but then they wouldn't show up in the index
466
-            $plural_model_route = EED_Core_Rest_Api::get_collection_route($model);
467
-            $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)');
468
-            $model_routes[$plural_model_route] = array(
469
-                array(
470
-                    'callback'        => array(
471
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
472
-                        'handleRequestGetAll',
473
-                    ),
474
-                    'callback_args'   => array($version, $model_name),
475
-                    'methods'         => WP_REST_Server::READABLE,
476
-                    'hidden_endpoint' => $hidden_endpoint,
477
-                    'args'            => $this->_get_read_query_params($model, $version),
478
-                    '_links'          => array(
479
-                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
480
-                    ),
481
-                ),
482
-                'schema' => array(
483
-                    'schema_callback' => array(
484
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
485
-                        'handleSchemaRequest',
486
-                    ),
487
-                    'callback_args'   => array($version, $model_name),
488
-                ),
489
-            );
490
-            $model_routes[$singular_model_route] = array(
491
-                array(
492
-                    'callback'        => array(
493
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
494
-                        'handleRequestGetOne',
495
-                    ),
496
-                    'callback_args'   => array($version, $model_name),
497
-                    'methods'         => WP_REST_Server::READABLE,
498
-                    'hidden_endpoint' => $hidden_endpoint,
499
-                    'args'            => $this->_get_response_selection_query_params($model, $version),
500
-                ),
501
-            );
502
-            if( apply_filters(
503
-                'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
504
-                EED_Core_Rest_Api::should_have_write_endpoints($model),
505
-                $model
506
-            )){
507
-                $model_routes[$plural_model_route][] = array(
508
-                    'callback'        => array(
509
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Write',
510
-                        'handleRequestInsert',
511
-                    ),
512
-                    'callback_args'   => array($version, $model_name),
513
-                    'methods'         => WP_REST_Server::CREATABLE,
514
-                    'hidden_endpoint' => $hidden_endpoint,
515
-                    'args'            => $this->_get_write_params($model_name, $model_version_info, true),
516
-                );
517
-                $model_routes[$singular_model_route] = array_merge(
518
-                    $model_routes[$singular_model_route],
519
-                    array(
520
-                        array(
521
-                            'callback'        => array(
522
-                                'EventEspresso\core\libraries\rest_api\controllers\model\Write',
523
-                                'handleRequestUpdate',
524
-                            ),
525
-                            'callback_args'   => array($version, $model_name),
526
-                            'methods'         => WP_REST_Server::EDITABLE,
527
-                            'hidden_endpoint' => $hidden_endpoint,
528
-                            'args'            => $this->_get_write_params($model_name, $model_version_info),
529
-                        ),
530
-                        array(
531
-                            'callback'        => array(
532
-                                'EventEspresso\core\libraries\rest_api\controllers\model\Write',
533
-                                'handleRequestDelete',
534
-                            ),
535
-                            'callback_args'   => array($version, $model_name),
536
-                            'methods'         => WP_REST_Server::DELETABLE,
537
-                            'hidden_endpoint' => $hidden_endpoint,
538
-                            'args'            => $this->_get_delete_query_params($model, $version),
539
-                        )
540
-                    )
541
-                );
542
-            }
543
-            foreach ($model->relation_settings() as $relation_name => $relation_obj) {
544
-
545
-                $related_route = EED_Core_Rest_Api::get_relation_route_via(
546
-                    $model,
547
-                    '(?P<id>[^\/]+)',
548
-                    $relation_obj
549
-                );
550
-                $endpoints = array(
551
-                    array(
552
-                        'callback'        => array(
553
-                            'EventEspresso\core\libraries\rest_api\controllers\model\Read',
554
-                            'handleRequestGetRelated',
555
-                        ),
556
-                        'callback_args'   => array($version, $model_name, $relation_name),
557
-                        'methods'         => WP_REST_Server::READABLE,
558
-                        'hidden_endpoint' => $hidden_endpoint,
559
-                        'args'            => $this->_get_read_query_params($relation_obj->get_other_model(), $version),
560
-                    ),
561
-                );
562
-                $model_routes[$related_route] = $endpoints;
563
-            }
564
-        }
565
-        return $model_routes;
566
-    }
567
-
568
-
569
-
570
-    /**
571
-     * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace,
572
-     * excluding the preceding slash.
573
-     * Eg you pass get_plural_route_to('Event') = 'events'
574
-     *
575
-     * @param EEM_Base $model
576
-     * @return string
577
-     */
578
-    public static function get_collection_route(EEM_Base $model)
579
-    {
580
-        return EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
581
-    }
582
-
583
-
584
-
585
-    /**
586
-     * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
587
-     * excluding the preceding slash.
588
-     * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
589
-     *
590
-     * @param EEM_Base $model eg Event or Venue
591
-     * @param string $id
592
-     * @return string
593
-     */
594
-    public static function get_entity_route($model, $id)
595
-    {
596
-        return EED_Core_Rest_Api::get_collection_route($model). '/' . $id;
597
-    }
598
-
599
-
600
-    /**
601
-     * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
602
-     * excluding the preceding slash.
603
-     * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
604
-     *
605
-     * @param EEM_Base                 $model eg Event or Venue
606
-     * @param string                 $id
607
-     * @param EE_Model_Relation_Base $relation_obj
608
-     * @return string
609
-     */
610
-    public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj)
611
-    {
612
-        $related_model_name_endpoint_part = ModelRead::getRelatedEntityName(
613
-            $relation_obj->get_other_model()->get_this_model_name(),
614
-            $relation_obj
615
-        );
616
-        return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
617
-    }
618
-
619
-
620
-
621
-    /**
622
-     * Adds onto the $relative_route the EE4 REST API versioned namespace.
623
-     * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events'
624
-     * @param string $relative_route
625
-     * @param string $version
626
-     * @return string
627
-     */
628
-    public static function get_versioned_route_to($relative_route, $version = '4.8.36'){
629
-        return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
630
-    }
631
-
632
-
633
-
634
-    /**
635
-     * Adds all the RPC-style routes (remote procedure call-like routes, ie
636
-     * routes that don't conform to the traditional REST CRUD-style).
637
-     *
638
-     * @deprecated since 4.9.1
639
-     */
640
-    protected function _register_rpc_routes()
641
-    {
642
-        $routes = array();
643
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
644
-            $routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version(
645
-                $version,
646
-                $hidden_endpoint
647
-            );
648
-        }
649
-        return $routes;
650
-    }
651
-
652
-
653
-
654
-    /**
655
-     * @param string  $version
656
-     * @param boolean $hidden_endpoint
657
-     * @return array
658
-     */
659
-    protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false)
660
-    {
661
-        $this_versions_routes = array();
662
-        //checkin endpoint
663
-        $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array(
664
-            array(
665
-                'callback'        => array(
666
-                    'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin',
667
-                    'handleRequestToggleCheckin',
668
-                ),
669
-                'methods'         => WP_REST_Server::CREATABLE,
670
-                'hidden_endpoint' => $hidden_endpoint,
671
-                'args'            => array(
672
-                    'force' => array(
673
-                        'required'    => false,
674
-                        'default'     => false,
675
-                        'description' => __(
676
-                            // @codingStandardsIgnoreStart
677
-                            'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses',
678
-                            // @codingStandardsIgnoreEnd
679
-                            'event_espresso'
680
-                        ),
681
-                    ),
682
-                ),
683
-                'callback_args'   => array($version),
684
-            ),
685
-        );
686
-        return apply_filters(
687
-            'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes',
688
-            $this_versions_routes,
689
-            $version,
690
-            $hidden_endpoint
691
-        );
692
-    }
693
-
694
-
695
-
696
-    /**
697
-     * Gets the query params that can be used when request one or many
698
-     *
699
-     * @param EEM_Base $model
700
-     * @param string   $version
701
-     * @return array
702
-     */
703
-    protected function _get_response_selection_query_params(\EEM_Base $model, $version)
704
-    {
705
-        return apply_filters(
706
-            'FHEE__EED_Core_Rest_Api___get_response_selection_query_params',
707
-            array(
708
-                'include'   => array(
709
-                    'required' => false,
710
-                    'default'  => '*',
711
-                    'type'     => 'string',
712
-                ),
713
-                'calculate' => array(
714
-                    'required'          => false,
715
-                    'default'           => '',
716
-                    'enum'              => self::$_field_calculator->retrieveCalculatedFieldsForModel($model),
717
-                    'type'              => 'string',
718
-                    //because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization
719
-                    //freaks out. We'll just validate this argument while handling the request
720
-                    'validate_callback' => null,
721
-                    'sanitize_callback' => null,
722
-                ),
723
-            ),
724
-            $model,
725
-            $version
726
-        );
727
-    }
728
-
729
-
730
-
731
-    /**
732
-     * Gets the parameters acceptable for delete requests
733
-     *
734
-     * @param \EEM_Base $model
735
-     * @param string    $version
736
-     * @return array
737
-     */
738
-    protected function _get_delete_query_params(\EEM_Base $model, $version)
739
-    {
740
-        $params_for_delete = array(
741
-            'allow_blocking' => array(
742
-                'required' => false,
743
-                'default'  => true,
744
-                'type'     => 'boolean',
745
-            ),
746
-        );
747
-        $params_for_delete['force'] = array(
748
-            'required' => false,
749
-            'default'  => false,
750
-            'type'     => 'boolean',
751
-        );
752
-        return apply_filters(
753
-            'FHEE__EED_Core_Rest_Api___get_delete_query_params',
754
-            $params_for_delete,
755
-            $model,
756
-            $version
757
-        );
758
-    }
759
-
760
-
761
-
762
-    /**
763
-     * Gets info about reading query params that are acceptable
764
-     *
765
-     * @param \EEM_Base $model eg 'Event' or 'Venue'
766
-     * @param  string   $version
767
-     * @return array    describing the args acceptable when querying this model
768
-     * @throws EE_Error
769
-     */
770
-    protected function _get_read_query_params(\EEM_Base $model, $version)
771
-    {
772
-        $default_orderby = array();
773
-        foreach ($model->get_combined_primary_key_fields() as $key_field) {
774
-            $default_orderby[$key_field->get_name()] = 'ASC';
775
-        }
776
-        return array_merge(
777
-            $this->_get_response_selection_query_params($model, $version),
778
-            array(
779
-                'where'    => array(
780
-                    'required' => false,
781
-                    'default'  => array(),
782
-                    'type'     => 'object',
783
-                    //because we accept an almost infinite list of possible where conditions, WP
784
-                    // core validation and sanitization freaks out. We'll just validate this argument
785
-                    // while handling the request
786
-                    'validate_callback' => null,
787
-                    'sanitize_callback' => null,
788
-                ),
789
-                'limit'    => array(
790
-                    'required' => false,
791
-                    'default'  => EED_Core_Rest_Api::get_default_query_limit(),
792
-                    'type'     => array(
793
-                        'array',
794
-                        'string',
795
-                        'integer',
796
-                    ),
797
-                    //because we accept a variety of types, WP core validation and sanitization
798
-                    //freaks out. We'll just validate this argument while handling the request
799
-                    'validate_callback' => null,
800
-                    'sanitize_callback' => null,
801
-                ),
802
-                'order_by' => array(
803
-                    'required' => false,
804
-                    'default'  => $default_orderby,
805
-                    'type'     => array(
806
-                        'object',
807
-                        'string',
808
-                    ),//because we accept a variety of types, WP core validation and sanitization
809
-                    //freaks out. We'll just validate this argument while handling the request
810
-                    'validate_callback' => null,
811
-                    'sanitize_callback' => null,
812
-                ),
813
-                'group_by' => array(
814
-                    'required' => false,
815
-                    'default'  => null,
816
-                    'type'     => array(
817
-                        'object',
818
-                        'string',
819
-                    ),
820
-                    //because we accept  an almost infinite list of possible groupings,
821
-                    // WP core validation and sanitization
822
-                    //freaks out. We'll just validate this argument while handling the request
823
-                    'validate_callback' => null,
824
-                    'sanitize_callback' => null,
825
-                ),
826
-                'having'   => array(
827
-                    'required' => false,
828
-                    'default'  => null,
829
-                    'type'     => 'object',
830
-                    //because we accept an almost infinite list of possible where conditions, WP
831
-                    // core validation and sanitization freaks out. We'll just validate this argument
832
-                    // while handling the request
833
-                    'validate_callback' => null,
834
-                    'sanitize_callback' => null,
835
-                ),
836
-                'caps'     => array(
837
-                    'required' => false,
838
-                    'default'  => EEM_Base::caps_read,
839
-                    'type'     => 'string',
840
-                    'enum'     => array(
841
-                        EEM_Base::caps_read,
842
-                        EEM_Base::caps_read_admin,
843
-                        EEM_Base::caps_edit,
844
-                        EEM_Base::caps_delete
845
-                    )
846
-                ),
847
-            )
848
-        );
849
-    }
850
-
851
-
852
-
853
-    /**
854
-     * Gets parameter information for a model regarding writing data
855
-     *
856
-     * @param string           $model_name
857
-     * @param ModelVersionInfo $model_version_info
858
-     * @param boolean          $create                                       whether this is for request to create (in which case we need
859
-     *                                                                       all required params) or just to update (in which case we don't need those on every request)
860
-     * @return array
861
-     */
862
-    protected function _get_write_params(
863
-        $model_name,
864
-        ModelVersionInfo $model_version_info,
865
-        $create = false
866
-    ) {
867
-        $model = EE_Registry::instance()->load_model($model_name);
868
-        $fields = $model_version_info->fieldsOnModelInThisVersion($model);
869
-        $args_info = array();
870
-        foreach ($fields as $field_name => $field_obj) {
871
-            if ($field_obj->is_auto_increment()) {
872
-                //totally ignore auto increment IDs
873
-                continue;
874
-            }
875
-            $arg_info = $field_obj->getSchema();
876
-            $required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null;
877
-            $arg_info['required'] = $required;
878
-            //remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right?
879
-            unset($arg_info['readonly']);
880
-            $schema_properties = $field_obj->getSchemaProperties();
881
-            if (
882
-                isset($schema_properties['raw'])
883
-                && $field_obj->getSchemaType() === 'object'
884
-            ) {
885
-                //if there's a "raw" form of this argument, use those properties instead
886
-                $arg_info = array_replace(
887
-                    $arg_info,
888
-                    $schema_properties['raw']
889
-                );
890
-            }
891
-            $arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson(
892
-                $field_obj,
893
-                $field_obj->get_default_value(),
894
-                $model_version_info->requestedVersion()
895
-            );
896
-            //we do our own validation and sanitization within the controller
897
-            if(function_exists('rest_validate_value_from_schema')){
898
-                $sanitize_callback = array(
899
-                    'EED_Core_Rest_Api',
900
-                    'default_sanitize_callback',
901
-                );
902
-            } else {
903
-                $sanitize_callback = null;
904
-            }
905
-            $arg_info['sanitize_callback'] = $sanitize_callback;
906
-            $args_info[$field_name] = $arg_info;
907
-            if ($field_obj instanceof EE_Datetime_Field) {
908
-                $gmt_arg_info = $arg_info;
909
-                $gmt_arg_info['description'] = sprintf(
910
-                    esc_html__(
911
-                        '%1$s - the value for this field in UTC. Ignored if %2$s is provided.',
912
-                        'event_espresso'
913
-                    ),
914
-                    $field_obj->get_nicename(),
915
-                    $field_name
916
-                );
917
-                $args_info[$field_name . '_gmt'] = $gmt_arg_info;
918
-            }
919
-        }
920
-        return $args_info;
921
-    }
922
-
923
-
924
-
925
-    /**
926
-     * Replacement for WP API's 'rest_parse_request_arg'.
927
-     * If the value is blank but not required, don't bother validating it.
928
-     * Also, it uses our email validation instead of WP API's default.
929
-     *
930
-     * @param                 $value
931
-     * @param WP_REST_Request $request
932
-     * @param                 $param
933
-     * @return bool|true|WP_Error
934
-     * @throws InvalidArgumentException
935
-     * @throws InvalidInterfaceException
936
-     * @throws InvalidDataTypeException
937
-     */
938
-    public static function default_sanitize_callback( $value, WP_REST_Request $request, $param)
939
-    {
940
-        $attributes = $request->get_attributes();
941
-        if (! isset($attributes['args'][$param])
942
-            || ! is_array($attributes['args'][$param])) {
943
-            $validation_result = true;
944
-        } else {
945
-            $args = $attributes['args'][$param];
946
-            if ((
947
-                    $value === ''
948
-                    || $value === null
949
-                )
950
-                && (! isset($args['required'])
951
-                    || $args['required'] === false
952
-                )
953
-            ) {
954
-                //not required and not provided? that's cool
955
-                $validation_result = true;
956
-            } elseif (isset($args['format'])
957
-                && $args['format'] === 'email'
958
-            ) {
959
-                $validation_result = true;
960
-                if (! self::_validate_email($value)) {
961
-                    $validation_result = new WP_Error(
962
-                        'rest_invalid_param',
963
-                        esc_html__(
964
-                            'The email address is not valid or does not exist.',
965
-                            'event_espresso'
966
-                        )
967
-                    );
968
-                }
969
-            } else {
970
-                $validation_result = rest_validate_value_from_schema($value, $args, $param);
971
-            }
972
-        }
973
-        if (is_wp_error($validation_result)) {
974
-            return $validation_result;
975
-        }
976
-        return rest_sanitize_request_arg($value, $request, $param);
977
-    }
978
-
979
-
980
-
981
-    /**
982
-     * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email()
983
-     *
984
-     * @param $email
985
-     * @return bool
986
-     * @throws InvalidArgumentException
987
-     * @throws InvalidInterfaceException
988
-     * @throws InvalidDataTypeException
989
-     */
990
-    protected static function _validate_email($email){
991
-        try {
992
-            EmailAddressFactory::create($email);
993
-            return true;
994
-        } catch (EmailValidationException $e) {
995
-            return false;
996
-        }
997
-    }
998
-
999
-
1000
-
1001
-    /**
1002
-     * Gets routes for the config
1003
-     *
1004
-     * @return array @see _register_model_routes
1005
-     * @deprecated since version 4.9.1
1006
-     */
1007
-    protected function _register_config_routes()
1008
-    {
1009
-        $config_routes = array();
1010
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
1011
-            $config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version(
1012
-                $version,
1013
-                $hidden_endpoint
1014
-            );
1015
-        }
1016
-        return $config_routes;
1017
-    }
1018
-
1019
-
1020
-
1021
-    /**
1022
-     * Gets routes for the config for the specified version
1023
-     *
1024
-     * @param string  $version
1025
-     * @param boolean $hidden_endpoint
1026
-     * @return array
1027
-     */
1028
-    protected function _get_config_route_data_for_version($version, $hidden_endpoint)
1029
-    {
1030
-        return array(
1031
-            'config'    => array(
1032
-                array(
1033
-                    'callback'        => array(
1034
-                        'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1035
-                        'handleRequest',
1036
-                    ),
1037
-                    'methods'         => WP_REST_Server::READABLE,
1038
-                    'hidden_endpoint' => $hidden_endpoint,
1039
-                    'callback_args'   => array($version),
1040
-                ),
1041
-            ),
1042
-            'site_info' => array(
1043
-                array(
1044
-                    'callback'        => array(
1045
-                        'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1046
-                        'handleRequestSiteInfo',
1047
-                    ),
1048
-                    'methods'         => WP_REST_Server::READABLE,
1049
-                    'hidden_endpoint' => $hidden_endpoint,
1050
-                    'callback_args'   => array($version),
1051
-                ),
1052
-            ),
1053
-        );
1054
-    }
1055
-
1056
-
1057
-
1058
-    /**
1059
-     * Gets the meta info routes
1060
-     *
1061
-     * @return array @see _register_model_routes
1062
-     * @deprecated since version 4.9.1
1063
-     */
1064
-    protected function _register_meta_routes()
1065
-    {
1066
-        $meta_routes = array();
1067
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
1068
-            $meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version(
1069
-                $version,
1070
-                $hidden_endpoint
1071
-            );
1072
-        }
1073
-        return $meta_routes;
1074
-    }
1075
-
1076
-
1077
-
1078
-    /**
1079
-     * @param string  $version
1080
-     * @param boolean $hidden_endpoint
1081
-     * @return array
1082
-     */
1083
-    protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false)
1084
-    {
1085
-        return array(
1086
-            'resources' => array(
1087
-                array(
1088
-                    'callback'        => array(
1089
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Meta',
1090
-                        'handleRequestModelsMeta',
1091
-                    ),
1092
-                    'methods'         => WP_REST_Server::READABLE,
1093
-                    'hidden_endpoint' => $hidden_endpoint,
1094
-                    'callback_args'   => array($version),
1095
-                ),
1096
-            ),
1097
-        );
1098
-    }
1099
-
1100
-
1101
-
1102
-    /**
1103
-     * Tries to hide old 4.6 endpoints from the
1104
-     *
1105
-     * @param array $route_data
1106
-     * @return array
1107
-     * @throws \EE_Error
1108
-     */
1109
-    public static function hide_old_endpoints($route_data)
1110
-    {
1111
-        //allow API clients to override which endpoints get hidden, in case
1112
-        //they want to discover particular endpoints
1113
-        //also, we don't have access to the request so we have to just grab it from the superglobal
1114
-        $force_show_ee_namespace = ltrim(
1115
-            EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''),
1116
-            '/'
1117
-        );
1118
-        foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) {
1119
-            foreach ($relative_urls as $resource_name => $endpoints) {
1120
-                foreach ($endpoints as $key => $endpoint) {
1121
-                    //skip schema and other route options
1122
-                    if (! is_numeric($key)) {
1123
-                        continue;
1124
-                    }
1125
-                    //by default, hide "hidden_endpoint"s, unless the request indicates
1126
-                    //to $force_show_ee_namespace, in which case only show that one
1127
-                    //namespace's endpoints (and hide all others)
1128
-                    if (
1129
-                        ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1130
-                        || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1131
-                    ) {
1132
-                        $full_route = '/' . ltrim($namespace, '/');
1133
-                        $full_route .= '/' . ltrim($resource_name, '/');
1134
-                        unset($route_data[$full_route]);
1135
-                    }
1136
-                }
1137
-            }
1138
-        }
1139
-        return $route_data;
1140
-    }
1141
-
1142
-
1143
-
1144
-    /**
1145
-     * Returns an array describing which versions of core support serving requests for.
1146
-     * Keys are core versions' major and minor version, and values are the
1147
-     * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like
1148
-     * data by just removing a few models and fields from the responses. However, 4.15 might remove
1149
-     * the answers table entirely, in which case it would be very difficult for
1150
-     * it to serve 4.6-style responses.
1151
-     * Versions of core that are missing from this array are unknowns.
1152
-     * previous ver
1153
-     *
1154
-     * @return array
1155
-     */
1156
-    public static function version_compatibilities()
1157
-    {
1158
-        return apply_filters(
1159
-            'FHEE__EED_Core_REST_API__version_compatibilities',
1160
-            array(
1161
-                '4.8.29' => '4.8.29',
1162
-                '4.8.33' => '4.8.29',
1163
-                '4.8.34' => '4.8.29',
1164
-                '4.8.36' => '4.8.29',
1165
-            )
1166
-        );
1167
-    }
1168
-
1169
-
1170
-
1171
-    /**
1172
-     * Gets the latest API version served. Eg if there
1173
-     * are two versions served of the API, 4.8.29 and 4.8.32, and
1174
-     * we are on core version 4.8.34, it will return the string "4.8.32"
1175
-     *
1176
-     * @return string
1177
-     */
1178
-    public static function latest_rest_api_version()
1179
-    {
1180
-        $versions_served = \EED_Core_Rest_Api::versions_served();
1181
-        $versions_served_keys = array_keys($versions_served);
1182
-        return end($versions_served_keys);
1183
-    }
1184
-
1185
-
1186
-
1187
-    /**
1188
-     * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of
1189
-     * EE the API can serve requests for. Eg, if we are on 4.15 of core, and
1190
-     * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ).
1191
-     * We also indicate whether or not this version should be put in the index or not
1192
-     *
1193
-     * @return array keys are API version numbers (just major and minor numbers), and values
1194
-     * are whether or not they should be hidden
1195
-     */
1196
-    public static function versions_served()
1197
-    {
1198
-        $versions_served = array();
1199
-        $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities();
1200
-        $lowest_compatible_version = end($possibly_served_versions);
1201
-        reset($possibly_served_versions);
1202
-        $versions_served_historically = array_keys($possibly_served_versions);
1203
-        $latest_version = end($versions_served_historically);
1204
-        reset($versions_served_historically);
1205
-        //for each version of core we have ever served:
1206
-        foreach ($versions_served_historically as $key_versioned_endpoint) {
1207
-            //if it's not above the current core version, and it's compatible with the current version of core
1208
-            if ($key_versioned_endpoint === $latest_version) {
1209
-                //don't hide the latest version in the index
1210
-                $versions_served[$key_versioned_endpoint] = false;
1211
-            } elseif (
1212
-                $key_versioned_endpoint >= $lowest_compatible_version
1213
-                && $key_versioned_endpoint < EED_Core_Rest_Api::core_version()
1214
-            ) {
1215
-                //include, but hide, previous versions which are still supported
1216
-                $versions_served[$key_versioned_endpoint] = true;
1217
-            } elseif (apply_filters(
1218
-                'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions',
1219
-                false,
1220
-                $possibly_served_versions
1221
-            )) {
1222
-                //if a version is no longer supported, don't include it in index or list of versions served
1223
-                $versions_served[$key_versioned_endpoint] = true;
1224
-            }
1225
-        }
1226
-        return $versions_served;
1227
-    }
1228
-
1229
-
1230
-
1231
-    /**
1232
-     * Gets the major and minor version of EE core's version string
1233
-     *
1234
-     * @return string
1235
-     */
1236
-    public static function core_version()
1237
-    {
1238
-        return apply_filters(
1239
-            'FHEE__EED_Core_REST_API__core_version',
1240
-            implode(
1241
-                '.',
1242
-                array_slice(
1243
-                    explode(
1244
-                        '.',
1245
-                        espresso_version()
1246
-                    ),
1247
-                0,
1248
-                3
1249
-                )
1250
-            )
1251
-        );
1252
-    }
1253
-
1254
-
1255
-
1256
-    /**
1257
-     * Gets the default limit that should be used when querying for resources
1258
-     *
1259
-     * @return int
1260
-     */
1261
-    public static function get_default_query_limit()
1262
-    {
1263
-        //we actually don't use a const because we want folks to always use
1264
-        //this method, not the const directly
1265
-        return apply_filters(
1266
-            'FHEE__EED_Core_Rest_Api__get_default_query_limit',
1267
-            50
1268
-        );
1269
-    }
1270
-
1271
-
1272
-    /**
1273
-     *
1274
-     * @param string $version api version string (i.e. '4.8.36')
1275
-     * @return array
1276
-     */
1277
-    public static function getCollectionRoutesIndexedByModelName($version = '')
1278
-    {
1279
-        $version = empty($version) ? self::latest_rest_api_version() : $version;
1280
-        $model_names = self::model_names_with_plural_routes($version);
1281
-        $collection_routes = array();
1282
-        foreach ($model_names as $model_name => $model_class_name) {
1283
-            $collection_routes[strtolower($model_name)] = '/' . self::ee_api_namespace . $version . '/'
1284
-                                                          . EEH_Inflector::pluralize_and_lower($model_name);
1285
-
1286
-        }
1287
-        return $collection_routes;
1288
-    }
1289
-
1290
-
1291
-
1292
-    /**
1293
-     *    run - initial module setup
1294
-     *
1295
-     * @access    public
1296
-     * @param  WP $WP
1297
-     * @return    void
1298
-     */
1299
-    public function run($WP)
1300
-    {
1301
-    }
31
+	const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/';
32
+
33
+	const saved_routes_option_names  = 'ee_core_routes';
34
+
35
+	/**
36
+	 * string used in _links response bodies to make them globally unique.
37
+	 *
38
+	 * @see http://v2.wp-api.org/extending/linking/
39
+	 */
40
+	const ee_api_link_namespace = 'https://api.eventespresso.com/';
41
+
42
+	/**
43
+	 * @var CalculatedModelFields
44
+	 */
45
+	protected static $_field_calculator;
46
+
47
+
48
+
49
+	/**
50
+	 * @return EED_Core_Rest_Api|EED_Module
51
+	 */
52
+	public static function instance()
53
+	{
54
+		self::$_field_calculator = new CalculatedModelFields();
55
+		return parent::get_instance(__CLASS__);
56
+	}
57
+
58
+
59
+
60
+	/**
61
+	 *    set_hooks - for hooking into EE Core, other modules, etc
62
+	 *
63
+	 * @access    public
64
+	 * @return    void
65
+	 */
66
+	public static function set_hooks()
67
+	{
68
+		self::set_hooks_both();
69
+	}
70
+
71
+
72
+
73
+	/**
74
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
75
+	 *
76
+	 * @access    public
77
+	 * @return    void
78
+	 */
79
+	public static function set_hooks_admin()
80
+	{
81
+		self::set_hooks_both();
82
+	}
83
+
84
+
85
+
86
+	public static function set_hooks_both()
87
+	{
88
+		add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10);
89
+		add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5);
90
+		add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2);
91
+		add_filter('rest_index',
92
+			array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex'));
93
+		EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change();
94
+	}
95
+
96
+
97
+
98
+	/**
99
+	 * sets up hooks which only need to be included as part of REST API requests;
100
+	 * other requests like to the frontend or admin etc don't need them
101
+	 *
102
+	 * @throws \EE_Error
103
+	 */
104
+	public static function set_hooks_rest_api()
105
+	{
106
+		//set hooks which account for changes made to the API
107
+		EED_Core_Rest_Api::_set_hooks_for_changes();
108
+	}
109
+
110
+
111
+
112
+	/**
113
+	 * public wrapper of _set_hooks_for_changes.
114
+	 * Loads all the hooks which make requests to old versions of the API
115
+	 * appear the same as they always did
116
+	 *
117
+	 * @throws EE_Error
118
+	 */
119
+	public static function set_hooks_for_changes()
120
+	{
121
+		self::_set_hooks_for_changes();
122
+	}
123
+
124
+
125
+
126
+	/**
127
+	 * Loads all the hooks which make requests to old versions of the API
128
+	 * appear the same as they always did
129
+	 *
130
+	 * @throws EE_Error
131
+	 */
132
+	protected static function _set_hooks_for_changes()
133
+	{
134
+		$folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
135
+		foreach ($folder_contents as $classname_in_namespace => $filepath) {
136
+			//ignore the base parent class
137
+			//and legacy named classes
138
+			if ($classname_in_namespace === 'ChangesInBase'
139
+				|| strpos($classname_in_namespace, 'Changes_In_') === 0
140
+			) {
141
+				continue;
142
+			}
143
+			$full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
144
+			if (class_exists($full_classname)) {
145
+				$instance_of_class = new $full_classname;
146
+				if ($instance_of_class instanceof ChangesInBase) {
147
+					$instance_of_class->setHooks();
148
+				}
149
+			}
150
+		}
151
+	}
152
+
153
+
154
+
155
+	/**
156
+	 * Filters the WP routes to add our EE-related ones. This takes a bit of time
157
+	 * so we actually prefer to only do it when an EE plugin is activated or upgraded
158
+	 *
159
+	 * @throws \EE_Error
160
+	 */
161
+	public static function register_routes()
162
+	{
163
+		foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) {
164
+			foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) {
165
+				/**
166
+				 * @var array $data_for_multiple_endpoints numerically indexed array
167
+				 *                                         but can also contain route options like {
168
+				 * @type array    $schema                      {
169
+				 * @type callable $schema_callback
170
+				 * @type array    $callback_args               arguments that will be passed to the callback, after the
171
+				 * WP_REST_Request of course
172
+				 * }
173
+				 * }
174
+				 */
175
+				//when registering routes, register all the endpoints' data at the same time
176
+				$multiple_endpoint_args = array();
177
+				foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) {
178
+					/**
179
+					 * @var array     $data_for_single_endpoint {
180
+					 * @type callable $callback
181
+					 * @type string methods
182
+					 * @type array args
183
+					 * @type array _links
184
+					 * @type array    $callback_args            arguments that will be passed to the callback, after the
185
+					 * WP_REST_Request of course
186
+					 * }
187
+					 */
188
+					//skip route options
189
+					if (! is_numeric($endpoint_key)) {
190
+						continue;
191
+					}
192
+					if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
193
+						throw new EE_Error(
194
+							esc_html__(
195
+								// @codingStandardsIgnoreStart
196
+								'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).',
197
+								// @codingStandardsIgnoreEnd
198
+								'event_espresso')
199
+						);
200
+					}
201
+					$callback = $data_for_single_endpoint['callback'];
202
+					$single_endpoint_args = array(
203
+						'methods' => $data_for_single_endpoint['methods'],
204
+						'args'    => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args']
205
+							: array(),
206
+					);
207
+					if (isset($data_for_single_endpoint['_links'])) {
208
+						$single_endpoint_args['_links'] = $data_for_single_endpoint['_links'];
209
+					}
210
+					if (isset($data_for_single_endpoint['callback_args'])) {
211
+						$callback_args = $data_for_single_endpoint['callback_args'];
212
+						$single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
213
+							$callback,
214
+							$callback_args
215
+						) {
216
+							array_unshift($callback_args, $request);
217
+							return call_user_func_array(
218
+								$callback,
219
+								$callback_args
220
+							);
221
+						};
222
+					} else {
223
+						$single_endpoint_args['callback'] = $data_for_single_endpoint['callback'];
224
+					}
225
+					$multiple_endpoint_args[] = $single_endpoint_args;
226
+				}
227
+				if (isset($data_for_multiple_endpoints['schema'])) {
228
+					$schema_route_data = $data_for_multiple_endpoints['schema'];
229
+					$schema_callback = $schema_route_data['schema_callback'];
230
+					$callback_args = $schema_route_data['callback_args'];
231
+					$multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
232
+						return call_user_func_array(
233
+							$schema_callback,
234
+							$callback_args
235
+						);
236
+					};
237
+				}
238
+				register_rest_route(
239
+					$namespace,
240
+					$relative_route,
241
+					$multiple_endpoint_args
242
+				);
243
+			}
244
+		}
245
+	}
246
+
247
+
248
+
249
+	/**
250
+	 * Checks if there was a version change or something that merits invalidating the cached
251
+	 * route data. If so, invalidates the cached route data so that it gets refreshed
252
+	 * next time the WP API is used
253
+	 */
254
+	public static function invalidate_cached_route_data_on_version_change()
255
+	{
256
+		if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) {
257
+			EED_Core_Rest_Api::invalidate_cached_route_data();
258
+		}
259
+		foreach (EE_Registry::instance()->addons as $addon) {
260
+			if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) {
261
+				EED_Core_Rest_Api::invalidate_cached_route_data();
262
+			}
263
+		}
264
+	}
265
+
266
+
267
+
268
+	/**
269
+	 * Removes the cached route data so it will get refreshed next time the WP API is used
270
+	 */
271
+	public static function invalidate_cached_route_data()
272
+	{
273
+		//delete the saved EE REST API routes
274
+		foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
275
+			delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
276
+		}
277
+	}
278
+
279
+
280
+
281
+	/**
282
+	 * Gets the EE route data
283
+	 *
284
+	 * @return array top-level key is the namespace, next-level key is the route and its value is array{
285
+	 * @throws \EE_Error
286
+	 * @type string|array $callback
287
+	 * @type string       $methods
288
+	 * @type boolean      $hidden_endpoint
289
+	 * }
290
+	 */
291
+	public static function get_ee_route_data()
292
+	{
293
+		$ee_routes = array();
294
+		foreach (self::versions_served() as $version => $hidden_endpoints) {
295
+			$ee_routes[self::ee_api_namespace . $version] = self::_get_ee_route_data_for_version(
296
+				$version,
297
+				$hidden_endpoints
298
+			);
299
+		}
300
+		return $ee_routes;
301
+	}
302
+
303
+
304
+
305
+	/**
306
+	 * Gets the EE route data from the wp options if it exists already,
307
+	 * otherwise re-generates it and saves it to the option
308
+	 *
309
+	 * @param string  $version
310
+	 * @param boolean $hidden_endpoints
311
+	 * @return array
312
+	 * @throws \EE_Error
313
+	 */
314
+	protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
315
+	{
316
+		$ee_routes = get_option(self::saved_routes_option_names . $version, null);
317
+		if (! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) {
318
+			$ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
319
+		}
320
+		return $ee_routes;
321
+	}
322
+
323
+
324
+
325
+	/**
326
+	 * Saves the EE REST API route data to a wp option and returns it
327
+	 *
328
+	 * @param string  $version
329
+	 * @param boolean $hidden_endpoints
330
+	 * @return mixed|null
331
+	 * @throws \EE_Error
332
+	 */
333
+	protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false)
334
+	{
335
+		$instance = self::instance();
336
+		$routes = apply_filters(
337
+			'EED_Core_Rest_Api__save_ee_route_data_for_version__routes',
338
+			array_replace_recursive(
339
+				$instance->_get_config_route_data_for_version($version, $hidden_endpoints),
340
+				$instance->_get_meta_route_data_for_version($version, $hidden_endpoints),
341
+				$instance->_get_model_route_data_for_version($version, $hidden_endpoints),
342
+				$instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
343
+			)
344
+		);
345
+		$option_name = self::saved_routes_option_names . $version;
346
+		if (get_option($option_name)) {
347
+			update_option($option_name, $routes, true);
348
+		} else {
349
+			add_option($option_name, $routes, null, 'no');
350
+		}
351
+		return $routes;
352
+	}
353
+
354
+
355
+
356
+	/**
357
+	 * Calculates all the EE routes and saves it to a WordPress option so we don't
358
+	 * need to calculate it on every request
359
+	 *
360
+	 * @deprecated since version 4.9.1
361
+	 * @return void
362
+	 */
363
+	public static function save_ee_routes()
364
+	{
365
+		if (EE_Maintenance_Mode::instance()->models_can_query()) {
366
+			$instance = self::instance();
367
+			$routes = apply_filters(
368
+				'EED_Core_Rest_Api__save_ee_routes__routes',
369
+				array_replace_recursive(
370
+					$instance->_register_config_routes(),
371
+					$instance->_register_meta_routes(),
372
+					$instance->_register_model_routes(),
373
+					$instance->_register_rpc_routes()
374
+				)
375
+			);
376
+			update_option(self::saved_routes_option_names, $routes, true);
377
+		}
378
+	}
379
+
380
+
381
+
382
+	/**
383
+	 * Gets all the route information relating to EE models
384
+	 *
385
+	 * @return array @see get_ee_route_data
386
+	 * @deprecated since version 4.9.1
387
+	 */
388
+	protected function _register_model_routes()
389
+	{
390
+		$model_routes = array();
391
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
392
+			$model_routes[EED_Core_Rest_Api::ee_api_namespace
393
+						  . $version] = $this->_get_config_route_data_for_version($version, $hidden_endpoint);
394
+		}
395
+		return $model_routes;
396
+	}
397
+
398
+
399
+
400
+	/**
401
+	 * Decides whether or not to add write endpoints for this model.
402
+	 *
403
+	 * Currently, this defaults to exclude all global tables and models
404
+	 * which would allow inserting WP core data (we don't want to duplicate
405
+	 * what WP API does, as it's unnecessary, extra work, and potentially extra bugs)
406
+	 * @param EEM_Base $model
407
+	 * @return bool
408
+	 */
409
+	public static function should_have_write_endpoints(EEM_Base $model)
410
+	{
411
+		if ($model->is_wp_core_model()){
412
+			return false;
413
+		}
414
+		foreach($model->get_tables() as $table){
415
+			if( $table->is_global()){
416
+				return false;
417
+			}
418
+		}
419
+		return true;
420
+	}
421
+
422
+
423
+
424
+	/**
425
+	 * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`)
426
+	 * in this versioned namespace of EE4
427
+	 * @param $version
428
+	 * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
429
+	 */
430
+	public static function model_names_with_plural_routes($version){
431
+		$model_version_info = new ModelVersionInfo($version);
432
+		$models_to_register = $model_version_info->modelsForRequestedVersion();
433
+		//let's not bother having endpoints for extra metas
434
+		unset(
435
+			$models_to_register['Extra_Meta'],
436
+			$models_to_register['Extra_Join'],
437
+			$models_to_register['Post_Meta']
438
+		);
439
+		return apply_filters(
440
+			'FHEE__EED_Core_REST_API___register_model_routes',
441
+			$models_to_register
442
+		);
443
+	}
444
+
445
+
446
+
447
+	/**
448
+	 * Gets the route data for EE models in the specified version
449
+	 *
450
+	 * @param string  $version
451
+	 * @param boolean $hidden_endpoint
452
+	 * @return array
453
+	 * @throws EE_Error
454
+	 */
455
+	protected function _get_model_route_data_for_version($version, $hidden_endpoint = false)
456
+	{
457
+		$model_routes = array();
458
+		$model_version_info = new ModelVersionInfo($version);
459
+		foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
460
+			$model = \EE_Registry::instance()->load_model($model_name);
461
+			//if this isn't a valid model then let's skip iterate to the next item in the loop.
462
+			if (! $model instanceof EEM_Base) {
463
+				continue;
464
+			}
465
+			//yes we could just register one route for ALL models, but then they wouldn't show up in the index
466
+			$plural_model_route = EED_Core_Rest_Api::get_collection_route($model);
467
+			$singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)');
468
+			$model_routes[$plural_model_route] = array(
469
+				array(
470
+					'callback'        => array(
471
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
472
+						'handleRequestGetAll',
473
+					),
474
+					'callback_args'   => array($version, $model_name),
475
+					'methods'         => WP_REST_Server::READABLE,
476
+					'hidden_endpoint' => $hidden_endpoint,
477
+					'args'            => $this->_get_read_query_params($model, $version),
478
+					'_links'          => array(
479
+						'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
480
+					),
481
+				),
482
+				'schema' => array(
483
+					'schema_callback' => array(
484
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
485
+						'handleSchemaRequest',
486
+					),
487
+					'callback_args'   => array($version, $model_name),
488
+				),
489
+			);
490
+			$model_routes[$singular_model_route] = array(
491
+				array(
492
+					'callback'        => array(
493
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
494
+						'handleRequestGetOne',
495
+					),
496
+					'callback_args'   => array($version, $model_name),
497
+					'methods'         => WP_REST_Server::READABLE,
498
+					'hidden_endpoint' => $hidden_endpoint,
499
+					'args'            => $this->_get_response_selection_query_params($model, $version),
500
+				),
501
+			);
502
+			if( apply_filters(
503
+				'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
504
+				EED_Core_Rest_Api::should_have_write_endpoints($model),
505
+				$model
506
+			)){
507
+				$model_routes[$plural_model_route][] = array(
508
+					'callback'        => array(
509
+						'EventEspresso\core\libraries\rest_api\controllers\model\Write',
510
+						'handleRequestInsert',
511
+					),
512
+					'callback_args'   => array($version, $model_name),
513
+					'methods'         => WP_REST_Server::CREATABLE,
514
+					'hidden_endpoint' => $hidden_endpoint,
515
+					'args'            => $this->_get_write_params($model_name, $model_version_info, true),
516
+				);
517
+				$model_routes[$singular_model_route] = array_merge(
518
+					$model_routes[$singular_model_route],
519
+					array(
520
+						array(
521
+							'callback'        => array(
522
+								'EventEspresso\core\libraries\rest_api\controllers\model\Write',
523
+								'handleRequestUpdate',
524
+							),
525
+							'callback_args'   => array($version, $model_name),
526
+							'methods'         => WP_REST_Server::EDITABLE,
527
+							'hidden_endpoint' => $hidden_endpoint,
528
+							'args'            => $this->_get_write_params($model_name, $model_version_info),
529
+						),
530
+						array(
531
+							'callback'        => array(
532
+								'EventEspresso\core\libraries\rest_api\controllers\model\Write',
533
+								'handleRequestDelete',
534
+							),
535
+							'callback_args'   => array($version, $model_name),
536
+							'methods'         => WP_REST_Server::DELETABLE,
537
+							'hidden_endpoint' => $hidden_endpoint,
538
+							'args'            => $this->_get_delete_query_params($model, $version),
539
+						)
540
+					)
541
+				);
542
+			}
543
+			foreach ($model->relation_settings() as $relation_name => $relation_obj) {
544
+
545
+				$related_route = EED_Core_Rest_Api::get_relation_route_via(
546
+					$model,
547
+					'(?P<id>[^\/]+)',
548
+					$relation_obj
549
+				);
550
+				$endpoints = array(
551
+					array(
552
+						'callback'        => array(
553
+							'EventEspresso\core\libraries\rest_api\controllers\model\Read',
554
+							'handleRequestGetRelated',
555
+						),
556
+						'callback_args'   => array($version, $model_name, $relation_name),
557
+						'methods'         => WP_REST_Server::READABLE,
558
+						'hidden_endpoint' => $hidden_endpoint,
559
+						'args'            => $this->_get_read_query_params($relation_obj->get_other_model(), $version),
560
+					),
561
+				);
562
+				$model_routes[$related_route] = $endpoints;
563
+			}
564
+		}
565
+		return $model_routes;
566
+	}
567
+
568
+
569
+
570
+	/**
571
+	 * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace,
572
+	 * excluding the preceding slash.
573
+	 * Eg you pass get_plural_route_to('Event') = 'events'
574
+	 *
575
+	 * @param EEM_Base $model
576
+	 * @return string
577
+	 */
578
+	public static function get_collection_route(EEM_Base $model)
579
+	{
580
+		return EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
581
+	}
582
+
583
+
584
+
585
+	/**
586
+	 * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
587
+	 * excluding the preceding slash.
588
+	 * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
589
+	 *
590
+	 * @param EEM_Base $model eg Event or Venue
591
+	 * @param string $id
592
+	 * @return string
593
+	 */
594
+	public static function get_entity_route($model, $id)
595
+	{
596
+		return EED_Core_Rest_Api::get_collection_route($model). '/' . $id;
597
+	}
598
+
599
+
600
+	/**
601
+	 * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
602
+	 * excluding the preceding slash.
603
+	 * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
604
+	 *
605
+	 * @param EEM_Base                 $model eg Event or Venue
606
+	 * @param string                 $id
607
+	 * @param EE_Model_Relation_Base $relation_obj
608
+	 * @return string
609
+	 */
610
+	public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj)
611
+	{
612
+		$related_model_name_endpoint_part = ModelRead::getRelatedEntityName(
613
+			$relation_obj->get_other_model()->get_this_model_name(),
614
+			$relation_obj
615
+		);
616
+		return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
617
+	}
618
+
619
+
620
+
621
+	/**
622
+	 * Adds onto the $relative_route the EE4 REST API versioned namespace.
623
+	 * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events'
624
+	 * @param string $relative_route
625
+	 * @param string $version
626
+	 * @return string
627
+	 */
628
+	public static function get_versioned_route_to($relative_route, $version = '4.8.36'){
629
+		return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
630
+	}
631
+
632
+
633
+
634
+	/**
635
+	 * Adds all the RPC-style routes (remote procedure call-like routes, ie
636
+	 * routes that don't conform to the traditional REST CRUD-style).
637
+	 *
638
+	 * @deprecated since 4.9.1
639
+	 */
640
+	protected function _register_rpc_routes()
641
+	{
642
+		$routes = array();
643
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
644
+			$routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version(
645
+				$version,
646
+				$hidden_endpoint
647
+			);
648
+		}
649
+		return $routes;
650
+	}
651
+
652
+
653
+
654
+	/**
655
+	 * @param string  $version
656
+	 * @param boolean $hidden_endpoint
657
+	 * @return array
658
+	 */
659
+	protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false)
660
+	{
661
+		$this_versions_routes = array();
662
+		//checkin endpoint
663
+		$this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array(
664
+			array(
665
+				'callback'        => array(
666
+					'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin',
667
+					'handleRequestToggleCheckin',
668
+				),
669
+				'methods'         => WP_REST_Server::CREATABLE,
670
+				'hidden_endpoint' => $hidden_endpoint,
671
+				'args'            => array(
672
+					'force' => array(
673
+						'required'    => false,
674
+						'default'     => false,
675
+						'description' => __(
676
+							// @codingStandardsIgnoreStart
677
+							'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses',
678
+							// @codingStandardsIgnoreEnd
679
+							'event_espresso'
680
+						),
681
+					),
682
+				),
683
+				'callback_args'   => array($version),
684
+			),
685
+		);
686
+		return apply_filters(
687
+			'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes',
688
+			$this_versions_routes,
689
+			$version,
690
+			$hidden_endpoint
691
+		);
692
+	}
693
+
694
+
695
+
696
+	/**
697
+	 * Gets the query params that can be used when request one or many
698
+	 *
699
+	 * @param EEM_Base $model
700
+	 * @param string   $version
701
+	 * @return array
702
+	 */
703
+	protected function _get_response_selection_query_params(\EEM_Base $model, $version)
704
+	{
705
+		return apply_filters(
706
+			'FHEE__EED_Core_Rest_Api___get_response_selection_query_params',
707
+			array(
708
+				'include'   => array(
709
+					'required' => false,
710
+					'default'  => '*',
711
+					'type'     => 'string',
712
+				),
713
+				'calculate' => array(
714
+					'required'          => false,
715
+					'default'           => '',
716
+					'enum'              => self::$_field_calculator->retrieveCalculatedFieldsForModel($model),
717
+					'type'              => 'string',
718
+					//because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization
719
+					//freaks out. We'll just validate this argument while handling the request
720
+					'validate_callback' => null,
721
+					'sanitize_callback' => null,
722
+				),
723
+			),
724
+			$model,
725
+			$version
726
+		);
727
+	}
728
+
729
+
730
+
731
+	/**
732
+	 * Gets the parameters acceptable for delete requests
733
+	 *
734
+	 * @param \EEM_Base $model
735
+	 * @param string    $version
736
+	 * @return array
737
+	 */
738
+	protected function _get_delete_query_params(\EEM_Base $model, $version)
739
+	{
740
+		$params_for_delete = array(
741
+			'allow_blocking' => array(
742
+				'required' => false,
743
+				'default'  => true,
744
+				'type'     => 'boolean',
745
+			),
746
+		);
747
+		$params_for_delete['force'] = array(
748
+			'required' => false,
749
+			'default'  => false,
750
+			'type'     => 'boolean',
751
+		);
752
+		return apply_filters(
753
+			'FHEE__EED_Core_Rest_Api___get_delete_query_params',
754
+			$params_for_delete,
755
+			$model,
756
+			$version
757
+		);
758
+	}
759
+
760
+
761
+
762
+	/**
763
+	 * Gets info about reading query params that are acceptable
764
+	 *
765
+	 * @param \EEM_Base $model eg 'Event' or 'Venue'
766
+	 * @param  string   $version
767
+	 * @return array    describing the args acceptable when querying this model
768
+	 * @throws EE_Error
769
+	 */
770
+	protected function _get_read_query_params(\EEM_Base $model, $version)
771
+	{
772
+		$default_orderby = array();
773
+		foreach ($model->get_combined_primary_key_fields() as $key_field) {
774
+			$default_orderby[$key_field->get_name()] = 'ASC';
775
+		}
776
+		return array_merge(
777
+			$this->_get_response_selection_query_params($model, $version),
778
+			array(
779
+				'where'    => array(
780
+					'required' => false,
781
+					'default'  => array(),
782
+					'type'     => 'object',
783
+					//because we accept an almost infinite list of possible where conditions, WP
784
+					// core validation and sanitization freaks out. We'll just validate this argument
785
+					// while handling the request
786
+					'validate_callback' => null,
787
+					'sanitize_callback' => null,
788
+				),
789
+				'limit'    => array(
790
+					'required' => false,
791
+					'default'  => EED_Core_Rest_Api::get_default_query_limit(),
792
+					'type'     => array(
793
+						'array',
794
+						'string',
795
+						'integer',
796
+					),
797
+					//because we accept a variety of types, WP core validation and sanitization
798
+					//freaks out. We'll just validate this argument while handling the request
799
+					'validate_callback' => null,
800
+					'sanitize_callback' => null,
801
+				),
802
+				'order_by' => array(
803
+					'required' => false,
804
+					'default'  => $default_orderby,
805
+					'type'     => array(
806
+						'object',
807
+						'string',
808
+					),//because we accept a variety of types, WP core validation and sanitization
809
+					//freaks out. We'll just validate this argument while handling the request
810
+					'validate_callback' => null,
811
+					'sanitize_callback' => null,
812
+				),
813
+				'group_by' => array(
814
+					'required' => false,
815
+					'default'  => null,
816
+					'type'     => array(
817
+						'object',
818
+						'string',
819
+					),
820
+					//because we accept  an almost infinite list of possible groupings,
821
+					// WP core validation and sanitization
822
+					//freaks out. We'll just validate this argument while handling the request
823
+					'validate_callback' => null,
824
+					'sanitize_callback' => null,
825
+				),
826
+				'having'   => array(
827
+					'required' => false,
828
+					'default'  => null,
829
+					'type'     => 'object',
830
+					//because we accept an almost infinite list of possible where conditions, WP
831
+					// core validation and sanitization freaks out. We'll just validate this argument
832
+					// while handling the request
833
+					'validate_callback' => null,
834
+					'sanitize_callback' => null,
835
+				),
836
+				'caps'     => array(
837
+					'required' => false,
838
+					'default'  => EEM_Base::caps_read,
839
+					'type'     => 'string',
840
+					'enum'     => array(
841
+						EEM_Base::caps_read,
842
+						EEM_Base::caps_read_admin,
843
+						EEM_Base::caps_edit,
844
+						EEM_Base::caps_delete
845
+					)
846
+				),
847
+			)
848
+		);
849
+	}
850
+
851
+
852
+
853
+	/**
854
+	 * Gets parameter information for a model regarding writing data
855
+	 *
856
+	 * @param string           $model_name
857
+	 * @param ModelVersionInfo $model_version_info
858
+	 * @param boolean          $create                                       whether this is for request to create (in which case we need
859
+	 *                                                                       all required params) or just to update (in which case we don't need those on every request)
860
+	 * @return array
861
+	 */
862
+	protected function _get_write_params(
863
+		$model_name,
864
+		ModelVersionInfo $model_version_info,
865
+		$create = false
866
+	) {
867
+		$model = EE_Registry::instance()->load_model($model_name);
868
+		$fields = $model_version_info->fieldsOnModelInThisVersion($model);
869
+		$args_info = array();
870
+		foreach ($fields as $field_name => $field_obj) {
871
+			if ($field_obj->is_auto_increment()) {
872
+				//totally ignore auto increment IDs
873
+				continue;
874
+			}
875
+			$arg_info = $field_obj->getSchema();
876
+			$required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null;
877
+			$arg_info['required'] = $required;
878
+			//remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right?
879
+			unset($arg_info['readonly']);
880
+			$schema_properties = $field_obj->getSchemaProperties();
881
+			if (
882
+				isset($schema_properties['raw'])
883
+				&& $field_obj->getSchemaType() === 'object'
884
+			) {
885
+				//if there's a "raw" form of this argument, use those properties instead
886
+				$arg_info = array_replace(
887
+					$arg_info,
888
+					$schema_properties['raw']
889
+				);
890
+			}
891
+			$arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson(
892
+				$field_obj,
893
+				$field_obj->get_default_value(),
894
+				$model_version_info->requestedVersion()
895
+			);
896
+			//we do our own validation and sanitization within the controller
897
+			if(function_exists('rest_validate_value_from_schema')){
898
+				$sanitize_callback = array(
899
+					'EED_Core_Rest_Api',
900
+					'default_sanitize_callback',
901
+				);
902
+			} else {
903
+				$sanitize_callback = null;
904
+			}
905
+			$arg_info['sanitize_callback'] = $sanitize_callback;
906
+			$args_info[$field_name] = $arg_info;
907
+			if ($field_obj instanceof EE_Datetime_Field) {
908
+				$gmt_arg_info = $arg_info;
909
+				$gmt_arg_info['description'] = sprintf(
910
+					esc_html__(
911
+						'%1$s - the value for this field in UTC. Ignored if %2$s is provided.',
912
+						'event_espresso'
913
+					),
914
+					$field_obj->get_nicename(),
915
+					$field_name
916
+				);
917
+				$args_info[$field_name . '_gmt'] = $gmt_arg_info;
918
+			}
919
+		}
920
+		return $args_info;
921
+	}
922
+
923
+
924
+
925
+	/**
926
+	 * Replacement for WP API's 'rest_parse_request_arg'.
927
+	 * If the value is blank but not required, don't bother validating it.
928
+	 * Also, it uses our email validation instead of WP API's default.
929
+	 *
930
+	 * @param                 $value
931
+	 * @param WP_REST_Request $request
932
+	 * @param                 $param
933
+	 * @return bool|true|WP_Error
934
+	 * @throws InvalidArgumentException
935
+	 * @throws InvalidInterfaceException
936
+	 * @throws InvalidDataTypeException
937
+	 */
938
+	public static function default_sanitize_callback( $value, WP_REST_Request $request, $param)
939
+	{
940
+		$attributes = $request->get_attributes();
941
+		if (! isset($attributes['args'][$param])
942
+			|| ! is_array($attributes['args'][$param])) {
943
+			$validation_result = true;
944
+		} else {
945
+			$args = $attributes['args'][$param];
946
+			if ((
947
+					$value === ''
948
+					|| $value === null
949
+				)
950
+				&& (! isset($args['required'])
951
+					|| $args['required'] === false
952
+				)
953
+			) {
954
+				//not required and not provided? that's cool
955
+				$validation_result = true;
956
+			} elseif (isset($args['format'])
957
+				&& $args['format'] === 'email'
958
+			) {
959
+				$validation_result = true;
960
+				if (! self::_validate_email($value)) {
961
+					$validation_result = new WP_Error(
962
+						'rest_invalid_param',
963
+						esc_html__(
964
+							'The email address is not valid or does not exist.',
965
+							'event_espresso'
966
+						)
967
+					);
968
+				}
969
+			} else {
970
+				$validation_result = rest_validate_value_from_schema($value, $args, $param);
971
+			}
972
+		}
973
+		if (is_wp_error($validation_result)) {
974
+			return $validation_result;
975
+		}
976
+		return rest_sanitize_request_arg($value, $request, $param);
977
+	}
978
+
979
+
980
+
981
+	/**
982
+	 * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email()
983
+	 *
984
+	 * @param $email
985
+	 * @return bool
986
+	 * @throws InvalidArgumentException
987
+	 * @throws InvalidInterfaceException
988
+	 * @throws InvalidDataTypeException
989
+	 */
990
+	protected static function _validate_email($email){
991
+		try {
992
+			EmailAddressFactory::create($email);
993
+			return true;
994
+		} catch (EmailValidationException $e) {
995
+			return false;
996
+		}
997
+	}
998
+
999
+
1000
+
1001
+	/**
1002
+	 * Gets routes for the config
1003
+	 *
1004
+	 * @return array @see _register_model_routes
1005
+	 * @deprecated since version 4.9.1
1006
+	 */
1007
+	protected function _register_config_routes()
1008
+	{
1009
+		$config_routes = array();
1010
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
1011
+			$config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version(
1012
+				$version,
1013
+				$hidden_endpoint
1014
+			);
1015
+		}
1016
+		return $config_routes;
1017
+	}
1018
+
1019
+
1020
+
1021
+	/**
1022
+	 * Gets routes for the config for the specified version
1023
+	 *
1024
+	 * @param string  $version
1025
+	 * @param boolean $hidden_endpoint
1026
+	 * @return array
1027
+	 */
1028
+	protected function _get_config_route_data_for_version($version, $hidden_endpoint)
1029
+	{
1030
+		return array(
1031
+			'config'    => array(
1032
+				array(
1033
+					'callback'        => array(
1034
+						'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1035
+						'handleRequest',
1036
+					),
1037
+					'methods'         => WP_REST_Server::READABLE,
1038
+					'hidden_endpoint' => $hidden_endpoint,
1039
+					'callback_args'   => array($version),
1040
+				),
1041
+			),
1042
+			'site_info' => array(
1043
+				array(
1044
+					'callback'        => array(
1045
+						'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1046
+						'handleRequestSiteInfo',
1047
+					),
1048
+					'methods'         => WP_REST_Server::READABLE,
1049
+					'hidden_endpoint' => $hidden_endpoint,
1050
+					'callback_args'   => array($version),
1051
+				),
1052
+			),
1053
+		);
1054
+	}
1055
+
1056
+
1057
+
1058
+	/**
1059
+	 * Gets the meta info routes
1060
+	 *
1061
+	 * @return array @see _register_model_routes
1062
+	 * @deprecated since version 4.9.1
1063
+	 */
1064
+	protected function _register_meta_routes()
1065
+	{
1066
+		$meta_routes = array();
1067
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
1068
+			$meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version(
1069
+				$version,
1070
+				$hidden_endpoint
1071
+			);
1072
+		}
1073
+		return $meta_routes;
1074
+	}
1075
+
1076
+
1077
+
1078
+	/**
1079
+	 * @param string  $version
1080
+	 * @param boolean $hidden_endpoint
1081
+	 * @return array
1082
+	 */
1083
+	protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false)
1084
+	{
1085
+		return array(
1086
+			'resources' => array(
1087
+				array(
1088
+					'callback'        => array(
1089
+						'EventEspresso\core\libraries\rest_api\controllers\model\Meta',
1090
+						'handleRequestModelsMeta',
1091
+					),
1092
+					'methods'         => WP_REST_Server::READABLE,
1093
+					'hidden_endpoint' => $hidden_endpoint,
1094
+					'callback_args'   => array($version),
1095
+				),
1096
+			),
1097
+		);
1098
+	}
1099
+
1100
+
1101
+
1102
+	/**
1103
+	 * Tries to hide old 4.6 endpoints from the
1104
+	 *
1105
+	 * @param array $route_data
1106
+	 * @return array
1107
+	 * @throws \EE_Error
1108
+	 */
1109
+	public static function hide_old_endpoints($route_data)
1110
+	{
1111
+		//allow API clients to override which endpoints get hidden, in case
1112
+		//they want to discover particular endpoints
1113
+		//also, we don't have access to the request so we have to just grab it from the superglobal
1114
+		$force_show_ee_namespace = ltrim(
1115
+			EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''),
1116
+			'/'
1117
+		);
1118
+		foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) {
1119
+			foreach ($relative_urls as $resource_name => $endpoints) {
1120
+				foreach ($endpoints as $key => $endpoint) {
1121
+					//skip schema and other route options
1122
+					if (! is_numeric($key)) {
1123
+						continue;
1124
+					}
1125
+					//by default, hide "hidden_endpoint"s, unless the request indicates
1126
+					//to $force_show_ee_namespace, in which case only show that one
1127
+					//namespace's endpoints (and hide all others)
1128
+					if (
1129
+						($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1130
+						|| ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1131
+					) {
1132
+						$full_route = '/' . ltrim($namespace, '/');
1133
+						$full_route .= '/' . ltrim($resource_name, '/');
1134
+						unset($route_data[$full_route]);
1135
+					}
1136
+				}
1137
+			}
1138
+		}
1139
+		return $route_data;
1140
+	}
1141
+
1142
+
1143
+
1144
+	/**
1145
+	 * Returns an array describing which versions of core support serving requests for.
1146
+	 * Keys are core versions' major and minor version, and values are the
1147
+	 * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like
1148
+	 * data by just removing a few models and fields from the responses. However, 4.15 might remove
1149
+	 * the answers table entirely, in which case it would be very difficult for
1150
+	 * it to serve 4.6-style responses.
1151
+	 * Versions of core that are missing from this array are unknowns.
1152
+	 * previous ver
1153
+	 *
1154
+	 * @return array
1155
+	 */
1156
+	public static function version_compatibilities()
1157
+	{
1158
+		return apply_filters(
1159
+			'FHEE__EED_Core_REST_API__version_compatibilities',
1160
+			array(
1161
+				'4.8.29' => '4.8.29',
1162
+				'4.8.33' => '4.8.29',
1163
+				'4.8.34' => '4.8.29',
1164
+				'4.8.36' => '4.8.29',
1165
+			)
1166
+		);
1167
+	}
1168
+
1169
+
1170
+
1171
+	/**
1172
+	 * Gets the latest API version served. Eg if there
1173
+	 * are two versions served of the API, 4.8.29 and 4.8.32, and
1174
+	 * we are on core version 4.8.34, it will return the string "4.8.32"
1175
+	 *
1176
+	 * @return string
1177
+	 */
1178
+	public static function latest_rest_api_version()
1179
+	{
1180
+		$versions_served = \EED_Core_Rest_Api::versions_served();
1181
+		$versions_served_keys = array_keys($versions_served);
1182
+		return end($versions_served_keys);
1183
+	}
1184
+
1185
+
1186
+
1187
+	/**
1188
+	 * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of
1189
+	 * EE the API can serve requests for. Eg, if we are on 4.15 of core, and
1190
+	 * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ).
1191
+	 * We also indicate whether or not this version should be put in the index or not
1192
+	 *
1193
+	 * @return array keys are API version numbers (just major and minor numbers), and values
1194
+	 * are whether or not they should be hidden
1195
+	 */
1196
+	public static function versions_served()
1197
+	{
1198
+		$versions_served = array();
1199
+		$possibly_served_versions = EED_Core_Rest_Api::version_compatibilities();
1200
+		$lowest_compatible_version = end($possibly_served_versions);
1201
+		reset($possibly_served_versions);
1202
+		$versions_served_historically = array_keys($possibly_served_versions);
1203
+		$latest_version = end($versions_served_historically);
1204
+		reset($versions_served_historically);
1205
+		//for each version of core we have ever served:
1206
+		foreach ($versions_served_historically as $key_versioned_endpoint) {
1207
+			//if it's not above the current core version, and it's compatible with the current version of core
1208
+			if ($key_versioned_endpoint === $latest_version) {
1209
+				//don't hide the latest version in the index
1210
+				$versions_served[$key_versioned_endpoint] = false;
1211
+			} elseif (
1212
+				$key_versioned_endpoint >= $lowest_compatible_version
1213
+				&& $key_versioned_endpoint < EED_Core_Rest_Api::core_version()
1214
+			) {
1215
+				//include, but hide, previous versions which are still supported
1216
+				$versions_served[$key_versioned_endpoint] = true;
1217
+			} elseif (apply_filters(
1218
+				'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions',
1219
+				false,
1220
+				$possibly_served_versions
1221
+			)) {
1222
+				//if a version is no longer supported, don't include it in index or list of versions served
1223
+				$versions_served[$key_versioned_endpoint] = true;
1224
+			}
1225
+		}
1226
+		return $versions_served;
1227
+	}
1228
+
1229
+
1230
+
1231
+	/**
1232
+	 * Gets the major and minor version of EE core's version string
1233
+	 *
1234
+	 * @return string
1235
+	 */
1236
+	public static function core_version()
1237
+	{
1238
+		return apply_filters(
1239
+			'FHEE__EED_Core_REST_API__core_version',
1240
+			implode(
1241
+				'.',
1242
+				array_slice(
1243
+					explode(
1244
+						'.',
1245
+						espresso_version()
1246
+					),
1247
+				0,
1248
+				3
1249
+				)
1250
+			)
1251
+		);
1252
+	}
1253
+
1254
+
1255
+
1256
+	/**
1257
+	 * Gets the default limit that should be used when querying for resources
1258
+	 *
1259
+	 * @return int
1260
+	 */
1261
+	public static function get_default_query_limit()
1262
+	{
1263
+		//we actually don't use a const because we want folks to always use
1264
+		//this method, not the const directly
1265
+		return apply_filters(
1266
+			'FHEE__EED_Core_Rest_Api__get_default_query_limit',
1267
+			50
1268
+		);
1269
+	}
1270
+
1271
+
1272
+	/**
1273
+	 *
1274
+	 * @param string $version api version string (i.e. '4.8.36')
1275
+	 * @return array
1276
+	 */
1277
+	public static function getCollectionRoutesIndexedByModelName($version = '')
1278
+	{
1279
+		$version = empty($version) ? self::latest_rest_api_version() : $version;
1280
+		$model_names = self::model_names_with_plural_routes($version);
1281
+		$collection_routes = array();
1282
+		foreach ($model_names as $model_name => $model_class_name) {
1283
+			$collection_routes[strtolower($model_name)] = '/' . self::ee_api_namespace . $version . '/'
1284
+														  . EEH_Inflector::pluralize_and_lower($model_name);
1285
+
1286
+		}
1287
+		return $collection_routes;
1288
+	}
1289
+
1290
+
1291
+
1292
+	/**
1293
+	 *    run - initial module setup
1294
+	 *
1295
+	 * @access    public
1296
+	 * @param  WP $WP
1297
+	 * @return    void
1298
+	 */
1299
+	public function run($WP)
1300
+	{
1301
+	}
1302 1302
 }
1303 1303
 
1304 1304
 // End of file EED_Core_Rest_Api.module.php
Please login to merge, or discard this patch.
Spacing   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -131,7 +131,7 @@  discard block
 block discarded – undo
131 131
      */
132 132
     protected static function _set_hooks_for_changes()
133 133
     {
134
-        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
134
+        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES.'rest_api'.DS.'changes'), false);
135 135
         foreach ($folder_contents as $classname_in_namespace => $filepath) {
136 136
             //ignore the base parent class
137 137
             //and legacy named classes
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
             ) {
141 141
                 continue;
142 142
             }
143
-            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
143
+            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\'.$classname_in_namespace;
144 144
             if (class_exists($full_classname)) {
145 145
                 $instance_of_class = new $full_classname;
146 146
                 if ($instance_of_class instanceof ChangesInBase) {
@@ -186,10 +186,10 @@  discard block
 block discarded – undo
186 186
                      * }
187 187
                      */
188 188
                     //skip route options
189
-                    if (! is_numeric($endpoint_key)) {
189
+                    if ( ! is_numeric($endpoint_key)) {
190 190
                         continue;
191 191
                     }
192
-                    if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
192
+                    if ( ! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
193 193
                         throw new EE_Error(
194 194
                             esc_html__(
195 195
                                 // @codingStandardsIgnoreStart
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
                     }
210 210
                     if (isset($data_for_single_endpoint['callback_args'])) {
211 211
                         $callback_args = $data_for_single_endpoint['callback_args'];
212
-                        $single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
212
+                        $single_endpoint_args['callback'] = function(\WP_REST_Request $request) use (
213 213
                             $callback,
214 214
                             $callback_args
215 215
                         ) {
@@ -228,7 +228,7 @@  discard block
 block discarded – undo
228 228
                     $schema_route_data = $data_for_multiple_endpoints['schema'];
229 229
                     $schema_callback = $schema_route_data['schema_callback'];
230 230
                     $callback_args = $schema_route_data['callback_args'];
231
-                    $multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
231
+                    $multiple_endpoint_args['schema'] = function() use ($schema_callback, $callback_args) {
232 232
                         return call_user_func_array(
233 233
                             $schema_callback,
234 234
                             $callback_args
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
     {
273 273
         //delete the saved EE REST API routes
274 274
         foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
275
-            delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
275
+            delete_option(EED_Core_Rest_Api::saved_routes_option_names.$version);
276 276
         }
277 277
     }
278 278
 
@@ -292,7 +292,7 @@  discard block
 block discarded – undo
292 292
     {
293 293
         $ee_routes = array();
294 294
         foreach (self::versions_served() as $version => $hidden_endpoints) {
295
-            $ee_routes[self::ee_api_namespace . $version] = self::_get_ee_route_data_for_version(
295
+            $ee_routes[self::ee_api_namespace.$version] = self::_get_ee_route_data_for_version(
296 296
                 $version,
297 297
                 $hidden_endpoints
298 298
             );
@@ -313,8 +313,8 @@  discard block
 block discarded – undo
313 313
      */
314 314
     protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
315 315
     {
316
-        $ee_routes = get_option(self::saved_routes_option_names . $version, null);
317
-        if (! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) {
316
+        $ee_routes = get_option(self::saved_routes_option_names.$version, null);
317
+        if ( ! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) {
318 318
             $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
319 319
         }
320 320
         return $ee_routes;
@@ -342,7 +342,7 @@  discard block
 block discarded – undo
342 342
                 $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
343 343
             )
344 344
         );
345
-        $option_name = self::saved_routes_option_names . $version;
345
+        $option_name = self::saved_routes_option_names.$version;
346 346
         if (get_option($option_name)) {
347 347
             update_option($option_name, $routes, true);
348 348
         } else {
@@ -408,11 +408,11 @@  discard block
 block discarded – undo
408 408
      */
409 409
     public static function should_have_write_endpoints(EEM_Base $model)
410 410
     {
411
-        if ($model->is_wp_core_model()){
411
+        if ($model->is_wp_core_model()) {
412 412
             return false;
413 413
         }
414
-        foreach($model->get_tables() as $table){
415
-            if( $table->is_global()){
414
+        foreach ($model->get_tables() as $table) {
415
+            if ($table->is_global()) {
416 416
                 return false;
417 417
             }
418 418
         }
@@ -427,7 +427,7 @@  discard block
 block discarded – undo
427 427
      * @param $version
428 428
      * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
429 429
      */
430
-    public static function model_names_with_plural_routes($version){
430
+    public static function model_names_with_plural_routes($version) {
431 431
         $model_version_info = new ModelVersionInfo($version);
432 432
         $models_to_register = $model_version_info->modelsForRequestedVersion();
433 433
         //let's not bother having endpoints for extra metas
@@ -459,7 +459,7 @@  discard block
 block discarded – undo
459 459
         foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
460 460
             $model = \EE_Registry::instance()->load_model($model_name);
461 461
             //if this isn't a valid model then let's skip iterate to the next item in the loop.
462
-            if (! $model instanceof EEM_Base) {
462
+            if ( ! $model instanceof EEM_Base) {
463 463
                 continue;
464 464
             }
465 465
             //yes we could just register one route for ALL models, but then they wouldn't show up in the index
@@ -476,7 +476,7 @@  discard block
 block discarded – undo
476 476
                     'hidden_endpoint' => $hidden_endpoint,
477 477
                     'args'            => $this->_get_read_query_params($model, $version),
478 478
                     '_links'          => array(
479
-                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
479
+                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace.$version.$singular_model_route),
480 480
                     ),
481 481
                 ),
482 482
                 'schema' => array(
@@ -499,11 +499,11 @@  discard block
 block discarded – undo
499 499
                     'args'            => $this->_get_response_selection_query_params($model, $version),
500 500
                 ),
501 501
             );
502
-            if( apply_filters(
502
+            if (apply_filters(
503 503
                 'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
504 504
                 EED_Core_Rest_Api::should_have_write_endpoints($model),
505 505
                 $model
506
-            )){
506
+            )) {
507 507
                 $model_routes[$plural_model_route][] = array(
508 508
                     'callback'        => array(
509 509
                         'EventEspresso\core\libraries\rest_api\controllers\model\Write',
@@ -593,7 +593,7 @@  discard block
 block discarded – undo
593 593
      */
594 594
     public static function get_entity_route($model, $id)
595 595
     {
596
-        return EED_Core_Rest_Api::get_collection_route($model). '/' . $id;
596
+        return EED_Core_Rest_Api::get_collection_route($model).'/'.$id;
597 597
     }
598 598
 
599 599
 
@@ -613,7 +613,7 @@  discard block
 block discarded – undo
613 613
             $relation_obj->get_other_model()->get_this_model_name(),
614 614
             $relation_obj
615 615
         );
616
-        return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
616
+        return EED_Core_Rest_Api::get_entity_route($model, $id).'/'.$related_model_name_endpoint_part;
617 617
     }
618 618
 
619 619
 
@@ -625,8 +625,8 @@  discard block
 block discarded – undo
625 625
      * @param string $version
626 626
      * @return string
627 627
      */
628
-    public static function get_versioned_route_to($relative_route, $version = '4.8.36'){
629
-        return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
628
+    public static function get_versioned_route_to($relative_route, $version = '4.8.36') {
629
+        return '/'.EED_Core_Rest_Api::ee_api_namespace.$version.'/'.$relative_route;
630 630
     }
631 631
 
632 632
 
@@ -641,7 +641,7 @@  discard block
 block discarded – undo
641 641
     {
642 642
         $routes = array();
643 643
         foreach (self::versions_served() as $version => $hidden_endpoint) {
644
-            $routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version(
644
+            $routes[self::ee_api_namespace.$version] = $this->_get_rpc_route_data_for_version(
645 645
                 $version,
646 646
                 $hidden_endpoint
647 647
             );
@@ -805,7 +805,7 @@  discard block
 block discarded – undo
805 805
                     'type'     => array(
806 806
                         'object',
807 807
                         'string',
808
-                    ),//because we accept a variety of types, WP core validation and sanitization
808
+                    ), //because we accept a variety of types, WP core validation and sanitization
809 809
                     //freaks out. We'll just validate this argument while handling the request
810 810
                     'validate_callback' => null,
811 811
                     'sanitize_callback' => null,
@@ -894,7 +894,7 @@  discard block
 block discarded – undo
894 894
                 $model_version_info->requestedVersion()
895 895
             );
896 896
             //we do our own validation and sanitization within the controller
897
-            if(function_exists('rest_validate_value_from_schema')){
897
+            if (function_exists('rest_validate_value_from_schema')) {
898 898
                 $sanitize_callback = array(
899 899
                     'EED_Core_Rest_Api',
900 900
                     'default_sanitize_callback',
@@ -914,7 +914,7 @@  discard block
 block discarded – undo
914 914
                     $field_obj->get_nicename(),
915 915
                     $field_name
916 916
                 );
917
-                $args_info[$field_name . '_gmt'] = $gmt_arg_info;
917
+                $args_info[$field_name.'_gmt'] = $gmt_arg_info;
918 918
             }
919 919
         }
920 920
         return $args_info;
@@ -935,10 +935,10 @@  discard block
 block discarded – undo
935 935
      * @throws InvalidInterfaceException
936 936
      * @throws InvalidDataTypeException
937 937
      */
938
-    public static function default_sanitize_callback( $value, WP_REST_Request $request, $param)
938
+    public static function default_sanitize_callback($value, WP_REST_Request $request, $param)
939 939
     {
940 940
         $attributes = $request->get_attributes();
941
-        if (! isset($attributes['args'][$param])
941
+        if ( ! isset($attributes['args'][$param])
942 942
             || ! is_array($attributes['args'][$param])) {
943 943
             $validation_result = true;
944 944
         } else {
@@ -947,7 +947,7 @@  discard block
 block discarded – undo
947 947
                     $value === ''
948 948
                     || $value === null
949 949
                 )
950
-                && (! isset($args['required'])
950
+                && ( ! isset($args['required'])
951 951
                     || $args['required'] === false
952 952
                 )
953 953
             ) {
@@ -957,7 +957,7 @@  discard block
 block discarded – undo
957 957
                 && $args['format'] === 'email'
958 958
             ) {
959 959
                 $validation_result = true;
960
-                if (! self::_validate_email($value)) {
960
+                if ( ! self::_validate_email($value)) {
961 961
                     $validation_result = new WP_Error(
962 962
                         'rest_invalid_param',
963 963
                         esc_html__(
@@ -987,7 +987,7 @@  discard block
 block discarded – undo
987 987
      * @throws InvalidInterfaceException
988 988
      * @throws InvalidDataTypeException
989 989
      */
990
-    protected static function _validate_email($email){
990
+    protected static function _validate_email($email) {
991 991
         try {
992 992
             EmailAddressFactory::create($email);
993 993
             return true;
@@ -1008,7 +1008,7 @@  discard block
 block discarded – undo
1008 1008
     {
1009 1009
         $config_routes = array();
1010 1010
         foreach (self::versions_served() as $version => $hidden_endpoint) {
1011
-            $config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version(
1011
+            $config_routes[self::ee_api_namespace.$version] = $this->_get_config_route_data_for_version(
1012 1012
                 $version,
1013 1013
                 $hidden_endpoint
1014 1014
             );
@@ -1065,7 +1065,7 @@  discard block
 block discarded – undo
1065 1065
     {
1066 1066
         $meta_routes = array();
1067 1067
         foreach (self::versions_served() as $version => $hidden_endpoint) {
1068
-            $meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version(
1068
+            $meta_routes[self::ee_api_namespace.$version] = $this->_get_meta_route_data_for_version(
1069 1069
                 $version,
1070 1070
                 $hidden_endpoint
1071 1071
             );
@@ -1119,7 +1119,7 @@  discard block
 block discarded – undo
1119 1119
             foreach ($relative_urls as $resource_name => $endpoints) {
1120 1120
                 foreach ($endpoints as $key => $endpoint) {
1121 1121
                     //skip schema and other route options
1122
-                    if (! is_numeric($key)) {
1122
+                    if ( ! is_numeric($key)) {
1123 1123
                         continue;
1124 1124
                     }
1125 1125
                     //by default, hide "hidden_endpoint"s, unless the request indicates
@@ -1129,8 +1129,8 @@  discard block
 block discarded – undo
1129 1129
                         ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1130 1130
                         || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1131 1131
                     ) {
1132
-                        $full_route = '/' . ltrim($namespace, '/');
1133
-                        $full_route .= '/' . ltrim($resource_name, '/');
1132
+                        $full_route = '/'.ltrim($namespace, '/');
1133
+                        $full_route .= '/'.ltrim($resource_name, '/');
1134 1134
                         unset($route_data[$full_route]);
1135 1135
                     }
1136 1136
                 }
@@ -1280,7 +1280,7 @@  discard block
 block discarded – undo
1280 1280
         $model_names = self::model_names_with_plural_routes($version);
1281 1281
         $collection_routes = array();
1282 1282
         foreach ($model_names as $model_name => $model_class_name) {
1283
-            $collection_routes[strtolower($model_name)] = '/' . self::ee_api_namespace . $version . '/'
1283
+            $collection_routes[strtolower($model_name)] = '/'.self::ee_api_namespace.$version.'/'
1284 1284
                                                           . EEH_Inflector::pluralize_and_lower($model_name);
1285 1285
 
1286 1286
         }
Please login to merge, or discard this patch.