Completed
Branch TASK/11422/upgrade-moment-js (49a5b7)
by
unknown
101:09 queued 88:09
created
core/services/request/InvalidRequestStackMiddlewareException.php 2 patches
Indentation   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -19,33 +19,33 @@
 block discarded – undo
19 19
 class InvalidRequestStackMiddlewareException extends InvalidDataTypeException
20 20
 {
21 21
 
22
-    /**
23
-     * @param  mixed     $middleware_app_class
24
-     * @param  string    $message
25
-     * @param int        $code
26
-     * @param Exception $previous
27
-     */
28
-    public function __construct($middleware_app_class, $message = '', $code = 0, Exception $previous = null)
29
-    {
30
-        if(is_array($middleware_app_class)) {
31
-            $middleware_app_class = reset($middleware_app_class);
32
-        }
33
-        if (empty($message)) {
34
-            $message = sprintf(
35
-                esc_html__(
36
-                    'The supplied Request Stack Middleware class "%1$s" is invalid or could no be found.',
37
-                    'event_espresso'
38
-                ),
39
-                $middleware_app_class
40
-            );
41
-        }
42
-        parent::__construct(
43
-            '$middleware_app_class',
44
-            $middleware_app_class,
45
-            'EventEspresso\core\services\request\middleware\Middleware',
46
-            $message,
47
-            $code,
48
-            $previous
49
-        );
50
-    }
22
+	/**
23
+	 * @param  mixed     $middleware_app_class
24
+	 * @param  string    $message
25
+	 * @param int        $code
26
+	 * @param Exception $previous
27
+	 */
28
+	public function __construct($middleware_app_class, $message = '', $code = 0, Exception $previous = null)
29
+	{
30
+		if(is_array($middleware_app_class)) {
31
+			$middleware_app_class = reset($middleware_app_class);
32
+		}
33
+		if (empty($message)) {
34
+			$message = sprintf(
35
+				esc_html__(
36
+					'The supplied Request Stack Middleware class "%1$s" is invalid or could no be found.',
37
+					'event_espresso'
38
+				),
39
+				$middleware_app_class
40
+			);
41
+		}
42
+		parent::__construct(
43
+			'$middleware_app_class',
44
+			$middleware_app_class,
45
+			'EventEspresso\core\services\request\middleware\Middleware',
46
+			$message,
47
+			$code,
48
+			$previous
49
+		);
50
+	}
51 51
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -27,7 +27,7 @@
 block discarded – undo
27 27
      */
28 28
     public function __construct($middleware_app_class, $message = '', $code = 0, Exception $previous = null)
29 29
     {
30
-        if(is_array($middleware_app_class)) {
30
+        if (is_array($middleware_app_class)) {
31 31
             $middleware_app_class = reset($middleware_app_class);
32 32
         }
33 33
         if (empty($message)) {
Please login to merge, or discard this patch.
core/services/request/RequestStackBuilder.php 2 patches
Indentation   +87 added lines, -87 removed lines patch added patch discarded remove patch
@@ -24,97 +24,97 @@
 block discarded – undo
24 24
 class RequestStackBuilder extends SplDoublyLinkedList
25 25
 {
26 26
 
27
-    /**
28
-     * @type LoaderInterface $loader
29
-     */
30
-    private $loader;
27
+	/**
28
+	 * @type LoaderInterface $loader
29
+	 */
30
+	private $loader;
31 31
 
32 32
 
33
-    /**
34
-     * RequestStackBuilder constructor.
35
-     *
36
-     * @param LoaderInterface $loader
37
-     */
38
-    public function __construct(LoaderInterface $loader)
39
-    {
40
-        $this->loader = $loader;
41
-        $this->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP);
42
-    }
33
+	/**
34
+	 * RequestStackBuilder constructor.
35
+	 *
36
+	 * @param LoaderInterface $loader
37
+	 */
38
+	public function __construct(LoaderInterface $loader)
39
+	{
40
+		$this->loader = $loader;
41
+		$this->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP);
42
+	}
43 43
 
44 44
 
45
-    /**
46
-     * builds decorated middleware stack
47
-     * by continuously injecting previous middleware app into the next
48
-     *
49
-     * @param RequestStackCoreAppInterface $application
50
-     * @return RequestStack
51
-     * @throws Exception
52
-     */
53
-    public function resolve(RequestStackCoreAppInterface $application)
54
-    {
55
-        $core_app = $application;
56
-        // NOW... because the RequestStack is following the decorator pattern,
57
-        // the first stack app we add will end up at the center of the stack,
58
-        // and will end up being the last item to actually run, but we don't want that!
59
-        // Basically we're dealing with TWO stacks, and transferring items from one to the other,
60
-        // BUT... we want the final stack to be in the same order as the first.
61
-        // So we need to reverse the iterator mode when transferring items,
62
-        // because if we don't, the second stack will end  up in the incorrect order.
63
-        $this->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO | SplDoublyLinkedList::IT_MODE_KEEP);
64
-        for ($this->rewind(); $this->valid(); $this->next()) {
65
-            try {
66
-                $middleware_app       = $this->validateMiddlewareAppDetails($this->current(), true);
67
-                $middleware_app_class = array_shift($middleware_app);
68
-                $middleware_app_args  = is_array($middleware_app) ? $middleware_app : array();
69
-                $middleware_app_args  = array($application, $this->loader) + $middleware_app_args;
70
-                $application          = $this->loader->getShared($middleware_app_class, $middleware_app_args);
71
-            } catch (InvalidRequestStackMiddlewareException $exception) {
72
-                if(WP_DEBUG) {
73
-                    new ExceptionStackTraceDisplay($exception);
74
-                    continue;
75
-                }
76
-                error_log($exception->getMessage());
77
-            }
78
-        }
79
-        return new RequestStack($application, $core_app);
80
-    }
45
+	/**
46
+	 * builds decorated middleware stack
47
+	 * by continuously injecting previous middleware app into the next
48
+	 *
49
+	 * @param RequestStackCoreAppInterface $application
50
+	 * @return RequestStack
51
+	 * @throws Exception
52
+	 */
53
+	public function resolve(RequestStackCoreAppInterface $application)
54
+	{
55
+		$core_app = $application;
56
+		// NOW... because the RequestStack is following the decorator pattern,
57
+		// the first stack app we add will end up at the center of the stack,
58
+		// and will end up being the last item to actually run, but we don't want that!
59
+		// Basically we're dealing with TWO stacks, and transferring items from one to the other,
60
+		// BUT... we want the final stack to be in the same order as the first.
61
+		// So we need to reverse the iterator mode when transferring items,
62
+		// because if we don't, the second stack will end  up in the incorrect order.
63
+		$this->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO | SplDoublyLinkedList::IT_MODE_KEEP);
64
+		for ($this->rewind(); $this->valid(); $this->next()) {
65
+			try {
66
+				$middleware_app       = $this->validateMiddlewareAppDetails($this->current(), true);
67
+				$middleware_app_class = array_shift($middleware_app);
68
+				$middleware_app_args  = is_array($middleware_app) ? $middleware_app : array();
69
+				$middleware_app_args  = array($application, $this->loader) + $middleware_app_args;
70
+				$application          = $this->loader->getShared($middleware_app_class, $middleware_app_args);
71
+			} catch (InvalidRequestStackMiddlewareException $exception) {
72
+				if(WP_DEBUG) {
73
+					new ExceptionStackTraceDisplay($exception);
74
+					continue;
75
+				}
76
+				error_log($exception->getMessage());
77
+			}
78
+		}
79
+		return new RequestStack($application, $core_app);
80
+	}
81 81
 
82 82
 
83
-    /**
84
-     * Ensures that the app details that have been pushed onto RequestStackBuilder
85
-     * are all ordered correctly so that the middleware can be properly constructed
86
-     *
87
-     * @param array $middleware_app
88
-     * @param bool  $recurse
89
-     * @return array
90
-     * @throws InvalidRequestStackMiddlewareException
91
-     */
92
-    protected function validateMiddlewareAppDetails(array $middleware_app, $recurse = false)
93
-    {
94
-        $middleware_app_class = reset($middleware_app);
95
-        // is array empty ?
96
-        if($middleware_app_class === false) {
97
-            throw new InvalidRequestStackMiddlewareException($middleware_app_class);
98
-        }
99
-        // are the class and arguments in the wrong order ?
100
-        if(is_array($middleware_app_class)) {
101
-            if ($recurse === true) {
102
-                return $this->validateMiddlewareAppDetails(array_reverse($middleware_app));
103
-            }
104
-            throw new InvalidRequestStackMiddlewareException($middleware_app_class);
105
-        }
106
-        // is filter callback working like legacy middleware and sending a numerically indexed array ?
107
-        if(is_int($middleware_app_class)) {
108
-            if ($recurse === true) {
109
-                $middleware_app = array_reverse($middleware_app);
110
-                return $this->validateMiddlewareAppDetails(array(reset($middleware_app), array()));
111
-            }
112
-            throw new InvalidRequestStackMiddlewareException($middleware_app_class);
113
-        }
114
-        // is $middleware_app_class a valid FQCN (or class is already loaded) ?
115
-        if(! class_exists($middleware_app_class)) {
116
-            throw new InvalidRequestStackMiddlewareException($middleware_app_class);
117
-        }
118
-        return $middleware_app;
119
-    }
83
+	/**
84
+	 * Ensures that the app details that have been pushed onto RequestStackBuilder
85
+	 * are all ordered correctly so that the middleware can be properly constructed
86
+	 *
87
+	 * @param array $middleware_app
88
+	 * @param bool  $recurse
89
+	 * @return array
90
+	 * @throws InvalidRequestStackMiddlewareException
91
+	 */
92
+	protected function validateMiddlewareAppDetails(array $middleware_app, $recurse = false)
93
+	{
94
+		$middleware_app_class = reset($middleware_app);
95
+		// is array empty ?
96
+		if($middleware_app_class === false) {
97
+			throw new InvalidRequestStackMiddlewareException($middleware_app_class);
98
+		}
99
+		// are the class and arguments in the wrong order ?
100
+		if(is_array($middleware_app_class)) {
101
+			if ($recurse === true) {
102
+				return $this->validateMiddlewareAppDetails(array_reverse($middleware_app));
103
+			}
104
+			throw new InvalidRequestStackMiddlewareException($middleware_app_class);
105
+		}
106
+		// is filter callback working like legacy middleware and sending a numerically indexed array ?
107
+		if(is_int($middleware_app_class)) {
108
+			if ($recurse === true) {
109
+				$middleware_app = array_reverse($middleware_app);
110
+				return $this->validateMiddlewareAppDetails(array(reset($middleware_app), array()));
111
+			}
112
+			throw new InvalidRequestStackMiddlewareException($middleware_app_class);
113
+		}
114
+		// is $middleware_app_class a valid FQCN (or class is already loaded) ?
115
+		if(! class_exists($middleware_app_class)) {
116
+			throw new InvalidRequestStackMiddlewareException($middleware_app_class);
117
+		}
118
+		return $middleware_app;
119
+	}
120 120
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
                 $middleware_app_args  = array($application, $this->loader) + $middleware_app_args;
70 70
                 $application          = $this->loader->getShared($middleware_app_class, $middleware_app_args);
71 71
             } catch (InvalidRequestStackMiddlewareException $exception) {
72
-                if(WP_DEBUG) {
72
+                if (WP_DEBUG) {
73 73
                     new ExceptionStackTraceDisplay($exception);
74 74
                     continue;
75 75
                 }
@@ -93,18 +93,18 @@  discard block
 block discarded – undo
93 93
     {
94 94
         $middleware_app_class = reset($middleware_app);
95 95
         // is array empty ?
96
-        if($middleware_app_class === false) {
96
+        if ($middleware_app_class === false) {
97 97
             throw new InvalidRequestStackMiddlewareException($middleware_app_class);
98 98
         }
99 99
         // are the class and arguments in the wrong order ?
100
-        if(is_array($middleware_app_class)) {
100
+        if (is_array($middleware_app_class)) {
101 101
             if ($recurse === true) {
102 102
                 return $this->validateMiddlewareAppDetails(array_reverse($middleware_app));
103 103
             }
104 104
             throw new InvalidRequestStackMiddlewareException($middleware_app_class);
105 105
         }
106 106
         // is filter callback working like legacy middleware and sending a numerically indexed array ?
107
-        if(is_int($middleware_app_class)) {
107
+        if (is_int($middleware_app_class)) {
108 108
             if ($recurse === true) {
109 109
                 $middleware_app = array_reverse($middleware_app);
110 110
                 return $this->validateMiddlewareAppDetails(array(reset($middleware_app), array()));
@@ -112,7 +112,7 @@  discard block
 block discarded – undo
112 112
             throw new InvalidRequestStackMiddlewareException($middleware_app_class);
113 113
         }
114 114
         // is $middleware_app_class a valid FQCN (or class is already loaded) ?
115
-        if(! class_exists($middleware_app_class)) {
115
+        if ( ! class_exists($middleware_app_class)) {
116 116
             throw new InvalidRequestStackMiddlewareException($middleware_app_class);
117 117
         }
118 118
         return $middleware_app;
Please login to merge, or discard this patch.
core/domain/DomainInterface.php 1 patch
Indentation   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -16,49 +16,49 @@
 block discarded – undo
16 16
 interface DomainInterface extends InterminableInterface
17 17
 {
18 18
 
19
-    /**
20
-     * @return string
21
-     * @throws DomainException
22
-     */
23
-    public function pluginFile();
19
+	/**
20
+	 * @return string
21
+	 * @throws DomainException
22
+	 */
23
+	public function pluginFile();
24 24
 
25 25
 
26
-    /**
27
-     * @return string
28
-     * @throws DomainException
29
-     */
30
-    public function pluginBasename();
26
+	/**
27
+	 * @return string
28
+	 * @throws DomainException
29
+	 */
30
+	public function pluginBasename();
31 31
 
32 32
 
33
-    /**
34
-     * @return string
35
-     */
36
-    public function pluginPath();
33
+	/**
34
+	 * @return string
35
+	 */
36
+	public function pluginPath();
37 37
 
38 38
 
39
-    /**
40
-     * @return string
41
-     * @throws DomainException
42
-     */
43
-    public function pluginUrl();
39
+	/**
40
+	 * @return string
41
+	 * @throws DomainException
42
+	 */
43
+	public function pluginUrl();
44 44
 
45 45
 
46
-    /**
47
-     * @return string
48
-     * @throws DomainException
49
-     */
50
-    public function version();
46
+	/**
47
+	 * @return string
48
+	 * @throws DomainException
49
+	 */
50
+	public function version();
51 51
 
52 52
 
53
-    /**
54
-     * @return string
55
-     */
56
-    public function distributionAssetsPath();
53
+	/**
54
+	 * @return string
55
+	 */
56
+	public function distributionAssetsPath();
57 57
 
58 58
 
59
-    /**
60
-     * @return string
61
-     */
62
-    public function distributionAssetsUrl();
59
+	/**
60
+	 * @return string
61
+	 */
62
+	public function distributionAssetsUrl();
63 63
 
64 64
 }
Please login to merge, or discard this patch.
core/libraries/form_sections/base/EE_Form_Section_Proper.form.php 1 patch
Indentation   +1501 added lines, -1501 removed lines patch added patch discarded remove patch
@@ -14,1506 +14,1506 @@
 block discarded – undo
14 14
 class EE_Form_Section_Proper extends EE_Form_Section_Validatable
15 15
 {
16 16
 
17
-    const SUBMITTED_FORM_DATA_SSN_KEY = 'submitted_form_data';
18
-
19
-    /**
20
-     * Subsections
21
-     *
22
-     * @var EE_Form_Section_Validatable[]
23
-     */
24
-    protected $_subsections = array();
25
-
26
-    /**
27
-     * Strategy for laying out the form
28
-     *
29
-     * @var EE_Form_Section_Layout_Base
30
-     */
31
-    protected $_layout_strategy;
32
-
33
-    /**
34
-     * Whether or not this form has received and validated a form submission yet
35
-     *
36
-     * @var boolean
37
-     */
38
-    protected $_received_submission = false;
39
-
40
-    /**
41
-     * message displayed to users upon successful form submission
42
-     *
43
-     * @var string
44
-     */
45
-    protected $_form_submission_success_message = '';
46
-
47
-    /**
48
-     * message displayed to users upon unsuccessful form submission
49
-     *
50
-     * @var string
51
-     */
52
-    protected $_form_submission_error_message = '';
53
-
54
-    /**
55
-     * @var array like $_REQUEST
56
-     */
57
-    protected $cached_request_data;
58
-
59
-    /**
60
-     * Stores whether this form (and its sub-sections) were found to be valid or not.
61
-     * Starts off as null, but once the form is validated, it set to either true or false
62
-     * @var boolean|null
63
-     */
64
-    protected $is_valid;
65
-
66
-    /**
67
-     * Stores all the data that will localized for form validation
68
-     *
69
-     * @var array
70
-     */
71
-    static protected $_js_localization = array();
72
-
73
-    /**
74
-     * whether or not the form's localized validation JS vars have been set
75
-     *
76
-     * @type boolean
77
-     */
78
-    static protected $_scripts_localized = false;
79
-
80
-
81
-    /**
82
-     * when constructing a proper form section, calls _construct_finalize on children
83
-     * so that they know who their parent is, and what name they've been given.
84
-     *
85
-     * @param array[] $options_array   {
86
-     * @type          $subsections     EE_Form_Section_Validatable[] where keys are the section's name
87
-     * @type          $include         string[] numerically-indexed where values are section names to be included,
88
-     *                                 and in that order. This is handy if you want
89
-     *                                 the subsections to be ordered differently than the default, and if you override
90
-     *                                 which fields are shown
91
-     * @type          $exclude         string[] values are subsections to be excluded. This is handy if you want
92
-     *                                 to remove certain default subsections (note: if you specify BOTH 'include' AND
93
-     *                                 'exclude', the inclusions will be applied first, and the exclusions will exclude
94
-     *                                 items from that list of inclusions)
95
-     * @type          $layout_strategy EE_Form_Section_Layout_Base strategy for laying out the form
96
-     *                                 } @see EE_Form_Section_Validatable::__construct()
97
-     * @throws EE_Error
98
-     */
99
-    public function __construct($options_array = array())
100
-    {
101
-        $options_array = (array) apply_filters(
102
-            'FHEE__EE_Form_Section_Proper___construct__options_array',
103
-            $options_array,
104
-            $this
105
-        );
106
-        //call parent first, as it may be setting the name
107
-        parent::__construct($options_array);
108
-        //if they've included subsections in the constructor, add them now
109
-        if (isset($options_array['include'])) {
110
-            //we are going to make sure we ONLY have those subsections to include
111
-            //AND we are going to make sure they're in that specified order
112
-            $reordered_subsections = array();
113
-            foreach ($options_array['include'] as $input_name) {
114
-                if (isset($this->_subsections[ $input_name ])) {
115
-                    $reordered_subsections[ $input_name ] = $this->_subsections[ $input_name ];
116
-                }
117
-            }
118
-            $this->_subsections = $reordered_subsections;
119
-        }
120
-        if (isset($options_array['exclude'])) {
121
-            $exclude            = $options_array['exclude'];
122
-            $this->_subsections = array_diff_key($this->_subsections, array_flip($exclude));
123
-        }
124
-        if (isset($options_array['layout_strategy'])) {
125
-            $this->_layout_strategy = $options_array['layout_strategy'];
126
-        }
127
-        if (! $this->_layout_strategy) {
128
-            $this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout();
129
-        }
130
-        $this->_layout_strategy->_construct_finalize($this);
131
-        //ok so we are definitely going to want the forms JS,
132
-        //so enqueue it or remember to enqueue it during wp_enqueue_scripts
133
-        if (did_action('wp_enqueue_scripts') || did_action('admin_enqueue_scripts')) {
134
-            //ok so they've constructed this object after when they should have.
135
-            //just enqueue the generic form scripts and initialize the form immediately in the JS
136
-            EE_Form_Section_Proper::wp_enqueue_scripts(true);
137
-        } else {
138
-            add_action('wp_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
139
-            add_action('admin_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
140
-        }
141
-        add_action('wp_footer', array($this, 'ensure_scripts_localized'), 1);
142
-        /**
143
-         * Gives other plugins a chance to hook in before construct finalize is called.
144
-         * The form probably doesn't yet have a parent form section.
145
-         * Since 4.9.32, when this action was introduced, this is the best place to add a subsection onto a form,
146
-         * assuming you don't care what the form section's name, HTML ID, or HTML name etc are.
147
-         * Also see AHEE__EE_Form_Section_Proper___construct_finalize__end
148
-         *
149
-         * @since 4.9.32
150
-         * @param EE_Form_Section_Proper $this          before __construct is done, but all of its logic,
151
-         *                                              except maybe calling _construct_finalize has been done
152
-         * @param array                  $options_array options passed into the constructor
153
-         */
154
-        do_action(
155
-            'AHEE__EE_Form_Input_Base___construct__before_construct_finalize_called',
156
-            $this,
157
-            $options_array
158
-        );
159
-        if (isset($options_array['name'])) {
160
-            $this->_construct_finalize(null, $options_array['name']);
161
-        }
162
-    }
163
-
164
-
165
-    /**
166
-     * Finishes construction given the parent form section and this form section's name
167
-     *
168
-     * @param EE_Form_Section_Proper $parent_form_section
169
-     * @param string                 $name
170
-     * @throws EE_Error
171
-     */
172
-    public function _construct_finalize($parent_form_section, $name)
173
-    {
174
-        parent::_construct_finalize($parent_form_section, $name);
175
-        $this->_set_default_name_if_empty();
176
-        $this->_set_default_html_id_if_empty();
177
-        foreach ($this->_subsections as $subsection_name => $subsection) {
178
-            if ($subsection instanceof EE_Form_Section_Base) {
179
-                $subsection->_construct_finalize($this, $subsection_name);
180
-            } else {
181
-                throw new EE_Error(
182
-                    sprintf(
183
-                        esc_html__(
184
-                            'Subsection "%s" is not an instanceof EE_Form_Section_Base on form "%s". It is a "%s"',
185
-                            'event_espresso'
186
-                        ),
187
-                        $subsection_name,
188
-                        get_class($this),
189
-                        $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso')
190
-                    )
191
-                );
192
-            }
193
-        }
194
-        /**
195
-         * Action performed just after form has been given a name (and HTML ID etc) and is fully constructed.
196
-         * If you have code that should modify the form and needs it and its subsections to have a name, HTML ID
197
-         * (or other attributes derived from the name like the HTML label id, etc), this is where it should be done.
198
-         * This might only happen just before displaying the form, or just before it receives form submission data.
199
-         * If you need to modify the form or its subsections before _construct_finalize is called on it (and we've
200
-         * ensured it has a name, HTML IDs, etc
201
-         *
202
-         * @param EE_Form_Section_Proper      $this
203
-         * @param EE_Form_Section_Proper|null $parent_form_section
204
-         * @param string                      $name
205
-         */
206
-        do_action(
207
-            'AHEE__EE_Form_Section_Proper___construct_finalize__end',
208
-            $this,
209
-            $parent_form_section,
210
-            $name
211
-        );
212
-    }
213
-
214
-
215
-    /**
216
-     * Gets the layout strategy for this form section
217
-     *
218
-     * @return EE_Form_Section_Layout_Base
219
-     */
220
-    public function get_layout_strategy()
221
-    {
222
-        return $this->_layout_strategy;
223
-    }
224
-
225
-
226
-    /**
227
-     * Gets the HTML for a single input for this form section according
228
-     * to the layout strategy
229
-     *
230
-     * @param EE_Form_Input_Base $input
231
-     * @return string
232
-     */
233
-    public function get_html_for_input($input)
234
-    {
235
-        return $this->_layout_strategy->layout_input($input);
236
-    }
237
-
238
-
239
-    /**
240
-     * was_submitted - checks if form inputs are present in request data
241
-     * Basically an alias for form_data_present_in() (which is used by both
242
-     * proper form sections and form inputs)
243
-     *
244
-     * @param null $form_data
245
-     * @return boolean
246
-     * @throws EE_Error
247
-     */
248
-    public function was_submitted($form_data = null)
249
-    {
250
-        return $this->form_data_present_in($form_data);
251
-    }
252
-
253
-    /**
254
-     * Gets the cached request data; but if there is none, or $req_data was set with
255
-     * something different, refresh the cache, and then return it
256
-     * @param null $req_data
257
-     * @return array
258
-     */
259
-    protected function getCachedRequest($req_data = null)
260
-    {
261
-        if ($this->cached_request_data === null
262
-            || (
263
-                $req_data !== null &&
264
-                $req_data !== $this->cached_request_data
265
-            )
266
-        ) {
267
-            $req_data = apply_filters(
268
-                'FHEE__EE_Form_Section_Proper__receive_form_submission__req_data',
269
-                $req_data,
270
-                $this
271
-            );
272
-            if ($req_data === null) {
273
-                $req_data = array_merge($_GET, $_POST);
274
-            }
275
-            $req_data = apply_filters(
276
-                'FHEE__EE_Form_Section_Proper__receive_form_submission__request_data',
277
-                $req_data,
278
-                $this
279
-            );
280
-            $this->cached_request_data = (array)$req_data;
281
-        }
282
-        return $this->cached_request_data;
283
-    }
284
-
285
-
286
-    /**
287
-     * After the form section is initially created, call this to sanitize the data in the submission
288
-     * which relates to this form section, validate it, and set it as properties on the form.
289
-     *
290
-     * @param array|null $req_data should usually be $_POST (the default).
291
-     *                             However, you CAN supply a different array.
292
-     *                             Consider using set_defaults() instead however.
293
-     *                             (If you rendered the form in the page using echo $form_x->get_html()
294
-     *                             the inputs will have the correct name in the request data for this function
295
-     *                             to find them and populate the form with them.
296
-     *                             If you have a flat form (with only input subsections),
297
-     *                             you can supply a flat array where keys
298
-     *                             are the form input names and values are their values)
299
-     * @param boolean    $validate whether or not to perform validation on this data. Default is,
300
-     *                             of course, to validate that data, and set errors on the invalid values.
301
-     *                             But if the data has already been validated
302
-     *                             (eg you validated the data then stored it in the DB)
303
-     *                             you may want to skip this step.
304
-     * @throws InvalidArgumentException
305
-     * @throws InvalidInterfaceException
306
-     * @throws InvalidDataTypeException
307
-     * @throws EE_Error
308
-     */
309
-    public function receive_form_submission($req_data = null, $validate = true)
310
-    {
311
-        $req_data = $this->getCachedRequest($req_data);
312
-        $this->_normalize($req_data);
313
-        if ($validate) {
314
-            $this->_validate();
315
-            //if it's invalid, we're going to want to re-display so remember what they submitted
316
-            if (! $this->is_valid()) {
317
-                $this->store_submitted_form_data_in_session();
318
-            }
319
-        }
320
-        if ($this->submission_error_message() === '' && ! $this->is_valid()) {
321
-            $this->set_submission_error_message();
322
-        }
323
-        do_action(
324
-            'AHEE__EE_Form_Section_Proper__receive_form_submission__end',
325
-            $req_data,
326
-            $this,
327
-            $validate
328
-        );
329
-    }
330
-
331
-
332
-    /**
333
-     * caches the originally submitted input values in the session
334
-     * so that they can be used to repopulate the form if it failed validation
335
-     *
336
-     * @return boolean whether or not the data was successfully stored in the session
337
-     * @throws InvalidArgumentException
338
-     * @throws InvalidInterfaceException
339
-     * @throws InvalidDataTypeException
340
-     * @throws EE_Error
341
-     */
342
-    protected function store_submitted_form_data_in_session()
343
-    {
344
-        return EE_Registry::instance()->SSN->set_session_data(
345
-            array(
346
-                EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY => $this->submitted_values(true),
347
-            )
348
-        );
349
-    }
350
-
351
-
352
-    /**
353
-     * retrieves the originally submitted input values in the session
354
-     * so that they can be used to repopulate the form if it failed validation
355
-     *
356
-     * @return array
357
-     * @throws InvalidArgumentException
358
-     * @throws InvalidInterfaceException
359
-     * @throws InvalidDataTypeException
360
-     */
361
-    protected function get_submitted_form_data_from_session()
362
-    {
363
-        $session = EE_Registry::instance()->SSN;
364
-        if ($session instanceof EE_Session) {
365
-            return $session->get_session_data(
366
-                EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY
367
-            );
368
-        }
369
-        return array();
370
-    }
371
-
372
-
373
-    /**
374
-     * flushed the originally submitted input values from the session
375
-     *
376
-     * @return boolean whether or not the data was successfully removed from the session
377
-     * @throws InvalidArgumentException
378
-     * @throws InvalidInterfaceException
379
-     * @throws InvalidDataTypeException
380
-     */
381
-    protected function flush_submitted_form_data_from_session()
382
-    {
383
-        return EE_Registry::instance()->SSN->reset_data(
384
-            array(EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY)
385
-        );
386
-    }
387
-
388
-
389
-    /**
390
-     * Populates this form and its subsections with data from the session.
391
-     * (Wrapper for EE_Form_Section_Proper::receive_form_submission, so it shows
392
-     * validation errors when displaying too)
393
-     * Returns true if the form was populated from the session, false otherwise
394
-     *
395
-     * @return boolean
396
-     * @throws InvalidArgumentException
397
-     * @throws InvalidInterfaceException
398
-     * @throws InvalidDataTypeException
399
-     * @throws EE_Error
400
-     */
401
-    public function populate_from_session()
402
-    {
403
-        $form_data_in_session = $this->get_submitted_form_data_from_session();
404
-        if (empty($form_data_in_session)) {
405
-            return false;
406
-        }
407
-        $this->receive_form_submission($form_data_in_session);
408
-        $this->flush_submitted_form_data_from_session();
409
-        if ($this->form_data_present_in($form_data_in_session)) {
410
-            return true;
411
-        }
412
-        return false;
413
-    }
414
-
415
-
416
-    /**
417
-     * Populates the default data for the form, given an array where keys are
418
-     * the input names, and values are their values (preferably normalized to be their
419
-     * proper PHP types, not all strings... although that should be ok too).
420
-     * Proper subsections are sub-arrays, the key being the subsection's name, and
421
-     * the value being an array formatted in teh same way
422
-     *
423
-     * @param array $default_data
424
-     * @throws EE_Error
425
-     */
426
-    public function populate_defaults($default_data)
427
-    {
428
-        foreach ($this->subsections(false) as $subsection_name => $subsection) {
429
-            if (isset($default_data[ $subsection_name ])) {
430
-                if ($subsection instanceof EE_Form_Input_Base) {
431
-                    $subsection->set_default($default_data[ $subsection_name ]);
432
-                } elseif ($subsection instanceof EE_Form_Section_Proper) {
433
-                    $subsection->populate_defaults($default_data[ $subsection_name ]);
434
-                }
435
-            }
436
-        }
437
-    }
438
-
439
-
440
-    /**
441
-     * returns true if subsection exists
442
-     *
443
-     * @param string $name
444
-     * @return boolean
445
-     */
446
-    public function subsection_exists($name)
447
-    {
448
-        return isset($this->_subsections[ $name ]) ? true : false;
449
-    }
450
-
451
-
452
-    /**
453
-     * Gets the subsection specified by its name
454
-     *
455
-     * @param string  $name
456
-     * @param boolean $require_construction_to_be_finalized most client code should leave this as TRUE
457
-     *                                                      so that the inputs will be properly configured.
458
-     *                                                      However, some client code may be ok
459
-     *                                                      with construction finalize being called later
460
-     *                                                      (realizing that the subsections' html names
461
-     *                                                      might not be set yet, etc.)
462
-     * @return EE_Form_Section_Base
463
-     * @throws EE_Error
464
-     */
465
-    public function get_subsection($name, $require_construction_to_be_finalized = true)
466
-    {
467
-        if ($require_construction_to_be_finalized) {
468
-            $this->ensure_construct_finalized_called();
469
-        }
470
-        return $this->subsection_exists($name) ? $this->_subsections[ $name ] : null;
471
-    }
472
-
473
-
474
-    /**
475
-     * Gets all the validatable subsections of this form section
476
-     *
477
-     * @return EE_Form_Section_Validatable[]
478
-     * @throws EE_Error
479
-     */
480
-    public function get_validatable_subsections()
481
-    {
482
-        $validatable_subsections = array();
483
-        foreach ($this->subsections() as $name => $obj) {
484
-            if ($obj instanceof EE_Form_Section_Validatable) {
485
-                $validatable_subsections[ $name ] = $obj;
486
-            }
487
-        }
488
-        return $validatable_subsections;
489
-    }
490
-
491
-
492
-    /**
493
-     * Gets an input by the given name. If not found, or if its not an EE_FOrm_Input_Base child,
494
-     * throw an EE_Error.
495
-     *
496
-     * @param string  $name
497
-     * @param boolean $require_construction_to_be_finalized most client code should
498
-     *                                                      leave this as TRUE so that the inputs will be properly
499
-     *                                                      configured. However, some client code may be ok with
500
-     *                                                      construction finalize being called later
501
-     *                                                      (realizing that the subsections' html names might not be
502
-     *                                                      set yet, etc.)
503
-     * @return EE_Form_Input_Base
504
-     * @throws EE_Error
505
-     */
506
-    public function get_input($name, $require_construction_to_be_finalized = true)
507
-    {
508
-        $subsection = $this->get_subsection(
509
-            $name,
510
-            $require_construction_to_be_finalized
511
-        );
512
-        if (! $subsection instanceof EE_Form_Input_Base) {
513
-            throw new EE_Error(
514
-                sprintf(
515
-                    esc_html__(
516
-                        "Subsection '%s' is not an instanceof EE_Form_Input_Base on form '%s'. It is a '%s'",
517
-                        'event_espresso'
518
-                    ),
519
-                    $name,
520
-                    get_class($this),
521
-                    $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso')
522
-                )
523
-            );
524
-        }
525
-        return $subsection;
526
-    }
527
-
528
-
529
-    /**
530
-     * Like get_input(), gets the proper subsection of the form given the name,
531
-     * otherwise throws an EE_Error
532
-     *
533
-     * @param string  $name
534
-     * @param boolean $require_construction_to_be_finalized most client code should
535
-     *                                                      leave this as TRUE so that the inputs will be properly
536
-     *                                                      configured. However, some client code may be ok with
537
-     *                                                      construction finalize being called later
538
-     *                                                      (realizing that the subsections' html names might not be
539
-     *                                                      set yet, etc.)
540
-     * @return EE_Form_Section_Proper
541
-     * @throws EE_Error
542
-     */
543
-    public function get_proper_subsection($name, $require_construction_to_be_finalized = true)
544
-    {
545
-        $subsection = $this->get_subsection(
546
-            $name,
547
-            $require_construction_to_be_finalized
548
-        );
549
-        if (! $subsection instanceof EE_Form_Section_Proper) {
550
-            throw new EE_Error(
551
-                sprintf(
552
-                    esc_html__(
553
-                        "Subsection '%'s is not an instanceof EE_Form_Section_Proper on form '%s'",
554
-                        'event_espresso'
555
-                    ),
556
-                    $name,
557
-                    get_class($this)
558
-                )
559
-            );
560
-        }
561
-        return $subsection;
562
-    }
563
-
564
-
565
-    /**
566
-     * Gets the value of the specified input. Should be called after receive_form_submission()
567
-     * or populate_defaults() on the form, where the normalized value on the input is set.
568
-     *
569
-     * @param string $name
570
-     * @return mixed depending on the input's type and its normalization strategy
571
-     * @throws EE_Error
572
-     */
573
-    public function get_input_value($name)
574
-    {
575
-        $input = $this->get_input($name);
576
-        return $input->normalized_value();
577
-    }
578
-
579
-
580
-    /**
581
-     * Checks if this form section itself is valid, and then checks its subsections
582
-     *
583
-     * @throws EE_Error
584
-     * @return boolean
585
-     */
586
-    public function is_valid()
587
-    {
588
-        if($this->is_valid === null) {
589
-            if (! $this->has_received_submission()) {
590
-                throw new EE_Error(
591
-                    sprintf(
592
-                        esc_html__(
593
-                            'You cannot check if a form is valid before receiving the form submission using receive_form_submission',
594
-                            'event_espresso'
595
-                        )
596
-                    )
597
-                );
598
-            }
599
-            if (! parent::is_valid()) {
600
-                $this->is_valid = false;
601
-            } else {
602
-                // ok so no general errors to this entire form section.
603
-                // so let's check the subsections, but only set errors if that hasn't been done yet
604
-                $this->is_valid = true;
605
-                foreach ($this->get_validatable_subsections() as $subsection) {
606
-                    if (! $subsection->is_valid()) {
607
-                        $this->is_valid = false;
608
-                    }
609
-                }
610
-            }
611
-        }
612
-        return $this->is_valid;
613
-    }
614
-
615
-
616
-    /**
617
-     * gets the default name of this form section if none is specified
618
-     *
619
-     * @return void
620
-     */
621
-    protected function _set_default_name_if_empty()
622
-    {
623
-        if (! $this->_name) {
624
-            $classname    = get_class($this);
625
-            $default_name = str_replace('EE_', '', $classname);
626
-            $this->_name  = $default_name;
627
-        }
628
-    }
629
-
630
-
631
-    /**
632
-     * Returns the HTML for the form, except for the form opening and closing tags
633
-     * (as the form section doesn't know where you necessarily want to send the information to),
634
-     * and except for a submit button. Enqueues JS and CSS; if called early enough we will
635
-     * try to enqueue them in the header, otherwise they'll be enqueued in the footer.
636
-     * Not doing_it_wrong because theoretically this CAN be used properly,
637
-     * provided its used during "wp_enqueue_scripts", or it doesn't need to enqueue
638
-     * any CSS.
639
-     *
640
-     * @throws InvalidArgumentException
641
-     * @throws InvalidInterfaceException
642
-     * @throws InvalidDataTypeException
643
-     * @throws EE_Error
644
-     */
645
-    public function get_html_and_js()
646
-    {
647
-        $this->enqueue_js();
648
-        return $this->get_html();
649
-    }
650
-
651
-
652
-    /**
653
-     * returns HTML for displaying this form section. recursively calls display_section() on all subsections
654
-     *
655
-     * @param bool $display_previously_submitted_data
656
-     * @return string
657
-     * @throws InvalidArgumentException
658
-     * @throws InvalidInterfaceException
659
-     * @throws InvalidDataTypeException
660
-     * @throws EE_Error
661
-     * @throws EE_Error
662
-     * @throws EE_Error
663
-     */
664
-    public function get_html($display_previously_submitted_data = true)
665
-    {
666
-        $this->ensure_construct_finalized_called();
667
-        if ($display_previously_submitted_data) {
668
-            $this->populate_from_session();
669
-        }
670
-        return $this->_form_html_filter
671
-            ? $this->_form_html_filter->filterHtml($this->_layout_strategy->layout_form(), $this)
672
-            : $this->_layout_strategy->layout_form();
673
-    }
674
-
675
-
676
-    /**
677
-     * enqueues JS and CSS for the form.
678
-     * It is preferred to call this before wp_enqueue_scripts so the
679
-     * scripts and styles can be put in the header, but if called later
680
-     * they will be put in the footer (which is OK for JS, but in HTML4 CSS should
681
-     * only be in the header; but in HTML5 its ok in the body.
682
-     * See http://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag.
683
-     * So if your form enqueues CSS, it's preferred to call this before wp_enqueue_scripts.)
684
-     *
685
-     * @return void
686
-     * @throws EE_Error
687
-     */
688
-    public function enqueue_js()
689
-    {
690
-        $this->_enqueue_and_localize_form_js();
691
-        foreach ($this->subsections() as $subsection) {
692
-            $subsection->enqueue_js();
693
-        }
694
-    }
695
-
696
-
697
-    /**
698
-     * adds a filter so that jquery validate gets enqueued in EE_System::wp_enqueue_scripts().
699
-     * This must be done BEFORE wp_enqueue_scripts() gets called, which is on
700
-     * the wp_enqueue_scripts hook.
701
-     * However, registering the form js and localizing it can happen when we
702
-     * actually output the form (which is preferred, seeing how teh form's fields
703
-     * could change until it's actually outputted)
704
-     *
705
-     * @param boolean $init_form_validation_automatically whether or not we want the form validation
706
-     *                                                    to be triggered automatically or not
707
-     * @return void
708
-     */
709
-    public static function wp_enqueue_scripts($init_form_validation_automatically = true)
710
-    {
711
-        wp_register_script(
712
-            'ee_form_section_validation',
713
-            EE_GLOBAL_ASSETS_URL . 'scripts' . DS . 'form_section_validation.js',
714
-            array('jquery-validate', 'jquery-ui-datepicker', 'jquery-validate-extra-methods'),
715
-            EVENT_ESPRESSO_VERSION,
716
-            true
717
-        );
718
-        wp_localize_script(
719
-            'ee_form_section_validation',
720
-            'ee_form_section_validation_init',
721
-            array('init' => $init_form_validation_automatically ? '1' : '0')
722
-        );
723
-    }
724
-
725
-
726
-    /**
727
-     * gets the variables used by form_section_validation.js.
728
-     * This needs to be called AFTER we've called $this->_enqueue_jquery_validate_script,
729
-     * but before the wordpress hook wp_loaded
730
-     *
731
-     * @throws EE_Error
732
-     */
733
-    public function _enqueue_and_localize_form_js()
734
-    {
735
-        $this->ensure_construct_finalized_called();
736
-        //actually, we don't want to localize just yet. There may be other forms on the page.
737
-        //so we need to add our form section data to a static variable accessible by all form sections
738
-        //and localize it just before the footer
739
-        $this->localize_validation_rules();
740
-        add_action('wp_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'), 2);
741
-        add_action('admin_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'));
742
-    }
743
-
744
-
745
-    /**
746
-     * add our form section data to a static variable accessible by all form sections
747
-     *
748
-     * @param bool $return_for_subsection
749
-     * @return void
750
-     * @throws EE_Error
751
-     */
752
-    public function localize_validation_rules($return_for_subsection = false)
753
-    {
754
-        // we only want to localize vars ONCE for the entire form,
755
-        // so if the form section doesn't have a parent, then it must be the top dog
756
-        if ($return_for_subsection || ! $this->parent_section()) {
757
-            EE_Form_Section_Proper::$_js_localization['form_data'][ $this->html_id() ] = array(
758
-                'form_section_id'  => $this->html_id(true),
759
-                'validation_rules' => $this->get_jquery_validation_rules(),
760
-                'other_data'       => $this->get_other_js_data(),
761
-                'errors'           => $this->subsection_validation_errors_by_html_name(),
762
-            );
763
-            EE_Form_Section_Proper::$_scripts_localized                                = true;
764
-        }
765
-    }
766
-
767
-
768
-    /**
769
-     * Gets an array of extra data that will be useful for client-side javascript.
770
-     * This is primarily data added by inputs and forms in addition to any
771
-     * scripts they might enqueue
772
-     *
773
-     * @param array $form_other_js_data
774
-     * @return array
775
-     * @throws EE_Error
776
-     */
777
-    public function get_other_js_data($form_other_js_data = array())
778
-    {
779
-        foreach ($this->subsections() as $subsection) {
780
-            $form_other_js_data = $subsection->get_other_js_data($form_other_js_data);
781
-        }
782
-        return $form_other_js_data;
783
-    }
784
-
785
-
786
-    /**
787
-     * Gets a flat array of inputs for this form section and its subsections.
788
-     * Keys are their form names, and values are the inputs themselves
789
-     *
790
-     * @return EE_Form_Input_Base
791
-     * @throws EE_Error
792
-     */
793
-    public function inputs_in_subsections()
794
-    {
795
-        $inputs = array();
796
-        foreach ($this->subsections() as $subsection) {
797
-            if ($subsection instanceof EE_Form_Input_Base) {
798
-                $inputs[ $subsection->html_name() ] = $subsection;
799
-            } elseif ($subsection instanceof EE_Form_Section_Proper) {
800
-                $inputs += $subsection->inputs_in_subsections();
801
-            }
802
-        }
803
-        return $inputs;
804
-    }
805
-
806
-
807
-    /**
808
-     * Gets a flat array of all the validation errors.
809
-     * Keys are html names (because those should be unique)
810
-     * and values are a string of all their validation errors
811
-     *
812
-     * @return string[]
813
-     * @throws EE_Error
814
-     */
815
-    public function subsection_validation_errors_by_html_name()
816
-    {
817
-        $inputs = $this->inputs();
818
-        $errors = array();
819
-        foreach ($inputs as $form_input) {
820
-            if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) {
821
-                $errors[ $form_input->html_name() ] = $form_input->get_validation_error_string();
822
-            }
823
-        }
824
-        return $errors;
825
-    }
826
-
827
-
828
-    /**
829
-     * passes all the form data required by the JS to the JS, and enqueues the few required JS files.
830
-     * Should be setup by each form during the _enqueues_and_localize_form_js
831
-     *
832
-     * @throws InvalidArgumentException
833
-     * @throws InvalidInterfaceException
834
-     * @throws InvalidDataTypeException
835
-     */
836
-    public static function localize_script_for_all_forms()
837
-    {
838
-        //allow inputs and stuff to hook in their JS and stuff here
839
-        do_action('AHEE__EE_Form_Section_Proper__localize_script_for_all_forms__begin');
840
-        EE_Form_Section_Proper::$_js_localization['localized_error_messages'] = EE_Form_Section_Proper::_get_localized_error_messages();
841
-        $email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level)
842
-            ? EE_Registry::instance()->CFG->registration->email_validation_level
843
-            : 'wp_default';
844
-        EE_Form_Section_Proper::$_js_localization['email_validation_level']   = $email_validation_level;
845
-        wp_enqueue_script('ee_form_section_validation');
846
-        wp_localize_script(
847
-            'ee_form_section_validation',
848
-            'ee_form_section_vars',
849
-            EE_Form_Section_Proper::$_js_localization
850
-        );
851
-    }
852
-
853
-
854
-    /**
855
-     * ensure_scripts_localized
856
-     *
857
-     * @throws EE_Error
858
-     */
859
-    public function ensure_scripts_localized()
860
-    {
861
-        if (! EE_Form_Section_Proper::$_scripts_localized) {
862
-            $this->_enqueue_and_localize_form_js();
863
-        }
864
-    }
865
-
866
-
867
-    /**
868
-     * Gets the hard-coded validation error messages to be used in the JS. The convention
869
-     * is that the key here should be the same as the custom validation rule put in the JS file
870
-     *
871
-     * @return array keys are custom validation rules, and values are internationalized strings
872
-     */
873
-    private static function _get_localized_error_messages()
874
-    {
875
-        return array(
876
-            'validUrl' => esc_html__('This is not a valid absolute URL. Eg, http://domain.com/monkey.jpg', 'event_espresso'),
877
-            'regex'    => esc_html__('Please check your input', 'event_espresso'),
878
-        );
879
-    }
880
-
881
-
882
-    /**
883
-     * @return array
884
-     */
885
-    public static function js_localization()
886
-    {
887
-        return self::$_js_localization;
888
-    }
889
-
890
-
891
-    /**
892
-     * @return void
893
-     */
894
-    public static function reset_js_localization()
895
-    {
896
-        self::$_js_localization = array();
897
-    }
898
-
899
-
900
-    /**
901
-     * Gets the JS to put inside the jquery validation rules for subsection of this form section.
902
-     * See parent function for more...
903
-     *
904
-     * @return array
905
-     * @throws EE_Error
906
-     */
907
-    public function get_jquery_validation_rules()
908
-    {
909
-        $jquery_validation_rules = array();
910
-        foreach ($this->get_validatable_subsections() as $subsection) {
911
-            $jquery_validation_rules = array_merge(
912
-                $jquery_validation_rules,
913
-                $subsection->get_jquery_validation_rules()
914
-            );
915
-        }
916
-        return $jquery_validation_rules;
917
-    }
918
-
919
-
920
-    /**
921
-     * Sanitizes all the data and sets the sanitized value of each field
922
-     *
923
-     * @param array $req_data like $_POST
924
-     * @return void
925
-     * @throws EE_Error
926
-     */
927
-    protected function _normalize($req_data)
928
-    {
929
-        $this->_received_submission = true;
930
-        $this->_validation_errors   = array();
931
-        foreach ($this->get_validatable_subsections() as $subsection) {
932
-            try {
933
-                $subsection->_normalize($req_data);
934
-            } catch (EE_Validation_Error $e) {
935
-                $subsection->add_validation_error($e);
936
-            }
937
-        }
938
-    }
939
-
940
-
941
-    /**
942
-     * Performs validation on this form section and its subsections.
943
-     * For each subsection,
944
-     * calls _validate_{subsection_name} on THIS form (if the function exists)
945
-     * and passes it the subsection, then calls _validate on that subsection.
946
-     * If you need to perform validation on the form as a whole (considering multiple)
947
-     * you would be best to override this _validate method,
948
-     * calling parent::_validate() first.
949
-     *
950
-     * @throws EE_Error
951
-     */
952
-    protected function _validate()
953
-    {
954
-        //reset the cache of whether this form is valid or not- we're re-validating it now
955
-        $this->is_valid = null;
956
-        foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
957
-            if (method_exists($this, '_validate_' . $subsection_name)) {
958
-                call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection));
959
-            }
960
-            $subsection->_validate();
961
-        }
962
-    }
963
-
964
-
965
-    /**
966
-     * Gets all the validated inputs for the form section
967
-     *
968
-     * @return array
969
-     * @throws EE_Error
970
-     */
971
-    public function valid_data()
972
-    {
973
-        $inputs = array();
974
-        foreach ($this->subsections() as $subsection_name => $subsection) {
975
-            if ($subsection instanceof EE_Form_Section_Proper) {
976
-                $inputs[ $subsection_name ] = $subsection->valid_data();
977
-            } elseif ($subsection instanceof EE_Form_Input_Base) {
978
-                $inputs[ $subsection_name ] = $subsection->normalized_value();
979
-            }
980
-        }
981
-        return $inputs;
982
-    }
983
-
984
-
985
-    /**
986
-     * Gets all the inputs on this form section
987
-     *
988
-     * @return EE_Form_Input_Base[]
989
-     * @throws EE_Error
990
-     */
991
-    public function inputs()
992
-    {
993
-        $inputs = array();
994
-        foreach ($this->subsections() as $subsection_name => $subsection) {
995
-            if ($subsection instanceof EE_Form_Input_Base) {
996
-                $inputs[ $subsection_name ] = $subsection;
997
-            }
998
-        }
999
-        return $inputs;
1000
-    }
1001
-
1002
-
1003
-    /**
1004
-     * Gets all the subsections which are a proper form
1005
-     *
1006
-     * @return EE_Form_Section_Proper[]
1007
-     * @throws EE_Error
1008
-     */
1009
-    public function subforms()
1010
-    {
1011
-        $form_sections = array();
1012
-        foreach ($this->subsections() as $name => $obj) {
1013
-            if ($obj instanceof EE_Form_Section_Proper) {
1014
-                $form_sections[ $name ] = $obj;
1015
-            }
1016
-        }
1017
-        return $form_sections;
1018
-    }
1019
-
1020
-
1021
-    /**
1022
-     * Gets all the subsections (inputs, proper subsections, or html-only sections).
1023
-     * Consider using inputs() or subforms()
1024
-     * if you only want form inputs or proper form sections.
1025
-     *
1026
-     * @param boolean $require_construction_to_be_finalized most client code should
1027
-     *                                                      leave this as TRUE so that the inputs will be properly
1028
-     *                                                      configured. However, some client code may be ok with
1029
-     *                                                      construction finalize being called later
1030
-     *                                                      (realizing that the subsections' html names might not be
1031
-     *                                                      set yet, etc.)
1032
-     * @return EE_Form_Section_Proper[]
1033
-     * @throws EE_Error
1034
-     */
1035
-    public function subsections($require_construction_to_be_finalized = true)
1036
-    {
1037
-        if ($require_construction_to_be_finalized) {
1038
-            $this->ensure_construct_finalized_called();
1039
-        }
1040
-        return $this->_subsections;
1041
-    }
1042
-
1043
-
1044
-    /**
1045
-     * Returns whether this form has any subforms or inputs
1046
-     * @return bool
1047
-     */
1048
-    public function hasSubsections()
1049
-    {
1050
-        return ! empty($this->_subsections);
1051
-    }
1052
-
1053
-
1054
-    /**
1055
-     * Returns a simple array where keys are input names, and values are their normalized
1056
-     * values. (Similar to calling get_input_value on inputs)
1057
-     *
1058
-     * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1059
-     *                                        or just this forms' direct children inputs
1060
-     * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1061
-     *                                        or allow multidimensional array
1062
-     * @return array if $flatten is TRUE it will always be a 1-dimensional array
1063
-     *                                        with array keys being input names
1064
-     *                                        (regardless of whether they are from a subsection or not),
1065
-     *                                        and if $flatten is FALSE it can be a multidimensional array
1066
-     *                                        where keys are always subsection names and values are either
1067
-     *                                        the input's normalized value, or an array like the top-level array
1068
-     * @throws EE_Error
1069
-     */
1070
-    public function input_values($include_subform_inputs = false, $flatten = false)
1071
-    {
1072
-        return $this->_input_values(false, $include_subform_inputs, $flatten);
1073
-    }
1074
-
1075
-
1076
-    /**
1077
-     * Similar to EE_Form_Section_Proper::input_values(), except this returns the 'display_value'
1078
-     * of each input. On some inputs (especially radio boxes or checkboxes), the value stored
1079
-     * is not necessarily the value we want to display to users. This creates an array
1080
-     * where keys are the input names, and values are their display values
1081
-     *
1082
-     * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1083
-     *                                        or just this forms' direct children inputs
1084
-     * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1085
-     *                                        or allow multidimensional array
1086
-     * @return array if $flatten is TRUE it will always be a 1-dimensional array
1087
-     *                                        with array keys being input names
1088
-     *                                        (regardless of whether they are from a subsection or not),
1089
-     *                                        and if $flatten is FALSE it can be a multidimensional array
1090
-     *                                        where keys are always subsection names and values are either
1091
-     *                                        the input's normalized value, or an array like the top-level array
1092
-     * @throws EE_Error
1093
-     */
1094
-    public function input_pretty_values($include_subform_inputs = false, $flatten = false)
1095
-    {
1096
-        return $this->_input_values(true, $include_subform_inputs, $flatten);
1097
-    }
1098
-
1099
-
1100
-    /**
1101
-     * Gets the input values from the form
1102
-     *
1103
-     * @param boolean $pretty                 Whether to retrieve the pretty value,
1104
-     *                                        or just the normalized value
1105
-     * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1106
-     *                                        or just this forms' direct children inputs
1107
-     * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1108
-     *                                        or allow multidimensional array
1109
-     * @return array if $flatten is TRUE it will always be a 1-dimensional array with array keys being
1110
-     *                                        input names (regardless of whether they are from a subsection or not),
1111
-     *                                        and if $flatten is FALSE it can be a multidimensional array
1112
-     *                                        where keys are always subsection names and values are either
1113
-     *                                        the input's normalized value, or an array like the top-level array
1114
-     * @throws EE_Error
1115
-     */
1116
-    public function _input_values($pretty = false, $include_subform_inputs = false, $flatten = false)
1117
-    {
1118
-        $input_values = array();
1119
-        foreach ($this->subsections() as $subsection_name => $subsection) {
1120
-            if ($subsection instanceof EE_Form_Input_Base) {
1121
-                $input_values[ $subsection_name ] = $pretty
1122
-                    ? $subsection->pretty_value()
1123
-                    : $subsection->normalized_value();
1124
-            } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) {
1125
-                $subform_input_values = $subsection->_input_values(
1126
-                    $pretty,
1127
-                    $include_subform_inputs,
1128
-                    $flatten
1129
-                );
1130
-                if ($flatten) {
1131
-                    $input_values = array_merge($input_values, $subform_input_values);
1132
-                } else {
1133
-                    $input_values[ $subsection_name ] = $subform_input_values;
1134
-                }
1135
-            }
1136
-        }
1137
-        return $input_values;
1138
-    }
1139
-
1140
-
1141
-    /**
1142
-     * Gets the originally submitted input values from the form
1143
-     *
1144
-     * @param boolean $include_subforms  Whether to include inputs from subforms,
1145
-     *                                   or just this forms' direct children inputs
1146
-     * @return array                     if $flatten is TRUE it will always be a 1-dimensional array
1147
-     *                                   with array keys being input names
1148
-     *                                   (regardless of whether they are from a subsection or not),
1149
-     *                                   and if $flatten is FALSE it can be a multidimensional array
1150
-     *                                   where keys are always subsection names and values are either
1151
-     *                                   the input's normalized value, or an array like the top-level array
1152
-     * @throws EE_Error
1153
-     */
1154
-    public function submitted_values($include_subforms = false)
1155
-    {
1156
-        $submitted_values = array();
1157
-        foreach ($this->subsections() as $subsection) {
1158
-            if ($subsection instanceof EE_Form_Input_Base) {
1159
-                // is this input part of an array of inputs?
1160
-                if (strpos($subsection->html_name(), '[') !== false) {
1161
-                    $full_input_name  = EEH_Array::convert_array_values_to_keys(
1162
-                        explode(
1163
-                            '[',
1164
-                            str_replace(']', '', $subsection->html_name())
1165
-                        ),
1166
-                        $subsection->raw_value()
1167
-                    );
1168
-                    $submitted_values = array_replace_recursive($submitted_values, $full_input_name);
1169
-                } else {
1170
-                    $submitted_values[ $subsection->html_name() ] = $subsection->raw_value();
1171
-                }
1172
-            } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subforms) {
1173
-                $subform_input_values = $subsection->submitted_values($include_subforms);
1174
-                $submitted_values     = array_replace_recursive($submitted_values, $subform_input_values);
1175
-            }
1176
-        }
1177
-        return $submitted_values;
1178
-    }
1179
-
1180
-
1181
-    /**
1182
-     * Indicates whether or not this form has received a submission yet
1183
-     * (ie, had receive_form_submission called on it yet)
1184
-     *
1185
-     * @return boolean
1186
-     * @throws EE_Error
1187
-     */
1188
-    public function has_received_submission()
1189
-    {
1190
-        $this->ensure_construct_finalized_called();
1191
-        return $this->_received_submission;
1192
-    }
1193
-
1194
-
1195
-    /**
1196
-     * Equivalent to passing 'exclude' in the constructor's options array.
1197
-     * Removes the listed inputs from the form
1198
-     *
1199
-     * @param array $inputs_to_exclude values are the input names
1200
-     * @return void
1201
-     */
1202
-    public function exclude(array $inputs_to_exclude = array())
1203
-    {
1204
-        foreach ($inputs_to_exclude as $input_to_exclude_name) {
1205
-            unset($this->_subsections[ $input_to_exclude_name ]);
1206
-        }
1207
-    }
1208
-
1209
-
1210
-    /**
1211
-     * Changes these inputs' display strategy to be EE_Hidden_Display_Strategy.
1212
-     * @param array $inputs_to_hide
1213
-     * @throws EE_Error
1214
-     */
1215
-    public function hide(array $inputs_to_hide = array())
1216
-    {
1217
-        foreach ($inputs_to_hide as $input_to_hide) {
1218
-            $input = $this->get_input($input_to_hide);
1219
-            $input->set_display_strategy(new EE_Hidden_Display_Strategy());
1220
-        }
1221
-    }
1222
-
1223
-
1224
-    /**
1225
-     * add_subsections
1226
-     * Adds the listed subsections to the form section.
1227
-     * If $subsection_name_to_target is provided,
1228
-     * then new subsections are added before or after that subsection,
1229
-     * otherwise to the start or end of the entire subsections array.
1230
-     *
1231
-     * @param EE_Form_Section_Base[] $new_subsections           array of new form subsections
1232
-     *                                                          where keys are their names
1233
-     * @param string                 $subsection_name_to_target an existing for section that $new_subsections
1234
-     *                                                          should be added before or after
1235
-     *                                                          IF $subsection_name_to_target is null,
1236
-     *                                                          then $new_subsections will be added to
1237
-     *                                                          the beginning or end of the entire subsections array
1238
-     * @param boolean                $add_before                whether to add $new_subsections, before or after
1239
-     *                                                          $subsection_name_to_target,
1240
-     *                                                          or if $subsection_name_to_target is null,
1241
-     *                                                          before or after entire subsections array
1242
-     * @return void
1243
-     * @throws EE_Error
1244
-     */
1245
-    public function add_subsections($new_subsections, $subsection_name_to_target = null, $add_before = true)
1246
-    {
1247
-        foreach ($new_subsections as $subsection_name => $subsection) {
1248
-            if (! $subsection instanceof EE_Form_Section_Base) {
1249
-                EE_Error::add_error(
1250
-                    sprintf(
1251
-                        esc_html__(
1252
-                            "Trying to add a %s as a subsection (it was named '%s') to the form section '%s'. It was removed.",
1253
-                            'event_espresso'
1254
-                        ),
1255
-                        get_class($subsection),
1256
-                        $subsection_name,
1257
-                        $this->name()
1258
-                    )
1259
-                );
1260
-                unset($new_subsections[ $subsection_name ]);
1261
-            }
1262
-        }
1263
-        $this->_subsections = EEH_Array::insert_into_array(
1264
-            $this->_subsections,
1265
-            $new_subsections,
1266
-            $subsection_name_to_target,
1267
-            $add_before
1268
-        );
1269
-        if ($this->_construction_finalized) {
1270
-            foreach ($this->_subsections as $name => $subsection) {
1271
-                $subsection->_construct_finalize($this, $name);
1272
-            }
1273
-        }
1274
-    }
1275
-
1276
-
1277
-    /**
1278
-     * Just gets all validatable subsections to clean their sensitive data
1279
-     *
1280
-     * @throws EE_Error
1281
-     */
1282
-    public function clean_sensitive_data()
1283
-    {
1284
-        foreach ($this->get_validatable_subsections() as $subsection) {
1285
-            $subsection->clean_sensitive_data();
1286
-        }
1287
-    }
1288
-
1289
-
1290
-    /**
1291
-     * Sets the submission error message (aka validation error message for this form section and all sub-sections)
1292
-     * @param string                           $form_submission_error_message
1293
-     * @param EE_Form_Section_Validatable $form_section unused
1294
-     * @throws EE_Error
1295
-     */
1296
-    public function set_submission_error_message(
1297
-        $form_submission_error_message = ''
1298
-    ) {
1299
-        $this->_form_submission_error_message = ! empty($form_submission_error_message)
1300
-            ? $form_submission_error_message
1301
-            : $this->getAllValidationErrorsString();
1302
-    }
1303
-
1304
-
1305
-    /**
1306
-     * Returns the cached error message. A default value is set for this during _validate(),
1307
-     * (called during receive_form_submission) but it can be explicitly set using
1308
-     * set_submission_error_message
1309
-     *
1310
-     * @return string
1311
-     */
1312
-    public function submission_error_message()
1313
-    {
1314
-        return $this->_form_submission_error_message;
1315
-    }
1316
-
1317
-
1318
-    /**
1319
-     * Sets a message to display if the data submitted to the form was valid.
1320
-     * @param string $form_submission_success_message
1321
-     */
1322
-    public function set_submission_success_message($form_submission_success_message = '')
1323
-    {
1324
-        $this->_form_submission_success_message = ! empty($form_submission_success_message)
1325
-            ? $form_submission_success_message
1326
-            : esc_html__('Form submitted successfully', 'event_espresso');
1327
-    }
1328
-
1329
-
1330
-    /**
1331
-     * Gets a message appropriate for display when the form is correctly submitted
1332
-     * @return string
1333
-     */
1334
-    public function submission_success_message()
1335
-    {
1336
-        return $this->_form_submission_success_message;
1337
-    }
1338
-
1339
-
1340
-    /**
1341
-     * Returns the prefix that should be used on child of this form section for
1342
-     * their html names. If this form section itself has a parent, prepends ITS
1343
-     * prefix onto this form section's prefix. Used primarily by
1344
-     * EE_Form_Input_Base::_set_default_html_name_if_empty
1345
-     *
1346
-     * @return string
1347
-     * @throws EE_Error
1348
-     */
1349
-    public function html_name_prefix()
1350
-    {
1351
-        if ($this->parent_section() instanceof EE_Form_Section_Proper) {
1352
-            return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']';
1353
-        }
1354
-        return $this->name();
1355
-    }
1356
-
1357
-
1358
-    /**
1359
-     * Gets the name, but first checks _construct_finalize has been called. If not,
1360
-     * calls it (assumes there is no parent and that we want the name to be whatever
1361
-     * was set, which is probably nothing, or the classname)
1362
-     *
1363
-     * @return string
1364
-     * @throws EE_Error
1365
-     */
1366
-    public function name()
1367
-    {
1368
-        $this->ensure_construct_finalized_called();
1369
-        return parent::name();
1370
-    }
1371
-
1372
-
1373
-    /**
1374
-     * @return EE_Form_Section_Proper
1375
-     * @throws EE_Error
1376
-     */
1377
-    public function parent_section()
1378
-    {
1379
-        $this->ensure_construct_finalized_called();
1380
-        return parent::parent_section();
1381
-    }
1382
-
1383
-
1384
-    /**
1385
-     * make sure construction finalized was called, otherwise children might not be ready
1386
-     *
1387
-     * @return void
1388
-     * @throws EE_Error
1389
-     */
1390
-    public function ensure_construct_finalized_called()
1391
-    {
1392
-        if (! $this->_construction_finalized) {
1393
-            $this->_construct_finalize($this->_parent_section, $this->_name);
1394
-        }
1395
-    }
1396
-
1397
-
1398
-    /**
1399
-     * Checks if any of this form section's inputs, or any of its children's inputs,
1400
-     * are in teh form data. If any are found, returns true. Else false
1401
-     *
1402
-     * @param array $req_data
1403
-     * @return boolean
1404
-     * @throws EE_Error
1405
-     */
1406
-    public function form_data_present_in($req_data = null)
1407
-    {
1408
-        $req_data = $this->getCachedRequest($req_data);
1409
-        foreach ($this->subsections() as $subsection) {
1410
-            if ($subsection instanceof EE_Form_Input_Base) {
1411
-                if ($subsection->form_data_present_in($req_data)) {
1412
-                    return true;
1413
-                }
1414
-            } elseif ($subsection instanceof EE_Form_Section_Proper) {
1415
-                if ($subsection->form_data_present_in($req_data)) {
1416
-                    return true;
1417
-                }
1418
-            }
1419
-        }
1420
-        return false;
1421
-    }
1422
-
1423
-
1424
-    /**
1425
-     * Gets validation errors for this form section and subsections
1426
-     * Similar to EE_Form_Section_Validatable::get_validation_errors() except this
1427
-     * gets the validation errors for ALL subsection
1428
-     *
1429
-     * @return EE_Validation_Error[]
1430
-     * @throws EE_Error
1431
-     */
1432
-    public function get_validation_errors_accumulated()
1433
-    {
1434
-        $validation_errors = $this->get_validation_errors();
1435
-        foreach ($this->get_validatable_subsections() as $subsection) {
1436
-            if ($subsection instanceof EE_Form_Section_Proper) {
1437
-                $validation_errors_on_this_subsection = $subsection->get_validation_errors_accumulated();
1438
-            } else {
1439
-                $validation_errors_on_this_subsection = $subsection->get_validation_errors();
1440
-            }
1441
-            if ($validation_errors_on_this_subsection) {
1442
-                $validation_errors = array_merge($validation_errors, $validation_errors_on_this_subsection);
1443
-            }
1444
-        }
1445
-        return $validation_errors;
1446
-    }
1447
-
1448
-    /**
1449
-     * Fetch validation errors from children and grandchildren and puts them in a single string.
1450
-     * This traverses the form section tree to generate this, but you probably want to instead use
1451
-     * get_form_submission_error_message() which is usually this message cached (or a custom validation error message)
1452
-     *
1453
-     * @return string
1454
-     * @since $VID:$
1455
-     */
1456
-    protected function getAllValidationErrorsString()
1457
-    {
1458
-        $submission_error_messages = array();
1459
-        // bad, bad, bad registrant
1460
-        foreach ($this->get_validation_errors_accumulated() as $validation_error) {
1461
-            if ($validation_error instanceof EE_Validation_Error) {
1462
-                $form_section = $validation_error->get_form_section();
1463
-                if ($form_section instanceof EE_Form_Input_Base) {
1464
-                   $label = $validation_error->get_form_section()->html_label_text();
1465
-                } elseif($form_section instanceof EE_Form_Section_Validatable) {
1466
-                    $label = $validation_error->get_form_section()->name();
1467
-                } else {
1468
-                    $label = esc_html__('Unknown', 'event_espresso');
1469
-                }
1470
-                $submission_error_messages[] = sprintf(
1471
-                    __('%s : %s', 'event_espresso'),
1472
-                    $label,
1473
-                    $validation_error->getMessage()
1474
-                );
1475
-            }
1476
-        }
1477
-        return implode('<br', $submission_error_messages);
1478
-    }
1479
-
1480
-
1481
-    /**
1482
-     * This isn't just the name of an input, it's a path pointing to an input. The
1483
-     * path is similar to a folder path: slash (/) means to descend into a subsection,
1484
-     * dot-dot-slash (../) means to ascend into the parent section.
1485
-     * After a series of slashes and dot-dot-slashes, there should be the name of an input,
1486
-     * which will be returned.
1487
-     * Eg, if you want the related input to be conditional on a sibling input name 'foobar'
1488
-     * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name
1489
-     * 'baz', use '../baz'. If you want it to be conditional on a cousin input,
1490
-     * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'.
1491
-     * Etc
1492
-     *
1493
-     * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false
1494
-     * @return EE_Form_Section_Base
1495
-     * @throws EE_Error
1496
-     */
1497
-    public function find_section_from_path($form_section_path)
1498
-    {
1499
-        //check if we can find the input from purely going straight up the tree
1500
-        $input = parent::find_section_from_path($form_section_path);
1501
-        if ($input instanceof EE_Form_Section_Base) {
1502
-            return $input;
1503
-        }
1504
-        $next_slash_pos = strpos($form_section_path, '/');
1505
-        if ($next_slash_pos !== false) {
1506
-            $child_section_name = substr($form_section_path, 0, $next_slash_pos);
1507
-            $subpath            = substr($form_section_path, $next_slash_pos + 1);
1508
-        } else {
1509
-            $child_section_name = $form_section_path;
1510
-            $subpath            = '';
1511
-        }
1512
-        $child_section = $this->get_subsection($child_section_name);
1513
-        if ($child_section instanceof EE_Form_Section_Base) {
1514
-            return $child_section->find_section_from_path($subpath);
1515
-        }
1516
-        return null;
1517
-    }
17
+	const SUBMITTED_FORM_DATA_SSN_KEY = 'submitted_form_data';
18
+
19
+	/**
20
+	 * Subsections
21
+	 *
22
+	 * @var EE_Form_Section_Validatable[]
23
+	 */
24
+	protected $_subsections = array();
25
+
26
+	/**
27
+	 * Strategy for laying out the form
28
+	 *
29
+	 * @var EE_Form_Section_Layout_Base
30
+	 */
31
+	protected $_layout_strategy;
32
+
33
+	/**
34
+	 * Whether or not this form has received and validated a form submission yet
35
+	 *
36
+	 * @var boolean
37
+	 */
38
+	protected $_received_submission = false;
39
+
40
+	/**
41
+	 * message displayed to users upon successful form submission
42
+	 *
43
+	 * @var string
44
+	 */
45
+	protected $_form_submission_success_message = '';
46
+
47
+	/**
48
+	 * message displayed to users upon unsuccessful form submission
49
+	 *
50
+	 * @var string
51
+	 */
52
+	protected $_form_submission_error_message = '';
53
+
54
+	/**
55
+	 * @var array like $_REQUEST
56
+	 */
57
+	protected $cached_request_data;
58
+
59
+	/**
60
+	 * Stores whether this form (and its sub-sections) were found to be valid or not.
61
+	 * Starts off as null, but once the form is validated, it set to either true or false
62
+	 * @var boolean|null
63
+	 */
64
+	protected $is_valid;
65
+
66
+	/**
67
+	 * Stores all the data that will localized for form validation
68
+	 *
69
+	 * @var array
70
+	 */
71
+	static protected $_js_localization = array();
72
+
73
+	/**
74
+	 * whether or not the form's localized validation JS vars have been set
75
+	 *
76
+	 * @type boolean
77
+	 */
78
+	static protected $_scripts_localized = false;
79
+
80
+
81
+	/**
82
+	 * when constructing a proper form section, calls _construct_finalize on children
83
+	 * so that they know who their parent is, and what name they've been given.
84
+	 *
85
+	 * @param array[] $options_array   {
86
+	 * @type          $subsections     EE_Form_Section_Validatable[] where keys are the section's name
87
+	 * @type          $include         string[] numerically-indexed where values are section names to be included,
88
+	 *                                 and in that order. This is handy if you want
89
+	 *                                 the subsections to be ordered differently than the default, and if you override
90
+	 *                                 which fields are shown
91
+	 * @type          $exclude         string[] values are subsections to be excluded. This is handy if you want
92
+	 *                                 to remove certain default subsections (note: if you specify BOTH 'include' AND
93
+	 *                                 'exclude', the inclusions will be applied first, and the exclusions will exclude
94
+	 *                                 items from that list of inclusions)
95
+	 * @type          $layout_strategy EE_Form_Section_Layout_Base strategy for laying out the form
96
+	 *                                 } @see EE_Form_Section_Validatable::__construct()
97
+	 * @throws EE_Error
98
+	 */
99
+	public function __construct($options_array = array())
100
+	{
101
+		$options_array = (array) apply_filters(
102
+			'FHEE__EE_Form_Section_Proper___construct__options_array',
103
+			$options_array,
104
+			$this
105
+		);
106
+		//call parent first, as it may be setting the name
107
+		parent::__construct($options_array);
108
+		//if they've included subsections in the constructor, add them now
109
+		if (isset($options_array['include'])) {
110
+			//we are going to make sure we ONLY have those subsections to include
111
+			//AND we are going to make sure they're in that specified order
112
+			$reordered_subsections = array();
113
+			foreach ($options_array['include'] as $input_name) {
114
+				if (isset($this->_subsections[ $input_name ])) {
115
+					$reordered_subsections[ $input_name ] = $this->_subsections[ $input_name ];
116
+				}
117
+			}
118
+			$this->_subsections = $reordered_subsections;
119
+		}
120
+		if (isset($options_array['exclude'])) {
121
+			$exclude            = $options_array['exclude'];
122
+			$this->_subsections = array_diff_key($this->_subsections, array_flip($exclude));
123
+		}
124
+		if (isset($options_array['layout_strategy'])) {
125
+			$this->_layout_strategy = $options_array['layout_strategy'];
126
+		}
127
+		if (! $this->_layout_strategy) {
128
+			$this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout();
129
+		}
130
+		$this->_layout_strategy->_construct_finalize($this);
131
+		//ok so we are definitely going to want the forms JS,
132
+		//so enqueue it or remember to enqueue it during wp_enqueue_scripts
133
+		if (did_action('wp_enqueue_scripts') || did_action('admin_enqueue_scripts')) {
134
+			//ok so they've constructed this object after when they should have.
135
+			//just enqueue the generic form scripts and initialize the form immediately in the JS
136
+			EE_Form_Section_Proper::wp_enqueue_scripts(true);
137
+		} else {
138
+			add_action('wp_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
139
+			add_action('admin_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts'));
140
+		}
141
+		add_action('wp_footer', array($this, 'ensure_scripts_localized'), 1);
142
+		/**
143
+		 * Gives other plugins a chance to hook in before construct finalize is called.
144
+		 * The form probably doesn't yet have a parent form section.
145
+		 * Since 4.9.32, when this action was introduced, this is the best place to add a subsection onto a form,
146
+		 * assuming you don't care what the form section's name, HTML ID, or HTML name etc are.
147
+		 * Also see AHEE__EE_Form_Section_Proper___construct_finalize__end
148
+		 *
149
+		 * @since 4.9.32
150
+		 * @param EE_Form_Section_Proper $this          before __construct is done, but all of its logic,
151
+		 *                                              except maybe calling _construct_finalize has been done
152
+		 * @param array                  $options_array options passed into the constructor
153
+		 */
154
+		do_action(
155
+			'AHEE__EE_Form_Input_Base___construct__before_construct_finalize_called',
156
+			$this,
157
+			$options_array
158
+		);
159
+		if (isset($options_array['name'])) {
160
+			$this->_construct_finalize(null, $options_array['name']);
161
+		}
162
+	}
163
+
164
+
165
+	/**
166
+	 * Finishes construction given the parent form section and this form section's name
167
+	 *
168
+	 * @param EE_Form_Section_Proper $parent_form_section
169
+	 * @param string                 $name
170
+	 * @throws EE_Error
171
+	 */
172
+	public function _construct_finalize($parent_form_section, $name)
173
+	{
174
+		parent::_construct_finalize($parent_form_section, $name);
175
+		$this->_set_default_name_if_empty();
176
+		$this->_set_default_html_id_if_empty();
177
+		foreach ($this->_subsections as $subsection_name => $subsection) {
178
+			if ($subsection instanceof EE_Form_Section_Base) {
179
+				$subsection->_construct_finalize($this, $subsection_name);
180
+			} else {
181
+				throw new EE_Error(
182
+					sprintf(
183
+						esc_html__(
184
+							'Subsection "%s" is not an instanceof EE_Form_Section_Base on form "%s". It is a "%s"',
185
+							'event_espresso'
186
+						),
187
+						$subsection_name,
188
+						get_class($this),
189
+						$subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso')
190
+					)
191
+				);
192
+			}
193
+		}
194
+		/**
195
+		 * Action performed just after form has been given a name (and HTML ID etc) and is fully constructed.
196
+		 * If you have code that should modify the form and needs it and its subsections to have a name, HTML ID
197
+		 * (or other attributes derived from the name like the HTML label id, etc), this is where it should be done.
198
+		 * This might only happen just before displaying the form, or just before it receives form submission data.
199
+		 * If you need to modify the form or its subsections before _construct_finalize is called on it (and we've
200
+		 * ensured it has a name, HTML IDs, etc
201
+		 *
202
+		 * @param EE_Form_Section_Proper      $this
203
+		 * @param EE_Form_Section_Proper|null $parent_form_section
204
+		 * @param string                      $name
205
+		 */
206
+		do_action(
207
+			'AHEE__EE_Form_Section_Proper___construct_finalize__end',
208
+			$this,
209
+			$parent_form_section,
210
+			$name
211
+		);
212
+	}
213
+
214
+
215
+	/**
216
+	 * Gets the layout strategy for this form section
217
+	 *
218
+	 * @return EE_Form_Section_Layout_Base
219
+	 */
220
+	public function get_layout_strategy()
221
+	{
222
+		return $this->_layout_strategy;
223
+	}
224
+
225
+
226
+	/**
227
+	 * Gets the HTML for a single input for this form section according
228
+	 * to the layout strategy
229
+	 *
230
+	 * @param EE_Form_Input_Base $input
231
+	 * @return string
232
+	 */
233
+	public function get_html_for_input($input)
234
+	{
235
+		return $this->_layout_strategy->layout_input($input);
236
+	}
237
+
238
+
239
+	/**
240
+	 * was_submitted - checks if form inputs are present in request data
241
+	 * Basically an alias for form_data_present_in() (which is used by both
242
+	 * proper form sections and form inputs)
243
+	 *
244
+	 * @param null $form_data
245
+	 * @return boolean
246
+	 * @throws EE_Error
247
+	 */
248
+	public function was_submitted($form_data = null)
249
+	{
250
+		return $this->form_data_present_in($form_data);
251
+	}
252
+
253
+	/**
254
+	 * Gets the cached request data; but if there is none, or $req_data was set with
255
+	 * something different, refresh the cache, and then return it
256
+	 * @param null $req_data
257
+	 * @return array
258
+	 */
259
+	protected function getCachedRequest($req_data = null)
260
+	{
261
+		if ($this->cached_request_data === null
262
+			|| (
263
+				$req_data !== null &&
264
+				$req_data !== $this->cached_request_data
265
+			)
266
+		) {
267
+			$req_data = apply_filters(
268
+				'FHEE__EE_Form_Section_Proper__receive_form_submission__req_data',
269
+				$req_data,
270
+				$this
271
+			);
272
+			if ($req_data === null) {
273
+				$req_data = array_merge($_GET, $_POST);
274
+			}
275
+			$req_data = apply_filters(
276
+				'FHEE__EE_Form_Section_Proper__receive_form_submission__request_data',
277
+				$req_data,
278
+				$this
279
+			);
280
+			$this->cached_request_data = (array)$req_data;
281
+		}
282
+		return $this->cached_request_data;
283
+	}
284
+
285
+
286
+	/**
287
+	 * After the form section is initially created, call this to sanitize the data in the submission
288
+	 * which relates to this form section, validate it, and set it as properties on the form.
289
+	 *
290
+	 * @param array|null $req_data should usually be $_POST (the default).
291
+	 *                             However, you CAN supply a different array.
292
+	 *                             Consider using set_defaults() instead however.
293
+	 *                             (If you rendered the form in the page using echo $form_x->get_html()
294
+	 *                             the inputs will have the correct name in the request data for this function
295
+	 *                             to find them and populate the form with them.
296
+	 *                             If you have a flat form (with only input subsections),
297
+	 *                             you can supply a flat array where keys
298
+	 *                             are the form input names and values are their values)
299
+	 * @param boolean    $validate whether or not to perform validation on this data. Default is,
300
+	 *                             of course, to validate that data, and set errors on the invalid values.
301
+	 *                             But if the data has already been validated
302
+	 *                             (eg you validated the data then stored it in the DB)
303
+	 *                             you may want to skip this step.
304
+	 * @throws InvalidArgumentException
305
+	 * @throws InvalidInterfaceException
306
+	 * @throws InvalidDataTypeException
307
+	 * @throws EE_Error
308
+	 */
309
+	public function receive_form_submission($req_data = null, $validate = true)
310
+	{
311
+		$req_data = $this->getCachedRequest($req_data);
312
+		$this->_normalize($req_data);
313
+		if ($validate) {
314
+			$this->_validate();
315
+			//if it's invalid, we're going to want to re-display so remember what they submitted
316
+			if (! $this->is_valid()) {
317
+				$this->store_submitted_form_data_in_session();
318
+			}
319
+		}
320
+		if ($this->submission_error_message() === '' && ! $this->is_valid()) {
321
+			$this->set_submission_error_message();
322
+		}
323
+		do_action(
324
+			'AHEE__EE_Form_Section_Proper__receive_form_submission__end',
325
+			$req_data,
326
+			$this,
327
+			$validate
328
+		);
329
+	}
330
+
331
+
332
+	/**
333
+	 * caches the originally submitted input values in the session
334
+	 * so that they can be used to repopulate the form if it failed validation
335
+	 *
336
+	 * @return boolean whether or not the data was successfully stored in the session
337
+	 * @throws InvalidArgumentException
338
+	 * @throws InvalidInterfaceException
339
+	 * @throws InvalidDataTypeException
340
+	 * @throws EE_Error
341
+	 */
342
+	protected function store_submitted_form_data_in_session()
343
+	{
344
+		return EE_Registry::instance()->SSN->set_session_data(
345
+			array(
346
+				EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY => $this->submitted_values(true),
347
+			)
348
+		);
349
+	}
350
+
351
+
352
+	/**
353
+	 * retrieves the originally submitted input values in the session
354
+	 * so that they can be used to repopulate the form if it failed validation
355
+	 *
356
+	 * @return array
357
+	 * @throws InvalidArgumentException
358
+	 * @throws InvalidInterfaceException
359
+	 * @throws InvalidDataTypeException
360
+	 */
361
+	protected function get_submitted_form_data_from_session()
362
+	{
363
+		$session = EE_Registry::instance()->SSN;
364
+		if ($session instanceof EE_Session) {
365
+			return $session->get_session_data(
366
+				EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY
367
+			);
368
+		}
369
+		return array();
370
+	}
371
+
372
+
373
+	/**
374
+	 * flushed the originally submitted input values from the session
375
+	 *
376
+	 * @return boolean whether or not the data was successfully removed from the session
377
+	 * @throws InvalidArgumentException
378
+	 * @throws InvalidInterfaceException
379
+	 * @throws InvalidDataTypeException
380
+	 */
381
+	protected function flush_submitted_form_data_from_session()
382
+	{
383
+		return EE_Registry::instance()->SSN->reset_data(
384
+			array(EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY)
385
+		);
386
+	}
387
+
388
+
389
+	/**
390
+	 * Populates this form and its subsections with data from the session.
391
+	 * (Wrapper for EE_Form_Section_Proper::receive_form_submission, so it shows
392
+	 * validation errors when displaying too)
393
+	 * Returns true if the form was populated from the session, false otherwise
394
+	 *
395
+	 * @return boolean
396
+	 * @throws InvalidArgumentException
397
+	 * @throws InvalidInterfaceException
398
+	 * @throws InvalidDataTypeException
399
+	 * @throws EE_Error
400
+	 */
401
+	public function populate_from_session()
402
+	{
403
+		$form_data_in_session = $this->get_submitted_form_data_from_session();
404
+		if (empty($form_data_in_session)) {
405
+			return false;
406
+		}
407
+		$this->receive_form_submission($form_data_in_session);
408
+		$this->flush_submitted_form_data_from_session();
409
+		if ($this->form_data_present_in($form_data_in_session)) {
410
+			return true;
411
+		}
412
+		return false;
413
+	}
414
+
415
+
416
+	/**
417
+	 * Populates the default data for the form, given an array where keys are
418
+	 * the input names, and values are their values (preferably normalized to be their
419
+	 * proper PHP types, not all strings... although that should be ok too).
420
+	 * Proper subsections are sub-arrays, the key being the subsection's name, and
421
+	 * the value being an array formatted in teh same way
422
+	 *
423
+	 * @param array $default_data
424
+	 * @throws EE_Error
425
+	 */
426
+	public function populate_defaults($default_data)
427
+	{
428
+		foreach ($this->subsections(false) as $subsection_name => $subsection) {
429
+			if (isset($default_data[ $subsection_name ])) {
430
+				if ($subsection instanceof EE_Form_Input_Base) {
431
+					$subsection->set_default($default_data[ $subsection_name ]);
432
+				} elseif ($subsection instanceof EE_Form_Section_Proper) {
433
+					$subsection->populate_defaults($default_data[ $subsection_name ]);
434
+				}
435
+			}
436
+		}
437
+	}
438
+
439
+
440
+	/**
441
+	 * returns true if subsection exists
442
+	 *
443
+	 * @param string $name
444
+	 * @return boolean
445
+	 */
446
+	public function subsection_exists($name)
447
+	{
448
+		return isset($this->_subsections[ $name ]) ? true : false;
449
+	}
450
+
451
+
452
+	/**
453
+	 * Gets the subsection specified by its name
454
+	 *
455
+	 * @param string  $name
456
+	 * @param boolean $require_construction_to_be_finalized most client code should leave this as TRUE
457
+	 *                                                      so that the inputs will be properly configured.
458
+	 *                                                      However, some client code may be ok
459
+	 *                                                      with construction finalize being called later
460
+	 *                                                      (realizing that the subsections' html names
461
+	 *                                                      might not be set yet, etc.)
462
+	 * @return EE_Form_Section_Base
463
+	 * @throws EE_Error
464
+	 */
465
+	public function get_subsection($name, $require_construction_to_be_finalized = true)
466
+	{
467
+		if ($require_construction_to_be_finalized) {
468
+			$this->ensure_construct_finalized_called();
469
+		}
470
+		return $this->subsection_exists($name) ? $this->_subsections[ $name ] : null;
471
+	}
472
+
473
+
474
+	/**
475
+	 * Gets all the validatable subsections of this form section
476
+	 *
477
+	 * @return EE_Form_Section_Validatable[]
478
+	 * @throws EE_Error
479
+	 */
480
+	public function get_validatable_subsections()
481
+	{
482
+		$validatable_subsections = array();
483
+		foreach ($this->subsections() as $name => $obj) {
484
+			if ($obj instanceof EE_Form_Section_Validatable) {
485
+				$validatable_subsections[ $name ] = $obj;
486
+			}
487
+		}
488
+		return $validatable_subsections;
489
+	}
490
+
491
+
492
+	/**
493
+	 * Gets an input by the given name. If not found, or if its not an EE_FOrm_Input_Base child,
494
+	 * throw an EE_Error.
495
+	 *
496
+	 * @param string  $name
497
+	 * @param boolean $require_construction_to_be_finalized most client code should
498
+	 *                                                      leave this as TRUE so that the inputs will be properly
499
+	 *                                                      configured. However, some client code may be ok with
500
+	 *                                                      construction finalize being called later
501
+	 *                                                      (realizing that the subsections' html names might not be
502
+	 *                                                      set yet, etc.)
503
+	 * @return EE_Form_Input_Base
504
+	 * @throws EE_Error
505
+	 */
506
+	public function get_input($name, $require_construction_to_be_finalized = true)
507
+	{
508
+		$subsection = $this->get_subsection(
509
+			$name,
510
+			$require_construction_to_be_finalized
511
+		);
512
+		if (! $subsection instanceof EE_Form_Input_Base) {
513
+			throw new EE_Error(
514
+				sprintf(
515
+					esc_html__(
516
+						"Subsection '%s' is not an instanceof EE_Form_Input_Base on form '%s'. It is a '%s'",
517
+						'event_espresso'
518
+					),
519
+					$name,
520
+					get_class($this),
521
+					$subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso')
522
+				)
523
+			);
524
+		}
525
+		return $subsection;
526
+	}
527
+
528
+
529
+	/**
530
+	 * Like get_input(), gets the proper subsection of the form given the name,
531
+	 * otherwise throws an EE_Error
532
+	 *
533
+	 * @param string  $name
534
+	 * @param boolean $require_construction_to_be_finalized most client code should
535
+	 *                                                      leave this as TRUE so that the inputs will be properly
536
+	 *                                                      configured. However, some client code may be ok with
537
+	 *                                                      construction finalize being called later
538
+	 *                                                      (realizing that the subsections' html names might not be
539
+	 *                                                      set yet, etc.)
540
+	 * @return EE_Form_Section_Proper
541
+	 * @throws EE_Error
542
+	 */
543
+	public function get_proper_subsection($name, $require_construction_to_be_finalized = true)
544
+	{
545
+		$subsection = $this->get_subsection(
546
+			$name,
547
+			$require_construction_to_be_finalized
548
+		);
549
+		if (! $subsection instanceof EE_Form_Section_Proper) {
550
+			throw new EE_Error(
551
+				sprintf(
552
+					esc_html__(
553
+						"Subsection '%'s is not an instanceof EE_Form_Section_Proper on form '%s'",
554
+						'event_espresso'
555
+					),
556
+					$name,
557
+					get_class($this)
558
+				)
559
+			);
560
+		}
561
+		return $subsection;
562
+	}
563
+
564
+
565
+	/**
566
+	 * Gets the value of the specified input. Should be called after receive_form_submission()
567
+	 * or populate_defaults() on the form, where the normalized value on the input is set.
568
+	 *
569
+	 * @param string $name
570
+	 * @return mixed depending on the input's type and its normalization strategy
571
+	 * @throws EE_Error
572
+	 */
573
+	public function get_input_value($name)
574
+	{
575
+		$input = $this->get_input($name);
576
+		return $input->normalized_value();
577
+	}
578
+
579
+
580
+	/**
581
+	 * Checks if this form section itself is valid, and then checks its subsections
582
+	 *
583
+	 * @throws EE_Error
584
+	 * @return boolean
585
+	 */
586
+	public function is_valid()
587
+	{
588
+		if($this->is_valid === null) {
589
+			if (! $this->has_received_submission()) {
590
+				throw new EE_Error(
591
+					sprintf(
592
+						esc_html__(
593
+							'You cannot check if a form is valid before receiving the form submission using receive_form_submission',
594
+							'event_espresso'
595
+						)
596
+					)
597
+				);
598
+			}
599
+			if (! parent::is_valid()) {
600
+				$this->is_valid = false;
601
+			} else {
602
+				// ok so no general errors to this entire form section.
603
+				// so let's check the subsections, but only set errors if that hasn't been done yet
604
+				$this->is_valid = true;
605
+				foreach ($this->get_validatable_subsections() as $subsection) {
606
+					if (! $subsection->is_valid()) {
607
+						$this->is_valid = false;
608
+					}
609
+				}
610
+			}
611
+		}
612
+		return $this->is_valid;
613
+	}
614
+
615
+
616
+	/**
617
+	 * gets the default name of this form section if none is specified
618
+	 *
619
+	 * @return void
620
+	 */
621
+	protected function _set_default_name_if_empty()
622
+	{
623
+		if (! $this->_name) {
624
+			$classname    = get_class($this);
625
+			$default_name = str_replace('EE_', '', $classname);
626
+			$this->_name  = $default_name;
627
+		}
628
+	}
629
+
630
+
631
+	/**
632
+	 * Returns the HTML for the form, except for the form opening and closing tags
633
+	 * (as the form section doesn't know where you necessarily want to send the information to),
634
+	 * and except for a submit button. Enqueues JS and CSS; if called early enough we will
635
+	 * try to enqueue them in the header, otherwise they'll be enqueued in the footer.
636
+	 * Not doing_it_wrong because theoretically this CAN be used properly,
637
+	 * provided its used during "wp_enqueue_scripts", or it doesn't need to enqueue
638
+	 * any CSS.
639
+	 *
640
+	 * @throws InvalidArgumentException
641
+	 * @throws InvalidInterfaceException
642
+	 * @throws InvalidDataTypeException
643
+	 * @throws EE_Error
644
+	 */
645
+	public function get_html_and_js()
646
+	{
647
+		$this->enqueue_js();
648
+		return $this->get_html();
649
+	}
650
+
651
+
652
+	/**
653
+	 * returns HTML for displaying this form section. recursively calls display_section() on all subsections
654
+	 *
655
+	 * @param bool $display_previously_submitted_data
656
+	 * @return string
657
+	 * @throws InvalidArgumentException
658
+	 * @throws InvalidInterfaceException
659
+	 * @throws InvalidDataTypeException
660
+	 * @throws EE_Error
661
+	 * @throws EE_Error
662
+	 * @throws EE_Error
663
+	 */
664
+	public function get_html($display_previously_submitted_data = true)
665
+	{
666
+		$this->ensure_construct_finalized_called();
667
+		if ($display_previously_submitted_data) {
668
+			$this->populate_from_session();
669
+		}
670
+		return $this->_form_html_filter
671
+			? $this->_form_html_filter->filterHtml($this->_layout_strategy->layout_form(), $this)
672
+			: $this->_layout_strategy->layout_form();
673
+	}
674
+
675
+
676
+	/**
677
+	 * enqueues JS and CSS for the form.
678
+	 * It is preferred to call this before wp_enqueue_scripts so the
679
+	 * scripts and styles can be put in the header, but if called later
680
+	 * they will be put in the footer (which is OK for JS, but in HTML4 CSS should
681
+	 * only be in the header; but in HTML5 its ok in the body.
682
+	 * See http://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag.
683
+	 * So if your form enqueues CSS, it's preferred to call this before wp_enqueue_scripts.)
684
+	 *
685
+	 * @return void
686
+	 * @throws EE_Error
687
+	 */
688
+	public function enqueue_js()
689
+	{
690
+		$this->_enqueue_and_localize_form_js();
691
+		foreach ($this->subsections() as $subsection) {
692
+			$subsection->enqueue_js();
693
+		}
694
+	}
695
+
696
+
697
+	/**
698
+	 * adds a filter so that jquery validate gets enqueued in EE_System::wp_enqueue_scripts().
699
+	 * This must be done BEFORE wp_enqueue_scripts() gets called, which is on
700
+	 * the wp_enqueue_scripts hook.
701
+	 * However, registering the form js and localizing it can happen when we
702
+	 * actually output the form (which is preferred, seeing how teh form's fields
703
+	 * could change until it's actually outputted)
704
+	 *
705
+	 * @param boolean $init_form_validation_automatically whether or not we want the form validation
706
+	 *                                                    to be triggered automatically or not
707
+	 * @return void
708
+	 */
709
+	public static function wp_enqueue_scripts($init_form_validation_automatically = true)
710
+	{
711
+		wp_register_script(
712
+			'ee_form_section_validation',
713
+			EE_GLOBAL_ASSETS_URL . 'scripts' . DS . 'form_section_validation.js',
714
+			array('jquery-validate', 'jquery-ui-datepicker', 'jquery-validate-extra-methods'),
715
+			EVENT_ESPRESSO_VERSION,
716
+			true
717
+		);
718
+		wp_localize_script(
719
+			'ee_form_section_validation',
720
+			'ee_form_section_validation_init',
721
+			array('init' => $init_form_validation_automatically ? '1' : '0')
722
+		);
723
+	}
724
+
725
+
726
+	/**
727
+	 * gets the variables used by form_section_validation.js.
728
+	 * This needs to be called AFTER we've called $this->_enqueue_jquery_validate_script,
729
+	 * but before the wordpress hook wp_loaded
730
+	 *
731
+	 * @throws EE_Error
732
+	 */
733
+	public function _enqueue_and_localize_form_js()
734
+	{
735
+		$this->ensure_construct_finalized_called();
736
+		//actually, we don't want to localize just yet. There may be other forms on the page.
737
+		//so we need to add our form section data to a static variable accessible by all form sections
738
+		//and localize it just before the footer
739
+		$this->localize_validation_rules();
740
+		add_action('wp_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'), 2);
741
+		add_action('admin_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'));
742
+	}
743
+
744
+
745
+	/**
746
+	 * add our form section data to a static variable accessible by all form sections
747
+	 *
748
+	 * @param bool $return_for_subsection
749
+	 * @return void
750
+	 * @throws EE_Error
751
+	 */
752
+	public function localize_validation_rules($return_for_subsection = false)
753
+	{
754
+		// we only want to localize vars ONCE for the entire form,
755
+		// so if the form section doesn't have a parent, then it must be the top dog
756
+		if ($return_for_subsection || ! $this->parent_section()) {
757
+			EE_Form_Section_Proper::$_js_localization['form_data'][ $this->html_id() ] = array(
758
+				'form_section_id'  => $this->html_id(true),
759
+				'validation_rules' => $this->get_jquery_validation_rules(),
760
+				'other_data'       => $this->get_other_js_data(),
761
+				'errors'           => $this->subsection_validation_errors_by_html_name(),
762
+			);
763
+			EE_Form_Section_Proper::$_scripts_localized                                = true;
764
+		}
765
+	}
766
+
767
+
768
+	/**
769
+	 * Gets an array of extra data that will be useful for client-side javascript.
770
+	 * This is primarily data added by inputs and forms in addition to any
771
+	 * scripts they might enqueue
772
+	 *
773
+	 * @param array $form_other_js_data
774
+	 * @return array
775
+	 * @throws EE_Error
776
+	 */
777
+	public function get_other_js_data($form_other_js_data = array())
778
+	{
779
+		foreach ($this->subsections() as $subsection) {
780
+			$form_other_js_data = $subsection->get_other_js_data($form_other_js_data);
781
+		}
782
+		return $form_other_js_data;
783
+	}
784
+
785
+
786
+	/**
787
+	 * Gets a flat array of inputs for this form section and its subsections.
788
+	 * Keys are their form names, and values are the inputs themselves
789
+	 *
790
+	 * @return EE_Form_Input_Base
791
+	 * @throws EE_Error
792
+	 */
793
+	public function inputs_in_subsections()
794
+	{
795
+		$inputs = array();
796
+		foreach ($this->subsections() as $subsection) {
797
+			if ($subsection instanceof EE_Form_Input_Base) {
798
+				$inputs[ $subsection->html_name() ] = $subsection;
799
+			} elseif ($subsection instanceof EE_Form_Section_Proper) {
800
+				$inputs += $subsection->inputs_in_subsections();
801
+			}
802
+		}
803
+		return $inputs;
804
+	}
805
+
806
+
807
+	/**
808
+	 * Gets a flat array of all the validation errors.
809
+	 * Keys are html names (because those should be unique)
810
+	 * and values are a string of all their validation errors
811
+	 *
812
+	 * @return string[]
813
+	 * @throws EE_Error
814
+	 */
815
+	public function subsection_validation_errors_by_html_name()
816
+	{
817
+		$inputs = $this->inputs();
818
+		$errors = array();
819
+		foreach ($inputs as $form_input) {
820
+			if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) {
821
+				$errors[ $form_input->html_name() ] = $form_input->get_validation_error_string();
822
+			}
823
+		}
824
+		return $errors;
825
+	}
826
+
827
+
828
+	/**
829
+	 * passes all the form data required by the JS to the JS, and enqueues the few required JS files.
830
+	 * Should be setup by each form during the _enqueues_and_localize_form_js
831
+	 *
832
+	 * @throws InvalidArgumentException
833
+	 * @throws InvalidInterfaceException
834
+	 * @throws InvalidDataTypeException
835
+	 */
836
+	public static function localize_script_for_all_forms()
837
+	{
838
+		//allow inputs and stuff to hook in their JS and stuff here
839
+		do_action('AHEE__EE_Form_Section_Proper__localize_script_for_all_forms__begin');
840
+		EE_Form_Section_Proper::$_js_localization['localized_error_messages'] = EE_Form_Section_Proper::_get_localized_error_messages();
841
+		$email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level)
842
+			? EE_Registry::instance()->CFG->registration->email_validation_level
843
+			: 'wp_default';
844
+		EE_Form_Section_Proper::$_js_localization['email_validation_level']   = $email_validation_level;
845
+		wp_enqueue_script('ee_form_section_validation');
846
+		wp_localize_script(
847
+			'ee_form_section_validation',
848
+			'ee_form_section_vars',
849
+			EE_Form_Section_Proper::$_js_localization
850
+		);
851
+	}
852
+
853
+
854
+	/**
855
+	 * ensure_scripts_localized
856
+	 *
857
+	 * @throws EE_Error
858
+	 */
859
+	public function ensure_scripts_localized()
860
+	{
861
+		if (! EE_Form_Section_Proper::$_scripts_localized) {
862
+			$this->_enqueue_and_localize_form_js();
863
+		}
864
+	}
865
+
866
+
867
+	/**
868
+	 * Gets the hard-coded validation error messages to be used in the JS. The convention
869
+	 * is that the key here should be the same as the custom validation rule put in the JS file
870
+	 *
871
+	 * @return array keys are custom validation rules, and values are internationalized strings
872
+	 */
873
+	private static function _get_localized_error_messages()
874
+	{
875
+		return array(
876
+			'validUrl' => esc_html__('This is not a valid absolute URL. Eg, http://domain.com/monkey.jpg', 'event_espresso'),
877
+			'regex'    => esc_html__('Please check your input', 'event_espresso'),
878
+		);
879
+	}
880
+
881
+
882
+	/**
883
+	 * @return array
884
+	 */
885
+	public static function js_localization()
886
+	{
887
+		return self::$_js_localization;
888
+	}
889
+
890
+
891
+	/**
892
+	 * @return void
893
+	 */
894
+	public static function reset_js_localization()
895
+	{
896
+		self::$_js_localization = array();
897
+	}
898
+
899
+
900
+	/**
901
+	 * Gets the JS to put inside the jquery validation rules for subsection of this form section.
902
+	 * See parent function for more...
903
+	 *
904
+	 * @return array
905
+	 * @throws EE_Error
906
+	 */
907
+	public function get_jquery_validation_rules()
908
+	{
909
+		$jquery_validation_rules = array();
910
+		foreach ($this->get_validatable_subsections() as $subsection) {
911
+			$jquery_validation_rules = array_merge(
912
+				$jquery_validation_rules,
913
+				$subsection->get_jquery_validation_rules()
914
+			);
915
+		}
916
+		return $jquery_validation_rules;
917
+	}
918
+
919
+
920
+	/**
921
+	 * Sanitizes all the data and sets the sanitized value of each field
922
+	 *
923
+	 * @param array $req_data like $_POST
924
+	 * @return void
925
+	 * @throws EE_Error
926
+	 */
927
+	protected function _normalize($req_data)
928
+	{
929
+		$this->_received_submission = true;
930
+		$this->_validation_errors   = array();
931
+		foreach ($this->get_validatable_subsections() as $subsection) {
932
+			try {
933
+				$subsection->_normalize($req_data);
934
+			} catch (EE_Validation_Error $e) {
935
+				$subsection->add_validation_error($e);
936
+			}
937
+		}
938
+	}
939
+
940
+
941
+	/**
942
+	 * Performs validation on this form section and its subsections.
943
+	 * For each subsection,
944
+	 * calls _validate_{subsection_name} on THIS form (if the function exists)
945
+	 * and passes it the subsection, then calls _validate on that subsection.
946
+	 * If you need to perform validation on the form as a whole (considering multiple)
947
+	 * you would be best to override this _validate method,
948
+	 * calling parent::_validate() first.
949
+	 *
950
+	 * @throws EE_Error
951
+	 */
952
+	protected function _validate()
953
+	{
954
+		//reset the cache of whether this form is valid or not- we're re-validating it now
955
+		$this->is_valid = null;
956
+		foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
957
+			if (method_exists($this, '_validate_' . $subsection_name)) {
958
+				call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection));
959
+			}
960
+			$subsection->_validate();
961
+		}
962
+	}
963
+
964
+
965
+	/**
966
+	 * Gets all the validated inputs for the form section
967
+	 *
968
+	 * @return array
969
+	 * @throws EE_Error
970
+	 */
971
+	public function valid_data()
972
+	{
973
+		$inputs = array();
974
+		foreach ($this->subsections() as $subsection_name => $subsection) {
975
+			if ($subsection instanceof EE_Form_Section_Proper) {
976
+				$inputs[ $subsection_name ] = $subsection->valid_data();
977
+			} elseif ($subsection instanceof EE_Form_Input_Base) {
978
+				$inputs[ $subsection_name ] = $subsection->normalized_value();
979
+			}
980
+		}
981
+		return $inputs;
982
+	}
983
+
984
+
985
+	/**
986
+	 * Gets all the inputs on this form section
987
+	 *
988
+	 * @return EE_Form_Input_Base[]
989
+	 * @throws EE_Error
990
+	 */
991
+	public function inputs()
992
+	{
993
+		$inputs = array();
994
+		foreach ($this->subsections() as $subsection_name => $subsection) {
995
+			if ($subsection instanceof EE_Form_Input_Base) {
996
+				$inputs[ $subsection_name ] = $subsection;
997
+			}
998
+		}
999
+		return $inputs;
1000
+	}
1001
+
1002
+
1003
+	/**
1004
+	 * Gets all the subsections which are a proper form
1005
+	 *
1006
+	 * @return EE_Form_Section_Proper[]
1007
+	 * @throws EE_Error
1008
+	 */
1009
+	public function subforms()
1010
+	{
1011
+		$form_sections = array();
1012
+		foreach ($this->subsections() as $name => $obj) {
1013
+			if ($obj instanceof EE_Form_Section_Proper) {
1014
+				$form_sections[ $name ] = $obj;
1015
+			}
1016
+		}
1017
+		return $form_sections;
1018
+	}
1019
+
1020
+
1021
+	/**
1022
+	 * Gets all the subsections (inputs, proper subsections, or html-only sections).
1023
+	 * Consider using inputs() or subforms()
1024
+	 * if you only want form inputs or proper form sections.
1025
+	 *
1026
+	 * @param boolean $require_construction_to_be_finalized most client code should
1027
+	 *                                                      leave this as TRUE so that the inputs will be properly
1028
+	 *                                                      configured. However, some client code may be ok with
1029
+	 *                                                      construction finalize being called later
1030
+	 *                                                      (realizing that the subsections' html names might not be
1031
+	 *                                                      set yet, etc.)
1032
+	 * @return EE_Form_Section_Proper[]
1033
+	 * @throws EE_Error
1034
+	 */
1035
+	public function subsections($require_construction_to_be_finalized = true)
1036
+	{
1037
+		if ($require_construction_to_be_finalized) {
1038
+			$this->ensure_construct_finalized_called();
1039
+		}
1040
+		return $this->_subsections;
1041
+	}
1042
+
1043
+
1044
+	/**
1045
+	 * Returns whether this form has any subforms or inputs
1046
+	 * @return bool
1047
+	 */
1048
+	public function hasSubsections()
1049
+	{
1050
+		return ! empty($this->_subsections);
1051
+	}
1052
+
1053
+
1054
+	/**
1055
+	 * Returns a simple array where keys are input names, and values are their normalized
1056
+	 * values. (Similar to calling get_input_value on inputs)
1057
+	 *
1058
+	 * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1059
+	 *                                        or just this forms' direct children inputs
1060
+	 * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1061
+	 *                                        or allow multidimensional array
1062
+	 * @return array if $flatten is TRUE it will always be a 1-dimensional array
1063
+	 *                                        with array keys being input names
1064
+	 *                                        (regardless of whether they are from a subsection or not),
1065
+	 *                                        and if $flatten is FALSE it can be a multidimensional array
1066
+	 *                                        where keys are always subsection names and values are either
1067
+	 *                                        the input's normalized value, or an array like the top-level array
1068
+	 * @throws EE_Error
1069
+	 */
1070
+	public function input_values($include_subform_inputs = false, $flatten = false)
1071
+	{
1072
+		return $this->_input_values(false, $include_subform_inputs, $flatten);
1073
+	}
1074
+
1075
+
1076
+	/**
1077
+	 * Similar to EE_Form_Section_Proper::input_values(), except this returns the 'display_value'
1078
+	 * of each input. On some inputs (especially radio boxes or checkboxes), the value stored
1079
+	 * is not necessarily the value we want to display to users. This creates an array
1080
+	 * where keys are the input names, and values are their display values
1081
+	 *
1082
+	 * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1083
+	 *                                        or just this forms' direct children inputs
1084
+	 * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1085
+	 *                                        or allow multidimensional array
1086
+	 * @return array if $flatten is TRUE it will always be a 1-dimensional array
1087
+	 *                                        with array keys being input names
1088
+	 *                                        (regardless of whether they are from a subsection or not),
1089
+	 *                                        and if $flatten is FALSE it can be a multidimensional array
1090
+	 *                                        where keys are always subsection names and values are either
1091
+	 *                                        the input's normalized value, or an array like the top-level array
1092
+	 * @throws EE_Error
1093
+	 */
1094
+	public function input_pretty_values($include_subform_inputs = false, $flatten = false)
1095
+	{
1096
+		return $this->_input_values(true, $include_subform_inputs, $flatten);
1097
+	}
1098
+
1099
+
1100
+	/**
1101
+	 * Gets the input values from the form
1102
+	 *
1103
+	 * @param boolean $pretty                 Whether to retrieve the pretty value,
1104
+	 *                                        or just the normalized value
1105
+	 * @param boolean $include_subform_inputs Whether to include inputs from subforms,
1106
+	 *                                        or just this forms' direct children inputs
1107
+	 * @param boolean $flatten                Whether to force the results into 1-dimensional array,
1108
+	 *                                        or allow multidimensional array
1109
+	 * @return array if $flatten is TRUE it will always be a 1-dimensional array with array keys being
1110
+	 *                                        input names (regardless of whether they are from a subsection or not),
1111
+	 *                                        and if $flatten is FALSE it can be a multidimensional array
1112
+	 *                                        where keys are always subsection names and values are either
1113
+	 *                                        the input's normalized value, or an array like the top-level array
1114
+	 * @throws EE_Error
1115
+	 */
1116
+	public function _input_values($pretty = false, $include_subform_inputs = false, $flatten = false)
1117
+	{
1118
+		$input_values = array();
1119
+		foreach ($this->subsections() as $subsection_name => $subsection) {
1120
+			if ($subsection instanceof EE_Form_Input_Base) {
1121
+				$input_values[ $subsection_name ] = $pretty
1122
+					? $subsection->pretty_value()
1123
+					: $subsection->normalized_value();
1124
+			} elseif ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) {
1125
+				$subform_input_values = $subsection->_input_values(
1126
+					$pretty,
1127
+					$include_subform_inputs,
1128
+					$flatten
1129
+				);
1130
+				if ($flatten) {
1131
+					$input_values = array_merge($input_values, $subform_input_values);
1132
+				} else {
1133
+					$input_values[ $subsection_name ] = $subform_input_values;
1134
+				}
1135
+			}
1136
+		}
1137
+		return $input_values;
1138
+	}
1139
+
1140
+
1141
+	/**
1142
+	 * Gets the originally submitted input values from the form
1143
+	 *
1144
+	 * @param boolean $include_subforms  Whether to include inputs from subforms,
1145
+	 *                                   or just this forms' direct children inputs
1146
+	 * @return array                     if $flatten is TRUE it will always be a 1-dimensional array
1147
+	 *                                   with array keys being input names
1148
+	 *                                   (regardless of whether they are from a subsection or not),
1149
+	 *                                   and if $flatten is FALSE it can be a multidimensional array
1150
+	 *                                   where keys are always subsection names and values are either
1151
+	 *                                   the input's normalized value, or an array like the top-level array
1152
+	 * @throws EE_Error
1153
+	 */
1154
+	public function submitted_values($include_subforms = false)
1155
+	{
1156
+		$submitted_values = array();
1157
+		foreach ($this->subsections() as $subsection) {
1158
+			if ($subsection instanceof EE_Form_Input_Base) {
1159
+				// is this input part of an array of inputs?
1160
+				if (strpos($subsection->html_name(), '[') !== false) {
1161
+					$full_input_name  = EEH_Array::convert_array_values_to_keys(
1162
+						explode(
1163
+							'[',
1164
+							str_replace(']', '', $subsection->html_name())
1165
+						),
1166
+						$subsection->raw_value()
1167
+					);
1168
+					$submitted_values = array_replace_recursive($submitted_values, $full_input_name);
1169
+				} else {
1170
+					$submitted_values[ $subsection->html_name() ] = $subsection->raw_value();
1171
+				}
1172
+			} elseif ($subsection instanceof EE_Form_Section_Proper && $include_subforms) {
1173
+				$subform_input_values = $subsection->submitted_values($include_subforms);
1174
+				$submitted_values     = array_replace_recursive($submitted_values, $subform_input_values);
1175
+			}
1176
+		}
1177
+		return $submitted_values;
1178
+	}
1179
+
1180
+
1181
+	/**
1182
+	 * Indicates whether or not this form has received a submission yet
1183
+	 * (ie, had receive_form_submission called on it yet)
1184
+	 *
1185
+	 * @return boolean
1186
+	 * @throws EE_Error
1187
+	 */
1188
+	public function has_received_submission()
1189
+	{
1190
+		$this->ensure_construct_finalized_called();
1191
+		return $this->_received_submission;
1192
+	}
1193
+
1194
+
1195
+	/**
1196
+	 * Equivalent to passing 'exclude' in the constructor's options array.
1197
+	 * Removes the listed inputs from the form
1198
+	 *
1199
+	 * @param array $inputs_to_exclude values are the input names
1200
+	 * @return void
1201
+	 */
1202
+	public function exclude(array $inputs_to_exclude = array())
1203
+	{
1204
+		foreach ($inputs_to_exclude as $input_to_exclude_name) {
1205
+			unset($this->_subsections[ $input_to_exclude_name ]);
1206
+		}
1207
+	}
1208
+
1209
+
1210
+	/**
1211
+	 * Changes these inputs' display strategy to be EE_Hidden_Display_Strategy.
1212
+	 * @param array $inputs_to_hide
1213
+	 * @throws EE_Error
1214
+	 */
1215
+	public function hide(array $inputs_to_hide = array())
1216
+	{
1217
+		foreach ($inputs_to_hide as $input_to_hide) {
1218
+			$input = $this->get_input($input_to_hide);
1219
+			$input->set_display_strategy(new EE_Hidden_Display_Strategy());
1220
+		}
1221
+	}
1222
+
1223
+
1224
+	/**
1225
+	 * add_subsections
1226
+	 * Adds the listed subsections to the form section.
1227
+	 * If $subsection_name_to_target is provided,
1228
+	 * then new subsections are added before or after that subsection,
1229
+	 * otherwise to the start or end of the entire subsections array.
1230
+	 *
1231
+	 * @param EE_Form_Section_Base[] $new_subsections           array of new form subsections
1232
+	 *                                                          where keys are their names
1233
+	 * @param string                 $subsection_name_to_target an existing for section that $new_subsections
1234
+	 *                                                          should be added before or after
1235
+	 *                                                          IF $subsection_name_to_target is null,
1236
+	 *                                                          then $new_subsections will be added to
1237
+	 *                                                          the beginning or end of the entire subsections array
1238
+	 * @param boolean                $add_before                whether to add $new_subsections, before or after
1239
+	 *                                                          $subsection_name_to_target,
1240
+	 *                                                          or if $subsection_name_to_target is null,
1241
+	 *                                                          before or after entire subsections array
1242
+	 * @return void
1243
+	 * @throws EE_Error
1244
+	 */
1245
+	public function add_subsections($new_subsections, $subsection_name_to_target = null, $add_before = true)
1246
+	{
1247
+		foreach ($new_subsections as $subsection_name => $subsection) {
1248
+			if (! $subsection instanceof EE_Form_Section_Base) {
1249
+				EE_Error::add_error(
1250
+					sprintf(
1251
+						esc_html__(
1252
+							"Trying to add a %s as a subsection (it was named '%s') to the form section '%s'. It was removed.",
1253
+							'event_espresso'
1254
+						),
1255
+						get_class($subsection),
1256
+						$subsection_name,
1257
+						$this->name()
1258
+					)
1259
+				);
1260
+				unset($new_subsections[ $subsection_name ]);
1261
+			}
1262
+		}
1263
+		$this->_subsections = EEH_Array::insert_into_array(
1264
+			$this->_subsections,
1265
+			$new_subsections,
1266
+			$subsection_name_to_target,
1267
+			$add_before
1268
+		);
1269
+		if ($this->_construction_finalized) {
1270
+			foreach ($this->_subsections as $name => $subsection) {
1271
+				$subsection->_construct_finalize($this, $name);
1272
+			}
1273
+		}
1274
+	}
1275
+
1276
+
1277
+	/**
1278
+	 * Just gets all validatable subsections to clean their sensitive data
1279
+	 *
1280
+	 * @throws EE_Error
1281
+	 */
1282
+	public function clean_sensitive_data()
1283
+	{
1284
+		foreach ($this->get_validatable_subsections() as $subsection) {
1285
+			$subsection->clean_sensitive_data();
1286
+		}
1287
+	}
1288
+
1289
+
1290
+	/**
1291
+	 * Sets the submission error message (aka validation error message for this form section and all sub-sections)
1292
+	 * @param string                           $form_submission_error_message
1293
+	 * @param EE_Form_Section_Validatable $form_section unused
1294
+	 * @throws EE_Error
1295
+	 */
1296
+	public function set_submission_error_message(
1297
+		$form_submission_error_message = ''
1298
+	) {
1299
+		$this->_form_submission_error_message = ! empty($form_submission_error_message)
1300
+			? $form_submission_error_message
1301
+			: $this->getAllValidationErrorsString();
1302
+	}
1303
+
1304
+
1305
+	/**
1306
+	 * Returns the cached error message. A default value is set for this during _validate(),
1307
+	 * (called during receive_form_submission) but it can be explicitly set using
1308
+	 * set_submission_error_message
1309
+	 *
1310
+	 * @return string
1311
+	 */
1312
+	public function submission_error_message()
1313
+	{
1314
+		return $this->_form_submission_error_message;
1315
+	}
1316
+
1317
+
1318
+	/**
1319
+	 * Sets a message to display if the data submitted to the form was valid.
1320
+	 * @param string $form_submission_success_message
1321
+	 */
1322
+	public function set_submission_success_message($form_submission_success_message = '')
1323
+	{
1324
+		$this->_form_submission_success_message = ! empty($form_submission_success_message)
1325
+			? $form_submission_success_message
1326
+			: esc_html__('Form submitted successfully', 'event_espresso');
1327
+	}
1328
+
1329
+
1330
+	/**
1331
+	 * Gets a message appropriate for display when the form is correctly submitted
1332
+	 * @return string
1333
+	 */
1334
+	public function submission_success_message()
1335
+	{
1336
+		return $this->_form_submission_success_message;
1337
+	}
1338
+
1339
+
1340
+	/**
1341
+	 * Returns the prefix that should be used on child of this form section for
1342
+	 * their html names. If this form section itself has a parent, prepends ITS
1343
+	 * prefix onto this form section's prefix. Used primarily by
1344
+	 * EE_Form_Input_Base::_set_default_html_name_if_empty
1345
+	 *
1346
+	 * @return string
1347
+	 * @throws EE_Error
1348
+	 */
1349
+	public function html_name_prefix()
1350
+	{
1351
+		if ($this->parent_section() instanceof EE_Form_Section_Proper) {
1352
+			return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']';
1353
+		}
1354
+		return $this->name();
1355
+	}
1356
+
1357
+
1358
+	/**
1359
+	 * Gets the name, but first checks _construct_finalize has been called. If not,
1360
+	 * calls it (assumes there is no parent and that we want the name to be whatever
1361
+	 * was set, which is probably nothing, or the classname)
1362
+	 *
1363
+	 * @return string
1364
+	 * @throws EE_Error
1365
+	 */
1366
+	public function name()
1367
+	{
1368
+		$this->ensure_construct_finalized_called();
1369
+		return parent::name();
1370
+	}
1371
+
1372
+
1373
+	/**
1374
+	 * @return EE_Form_Section_Proper
1375
+	 * @throws EE_Error
1376
+	 */
1377
+	public function parent_section()
1378
+	{
1379
+		$this->ensure_construct_finalized_called();
1380
+		return parent::parent_section();
1381
+	}
1382
+
1383
+
1384
+	/**
1385
+	 * make sure construction finalized was called, otherwise children might not be ready
1386
+	 *
1387
+	 * @return void
1388
+	 * @throws EE_Error
1389
+	 */
1390
+	public function ensure_construct_finalized_called()
1391
+	{
1392
+		if (! $this->_construction_finalized) {
1393
+			$this->_construct_finalize($this->_parent_section, $this->_name);
1394
+		}
1395
+	}
1396
+
1397
+
1398
+	/**
1399
+	 * Checks if any of this form section's inputs, or any of its children's inputs,
1400
+	 * are in teh form data. If any are found, returns true. Else false
1401
+	 *
1402
+	 * @param array $req_data
1403
+	 * @return boolean
1404
+	 * @throws EE_Error
1405
+	 */
1406
+	public function form_data_present_in($req_data = null)
1407
+	{
1408
+		$req_data = $this->getCachedRequest($req_data);
1409
+		foreach ($this->subsections() as $subsection) {
1410
+			if ($subsection instanceof EE_Form_Input_Base) {
1411
+				if ($subsection->form_data_present_in($req_data)) {
1412
+					return true;
1413
+				}
1414
+			} elseif ($subsection instanceof EE_Form_Section_Proper) {
1415
+				if ($subsection->form_data_present_in($req_data)) {
1416
+					return true;
1417
+				}
1418
+			}
1419
+		}
1420
+		return false;
1421
+	}
1422
+
1423
+
1424
+	/**
1425
+	 * Gets validation errors for this form section and subsections
1426
+	 * Similar to EE_Form_Section_Validatable::get_validation_errors() except this
1427
+	 * gets the validation errors for ALL subsection
1428
+	 *
1429
+	 * @return EE_Validation_Error[]
1430
+	 * @throws EE_Error
1431
+	 */
1432
+	public function get_validation_errors_accumulated()
1433
+	{
1434
+		$validation_errors = $this->get_validation_errors();
1435
+		foreach ($this->get_validatable_subsections() as $subsection) {
1436
+			if ($subsection instanceof EE_Form_Section_Proper) {
1437
+				$validation_errors_on_this_subsection = $subsection->get_validation_errors_accumulated();
1438
+			} else {
1439
+				$validation_errors_on_this_subsection = $subsection->get_validation_errors();
1440
+			}
1441
+			if ($validation_errors_on_this_subsection) {
1442
+				$validation_errors = array_merge($validation_errors, $validation_errors_on_this_subsection);
1443
+			}
1444
+		}
1445
+		return $validation_errors;
1446
+	}
1447
+
1448
+	/**
1449
+	 * Fetch validation errors from children and grandchildren and puts them in a single string.
1450
+	 * This traverses the form section tree to generate this, but you probably want to instead use
1451
+	 * get_form_submission_error_message() which is usually this message cached (or a custom validation error message)
1452
+	 *
1453
+	 * @return string
1454
+	 * @since $VID:$
1455
+	 */
1456
+	protected function getAllValidationErrorsString()
1457
+	{
1458
+		$submission_error_messages = array();
1459
+		// bad, bad, bad registrant
1460
+		foreach ($this->get_validation_errors_accumulated() as $validation_error) {
1461
+			if ($validation_error instanceof EE_Validation_Error) {
1462
+				$form_section = $validation_error->get_form_section();
1463
+				if ($form_section instanceof EE_Form_Input_Base) {
1464
+				   $label = $validation_error->get_form_section()->html_label_text();
1465
+				} elseif($form_section instanceof EE_Form_Section_Validatable) {
1466
+					$label = $validation_error->get_form_section()->name();
1467
+				} else {
1468
+					$label = esc_html__('Unknown', 'event_espresso');
1469
+				}
1470
+				$submission_error_messages[] = sprintf(
1471
+					__('%s : %s', 'event_espresso'),
1472
+					$label,
1473
+					$validation_error->getMessage()
1474
+				);
1475
+			}
1476
+		}
1477
+		return implode('<br', $submission_error_messages);
1478
+	}
1479
+
1480
+
1481
+	/**
1482
+	 * This isn't just the name of an input, it's a path pointing to an input. The
1483
+	 * path is similar to a folder path: slash (/) means to descend into a subsection,
1484
+	 * dot-dot-slash (../) means to ascend into the parent section.
1485
+	 * After a series of slashes and dot-dot-slashes, there should be the name of an input,
1486
+	 * which will be returned.
1487
+	 * Eg, if you want the related input to be conditional on a sibling input name 'foobar'
1488
+	 * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name
1489
+	 * 'baz', use '../baz'. If you want it to be conditional on a cousin input,
1490
+	 * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'.
1491
+	 * Etc
1492
+	 *
1493
+	 * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false
1494
+	 * @return EE_Form_Section_Base
1495
+	 * @throws EE_Error
1496
+	 */
1497
+	public function find_section_from_path($form_section_path)
1498
+	{
1499
+		//check if we can find the input from purely going straight up the tree
1500
+		$input = parent::find_section_from_path($form_section_path);
1501
+		if ($input instanceof EE_Form_Section_Base) {
1502
+			return $input;
1503
+		}
1504
+		$next_slash_pos = strpos($form_section_path, '/');
1505
+		if ($next_slash_pos !== false) {
1506
+			$child_section_name = substr($form_section_path, 0, $next_slash_pos);
1507
+			$subpath            = substr($form_section_path, $next_slash_pos + 1);
1508
+		} else {
1509
+			$child_section_name = $form_section_path;
1510
+			$subpath            = '';
1511
+		}
1512
+		$child_section = $this->get_subsection($child_section_name);
1513
+		if ($child_section instanceof EE_Form_Section_Base) {
1514
+			return $child_section->find_section_from_path($subpath);
1515
+		}
1516
+		return null;
1517
+	}
1518 1518
 }
1519 1519
 
Please login to merge, or discard this patch.
core/services/assets/Registry.php 1 patch
Indentation   +449 added lines, -449 removed lines patch added patch discarded remove patch
@@ -24,459 +24,459 @@
 block discarded – undo
24 24
 class Registry
25 25
 {
26 26
 
27
-    /**
28
-     * @var EE_Template_Config $template_config
29
-     */
30
-    protected $template_config;
31
-
32
-    /**
33
-     * @var EE_Currency_Config $currency_config
34
-     */
35
-    protected $currency_config;
36
-
37
-    /**
38
-     * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script.
39
-     *
40
-     * @var array
41
-     */
42
-    protected $jsdata = array();
43
-
44
-
45
-    /**
46
-     * This keeps track of all scripts with registered data.  It is used to prevent duplicate data objects setup in the
47
-     * page source.
48
-     * @var array
49
-     */
50
-    protected $script_handles_with_data = array();
51
-
52
-
53
-    /**
54
-     * @var DomainInterface
55
-     */
56
-    protected $domain;
57
-
58
-
59
-    /**
60
-     * Registry constructor.
61
-     * Hooking into WP actions for script registry.
62
-     *
63
-     * @param EE_Template_Config $template_config
64
-     * @param EE_Currency_Config $currency_config
65
-     * @param DomainInterface    $domain
66
-     */
67
-    public function __construct(
68
-        EE_Template_Config $template_config,
69
-        EE_Currency_Config $currency_config,
70
-        DomainInterface $domain
71
-    ) {
72
-        $this->template_config = $template_config;
73
-        $this->currency_config = $currency_config;
74
-        $this->domain = $domain;
75
-        add_action('wp_enqueue_scripts', array($this, 'scripts'), 1);
76
-        add_action('admin_enqueue_scripts', array($this, 'scripts'), 1);
77
-        add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 2);
78
-        add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 2);
79
-        add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1);
80
-        add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1);
81
-    }
82
-
83
-
84
-
85
-    /**
86
-     * Callback for the WP script actions.
87
-     * Used to register globally accessible core scripts.
88
-     * Also used to add the eejs.data object to the source for any js having eejs-core as a dependency.
89
-     */
90
-    public function scripts()
91
-    {
92
-        global $wp_version;
93
-        wp_register_script(
94
-            'eejs-core',
95
-            EE_PLUGIN_DIR_URL . 'core/services/assets/core_assets/eejs-core.js',
96
-            array(),
97
-            EVENT_ESPRESSO_VERSION,
98
-            true
99
-        );
100
-        //only run this if WordPress 4.4.0 > is in use.
101
-        if (version_compare($wp_version, '4.4.0', '>')) {
102
-            //js.api
103
-            wp_register_script(
104
-                'eejs-api',
105
-                EE_LIBRARIES_URL . 'rest_api/assets/js/eejs-api.min.js',
106
-                array('underscore', 'eejs-core'),
107
-                EVENT_ESPRESSO_VERSION,
108
-                true
109
-            );
110
-            $this->jsdata['eejs_api_nonce'] = wp_create_nonce('wp_rest');
111
-            $this->jsdata['paths'] = array('rest_route' => rest_url('ee/v4.8.36/'));
112
-        }
113
-        if (! is_admin()) {
114
-            $this->loadCoreCss();
115
-        }
116
-        $this->loadCoreJs();
117
-        $this->loadJqueryValidate();
118
-        $this->loadAccountingJs();
119
-        $this->loadQtipJs();
120
-    }
121
-
122
-
123
-
124
-    /**
125
-     * Call back for the script print in frontend and backend.
126
-     * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point.
127
-     *
128
-     * @since 4.9.31.rc.015
129
-     */
130
-    public function enqueueData()
131
-    {
132
-        $this->removeAlreadyRegisteredDataForScriptHandles();
133
-        wp_localize_script('eejs-core', 'eejs', array('data' => $this->jsdata));
134
-        wp_localize_script('espresso_core', 'eei18n', EE_Registry::$i18n_js_strings);
135
-        $this->localizeAccountingJs();
136
-        $this->addRegisteredScriptHandlesWithData('eejs-core');
137
-        $this->addRegisteredScriptHandlesWithData('espresso_core');
138
-    }
139
-
140
-
141
-
142
-    /**
143
-     * Used to add data to eejs.data object.
144
-     * Note:  Overriding existing data is not allowed.
145
-     * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript.
146
-     * If the data you add is something like this:
147
-     *  $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) );
148
-     * It will be exposed in the page source as:
149
-     *  eejs.data.my_plugin_data.foo == gar
150
-     *
151
-     * @param string       $key   Key used to access your data
152
-     * @param string|array $value Value to attach to key
153
-     * @throws InvalidArgumentException
154
-     */
155
-    public function addData($key, $value)
156
-    {
157
-        if ($this->verifyDataNotExisting($key)) {
158
-            $this->jsdata[$key] = $value;
159
-        }
160
-    }
161
-
162
-
163
-
164
-    /**
165
-     * Similar to addData except this allows for users to push values to an existing key where the values on key are
166
-     * elements in an array.
167
-     * When you use this method, the value you include will be appended to the end of an array on $key.
168
-     * So if the $key was 'test' and you added a value of 'my_data' then it would be represented in the javascript
169
-     * object like this, eejs.data.test = [ my_data,
170
-     * ]
171
-     * If there has already been a scalar value attached to the data object given key, then
172
-     * this will throw an exception.
173
-     *
174
-     * @param string       $key   Key to attach data to.
175
-     * @param string|array $value Value being registered.
176
-     * @throws InvalidArgumentException
177
-     */
178
-    public function pushData($key, $value)
179
-    {
180
-        if (isset($this->jsdata[$key])
181
-            && ! is_array($this->jsdata[$key])
182
-        ) {
183
-            throw new invalidArgumentException(
184
-                sprintf(
185
-                    __(
186
-                        'The value for %1$s is already set and it is not an array. The %2$s method can only be used to
27
+	/**
28
+	 * @var EE_Template_Config $template_config
29
+	 */
30
+	protected $template_config;
31
+
32
+	/**
33
+	 * @var EE_Currency_Config $currency_config
34
+	 */
35
+	protected $currency_config;
36
+
37
+	/**
38
+	 * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script.
39
+	 *
40
+	 * @var array
41
+	 */
42
+	protected $jsdata = array();
43
+
44
+
45
+	/**
46
+	 * This keeps track of all scripts with registered data.  It is used to prevent duplicate data objects setup in the
47
+	 * page source.
48
+	 * @var array
49
+	 */
50
+	protected $script_handles_with_data = array();
51
+
52
+
53
+	/**
54
+	 * @var DomainInterface
55
+	 */
56
+	protected $domain;
57
+
58
+
59
+	/**
60
+	 * Registry constructor.
61
+	 * Hooking into WP actions for script registry.
62
+	 *
63
+	 * @param EE_Template_Config $template_config
64
+	 * @param EE_Currency_Config $currency_config
65
+	 * @param DomainInterface    $domain
66
+	 */
67
+	public function __construct(
68
+		EE_Template_Config $template_config,
69
+		EE_Currency_Config $currency_config,
70
+		DomainInterface $domain
71
+	) {
72
+		$this->template_config = $template_config;
73
+		$this->currency_config = $currency_config;
74
+		$this->domain = $domain;
75
+		add_action('wp_enqueue_scripts', array($this, 'scripts'), 1);
76
+		add_action('admin_enqueue_scripts', array($this, 'scripts'), 1);
77
+		add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 2);
78
+		add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 2);
79
+		add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1);
80
+		add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1);
81
+	}
82
+
83
+
84
+
85
+	/**
86
+	 * Callback for the WP script actions.
87
+	 * Used to register globally accessible core scripts.
88
+	 * Also used to add the eejs.data object to the source for any js having eejs-core as a dependency.
89
+	 */
90
+	public function scripts()
91
+	{
92
+		global $wp_version;
93
+		wp_register_script(
94
+			'eejs-core',
95
+			EE_PLUGIN_DIR_URL . 'core/services/assets/core_assets/eejs-core.js',
96
+			array(),
97
+			EVENT_ESPRESSO_VERSION,
98
+			true
99
+		);
100
+		//only run this if WordPress 4.4.0 > is in use.
101
+		if (version_compare($wp_version, '4.4.0', '>')) {
102
+			//js.api
103
+			wp_register_script(
104
+				'eejs-api',
105
+				EE_LIBRARIES_URL . 'rest_api/assets/js/eejs-api.min.js',
106
+				array('underscore', 'eejs-core'),
107
+				EVENT_ESPRESSO_VERSION,
108
+				true
109
+			);
110
+			$this->jsdata['eejs_api_nonce'] = wp_create_nonce('wp_rest');
111
+			$this->jsdata['paths'] = array('rest_route' => rest_url('ee/v4.8.36/'));
112
+		}
113
+		if (! is_admin()) {
114
+			$this->loadCoreCss();
115
+		}
116
+		$this->loadCoreJs();
117
+		$this->loadJqueryValidate();
118
+		$this->loadAccountingJs();
119
+		$this->loadQtipJs();
120
+	}
121
+
122
+
123
+
124
+	/**
125
+	 * Call back for the script print in frontend and backend.
126
+	 * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point.
127
+	 *
128
+	 * @since 4.9.31.rc.015
129
+	 */
130
+	public function enqueueData()
131
+	{
132
+		$this->removeAlreadyRegisteredDataForScriptHandles();
133
+		wp_localize_script('eejs-core', 'eejs', array('data' => $this->jsdata));
134
+		wp_localize_script('espresso_core', 'eei18n', EE_Registry::$i18n_js_strings);
135
+		$this->localizeAccountingJs();
136
+		$this->addRegisteredScriptHandlesWithData('eejs-core');
137
+		$this->addRegisteredScriptHandlesWithData('espresso_core');
138
+	}
139
+
140
+
141
+
142
+	/**
143
+	 * Used to add data to eejs.data object.
144
+	 * Note:  Overriding existing data is not allowed.
145
+	 * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript.
146
+	 * If the data you add is something like this:
147
+	 *  $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) );
148
+	 * It will be exposed in the page source as:
149
+	 *  eejs.data.my_plugin_data.foo == gar
150
+	 *
151
+	 * @param string       $key   Key used to access your data
152
+	 * @param string|array $value Value to attach to key
153
+	 * @throws InvalidArgumentException
154
+	 */
155
+	public function addData($key, $value)
156
+	{
157
+		if ($this->verifyDataNotExisting($key)) {
158
+			$this->jsdata[$key] = $value;
159
+		}
160
+	}
161
+
162
+
163
+
164
+	/**
165
+	 * Similar to addData except this allows for users to push values to an existing key where the values on key are
166
+	 * elements in an array.
167
+	 * When you use this method, the value you include will be appended to the end of an array on $key.
168
+	 * So if the $key was 'test' and you added a value of 'my_data' then it would be represented in the javascript
169
+	 * object like this, eejs.data.test = [ my_data,
170
+	 * ]
171
+	 * If there has already been a scalar value attached to the data object given key, then
172
+	 * this will throw an exception.
173
+	 *
174
+	 * @param string       $key   Key to attach data to.
175
+	 * @param string|array $value Value being registered.
176
+	 * @throws InvalidArgumentException
177
+	 */
178
+	public function pushData($key, $value)
179
+	{
180
+		if (isset($this->jsdata[$key])
181
+			&& ! is_array($this->jsdata[$key])
182
+		) {
183
+			throw new invalidArgumentException(
184
+				sprintf(
185
+					__(
186
+						'The value for %1$s is already set and it is not an array. The %2$s method can only be used to
187 187
                          push values to this data element when it is an array.',
188
-                        'event_espresso'
189
-                    ),
190
-                    $key,
191
-                    __METHOD__
192
-                )
193
-            );
194
-        }
195
-        $this->jsdata[$key][] = $value;
196
-    }
197
-
198
-
199
-
200
-    /**
201
-     * Used to set content used by javascript for a template.
202
-     * Note: Overrides of existing registered templates are not allowed.
203
-     *
204
-     * @param string $template_reference
205
-     * @param string $template_content
206
-     * @throws InvalidArgumentException
207
-     */
208
-    public function addTemplate($template_reference, $template_content)
209
-    {
210
-        if (! isset($this->jsdata['templates'])) {
211
-            $this->jsdata['templates'] = array();
212
-        }
213
-        //no overrides allowed.
214
-        if (isset($this->jsdata['templates'][$template_reference])) {
215
-            throw new invalidArgumentException(
216
-                sprintf(
217
-                    __(
218
-                        'The %1$s key already exists for the templates array in the js data array.  No overrides are allowed.',
219
-                        'event_espresso'
220
-                    ),
221
-                    $template_reference
222
-                )
223
-            );
224
-        }
225
-        $this->jsdata['templates'][$template_reference] = $template_content;
226
-    }
227
-
228
-
229
-
230
-    /**
231
-     * Retrieve the template content already registered for the given reference.
232
-     *
233
-     * @param string $template_reference
234
-     * @return string
235
-     */
236
-    public function getTemplate($template_reference)
237
-    {
238
-        return isset($this->jsdata['templates'], $this->jsdata['templates'][$template_reference])
239
-            ? $this->jsdata['templates'][$template_reference]
240
-            : '';
241
-    }
242
-
243
-
244
-
245
-    /**
246
-     * Retrieve registered data.
247
-     *
248
-     * @param string $key Name of key to attach data to.
249
-     * @return mixed                If there is no for the given key, then false is returned.
250
-     */
251
-    public function getData($key)
252
-    {
253
-        return isset($this->jsdata[$key])
254
-            ? $this->jsdata[$key]
255
-            : false;
256
-    }
257
-
258
-
259
-
260
-    /**
261
-     * Verifies whether the given data exists already on the jsdata array.
262
-     * Overriding data is not allowed.
263
-     *
264
-     * @param string $key Index for data.
265
-     * @return bool        If valid then return true.
266
-     * @throws InvalidArgumentException if data already exists.
267
-     */
268
-    protected function verifyDataNotExisting($key)
269
-    {
270
-        if (isset($this->jsdata[$key])) {
271
-            if (is_array($this->jsdata[$key])) {
272
-                throw new InvalidArgumentException(
273
-                    sprintf(
274
-                        __(
275
-                            'The value for %1$s already exists in the Registry::eejs object.
188
+						'event_espresso'
189
+					),
190
+					$key,
191
+					__METHOD__
192
+				)
193
+			);
194
+		}
195
+		$this->jsdata[$key][] = $value;
196
+	}
197
+
198
+
199
+
200
+	/**
201
+	 * Used to set content used by javascript for a template.
202
+	 * Note: Overrides of existing registered templates are not allowed.
203
+	 *
204
+	 * @param string $template_reference
205
+	 * @param string $template_content
206
+	 * @throws InvalidArgumentException
207
+	 */
208
+	public function addTemplate($template_reference, $template_content)
209
+	{
210
+		if (! isset($this->jsdata['templates'])) {
211
+			$this->jsdata['templates'] = array();
212
+		}
213
+		//no overrides allowed.
214
+		if (isset($this->jsdata['templates'][$template_reference])) {
215
+			throw new invalidArgumentException(
216
+				sprintf(
217
+					__(
218
+						'The %1$s key already exists for the templates array in the js data array.  No overrides are allowed.',
219
+						'event_espresso'
220
+					),
221
+					$template_reference
222
+				)
223
+			);
224
+		}
225
+		$this->jsdata['templates'][$template_reference] = $template_content;
226
+	}
227
+
228
+
229
+
230
+	/**
231
+	 * Retrieve the template content already registered for the given reference.
232
+	 *
233
+	 * @param string $template_reference
234
+	 * @return string
235
+	 */
236
+	public function getTemplate($template_reference)
237
+	{
238
+		return isset($this->jsdata['templates'], $this->jsdata['templates'][$template_reference])
239
+			? $this->jsdata['templates'][$template_reference]
240
+			: '';
241
+	}
242
+
243
+
244
+
245
+	/**
246
+	 * Retrieve registered data.
247
+	 *
248
+	 * @param string $key Name of key to attach data to.
249
+	 * @return mixed                If there is no for the given key, then false is returned.
250
+	 */
251
+	public function getData($key)
252
+	{
253
+		return isset($this->jsdata[$key])
254
+			? $this->jsdata[$key]
255
+			: false;
256
+	}
257
+
258
+
259
+
260
+	/**
261
+	 * Verifies whether the given data exists already on the jsdata array.
262
+	 * Overriding data is not allowed.
263
+	 *
264
+	 * @param string $key Index for data.
265
+	 * @return bool        If valid then return true.
266
+	 * @throws InvalidArgumentException if data already exists.
267
+	 */
268
+	protected function verifyDataNotExisting($key)
269
+	{
270
+		if (isset($this->jsdata[$key])) {
271
+			if (is_array($this->jsdata[$key])) {
272
+				throw new InvalidArgumentException(
273
+					sprintf(
274
+						__(
275
+							'The value for %1$s already exists in the Registry::eejs object.
276 276
                             Overrides are not allowed. Since the value of this data is an array, you may want to use the
277 277
                             %2$s method to push your value to the array.',
278
-                            'event_espresso'
279
-                        ),
280
-                        $key,
281
-                        'pushData()'
282
-                    )
283
-                );
284
-            }
285
-            throw new InvalidArgumentException(
286
-                sprintf(
287
-                    __(
288
-                        'The value for %1$s already exists in the Registry::eejs object. Overrides are not
278
+							'event_espresso'
279
+						),
280
+						$key,
281
+						'pushData()'
282
+					)
283
+				);
284
+			}
285
+			throw new InvalidArgumentException(
286
+				sprintf(
287
+					__(
288
+						'The value for %1$s already exists in the Registry::eejs object. Overrides are not
289 289
                         allowed.  Consider attaching your value to a different key',
290
-                        'event_espresso'
291
-                    ),
292
-                    $key
293
-                )
294
-            );
295
-        }
296
-        return true;
297
-    }
298
-
299
-
300
-
301
-    /**
302
-     * registers core default stylesheets
303
-     */
304
-    private function loadCoreCss()
305
-    {
306
-        if ($this->template_config->enable_default_style) {
307
-            $default_stylesheet_path = is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
308
-                ? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css'
309
-                : EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css';
310
-            wp_register_style(
311
-                'espresso_default',
312
-                $default_stylesheet_path,
313
-                array('dashicons'),
314
-                EVENT_ESPRESSO_VERSION
315
-            );
316
-            //Load custom style sheet if available
317
-            if ($this->template_config->custom_style_sheet !== null) {
318
-                wp_register_style(
319
-                    'espresso_custom_css',
320
-                    EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
321
-                    array('espresso_default'),
322
-                    EVENT_ESPRESSO_VERSION
323
-                );
324
-            }
325
-        }
326
-    }
327
-
328
-
329
-
330
-    /**
331
-     * registers core default javascript
332
-     */
333
-    private function loadCoreJs()
334
-    {
335
-        // load core js
336
-        wp_register_script(
337
-            'espresso_core',
338
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
339
-            array('jquery'),
340
-            EVENT_ESPRESSO_VERSION,
341
-            true
342
-        );
343
-    }
344
-
345
-
346
-
347
-    /**
348
-     * registers jQuery Validate for form validation
349
-     */
350
-    private function loadJqueryValidate()
351
-    {
352
-        // register jQuery Validate and additional methods
353
-        wp_register_script(
354
-            'jquery-validate',
355
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
356
-            array('jquery'),
357
-            '1.15.0',
358
-            true
359
-        );
360
-        wp_register_script(
361
-            'jquery-validate-extra-methods',
362
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
363
-            array('jquery', 'jquery-validate'),
364
-            '1.15.0',
365
-            true
366
-        );
367
-    }
368
-
369
-
370
-
371
-    /**
372
-     * registers accounting.js for performing client-side calculations
373
-     */
374
-    private function loadAccountingJs()
375
-    {
376
-        //accounting.js library
377
-        // @link http://josscrowcroft.github.io/accounting.js/
378
-        wp_register_script(
379
-            'ee-accounting-core',
380
-            EE_THIRD_PARTY_URL . 'accounting/accounting.js',
381
-            array('underscore'),
382
-            '0.3.2',
383
-            true
384
-        );
385
-        wp_register_script(
386
-            'ee-accounting',
387
-            EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js',
388
-            array('ee-accounting-core'),
389
-            EVENT_ESPRESSO_VERSION,
390
-            true
391
-        );
392
-    }
393
-
394
-
395
-
396
-    /**
397
-     * registers accounting.js for performing client-side calculations
398
-     */
399
-    private function localizeAccountingJs()
400
-    {
401
-        wp_localize_script(
402
-            'ee-accounting',
403
-            'EE_ACCOUNTING_CFG',
404
-            array(
405
-                'currency' => array(
406
-                    'symbol'    => $this->currency_config->sign,
407
-                    'format'    => array(
408
-                        'pos'  => $this->currency_config->sign_b4 ? '%s%v' : '%v%s',
409
-                        'neg'  => $this->currency_config->sign_b4 ? '- %s%v' : '- %v%s',
410
-                        'zero' => $this->currency_config->sign_b4 ? '%s--' : '--%s',
411
-                    ),
412
-                    'decimal'   => $this->currency_config->dec_mrk,
413
-                    'thousand'  => $this->currency_config->thsnds,
414
-                    'precision' => $this->currency_config->dec_plc,
415
-                ),
416
-                'number'   => array(
417
-                    'precision' => $this->currency_config->dec_plc,
418
-                    'thousand'  => $this->currency_config->thsnds,
419
-                    'decimal'   => $this->currency_config->dec_mrk,
420
-                ),
421
-            )
422
-        );
423
-        $this->addRegisteredScriptHandlesWithData('ee-accounting');
424
-    }
425
-
426
-
427
-
428
-    /**
429
-     * registers assets for cleaning your ears
430
-     */
431
-    private function loadQtipJs()
432
-    {
433
-        // qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook,
434
-        // can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' );
435
-        if (apply_filters('FHEE_load_qtip', false)) {
436
-            EEH_Qtip_Loader::instance()->register_and_enqueue();
437
-        }
438
-    }
439
-
440
-
441
-    /**
442
-     * This is used to set registered script handles that have data.
443
-     * @param string $script_handle
444
-     */
445
-    private function addRegisteredScriptHandlesWithData($script_handle)
446
-    {
447
-        $this->script_handles_with_data[$script_handle] = $script_handle;
448
-    }
449
-
450
-
451
-    /**
452
-     * Checks WP_Scripts for all of each script handle registered internally as having data and unsets from the
453
-     * Dependency stored in WP_Scripts if its set.
454
-     */
455
-    private function removeAlreadyRegisteredDataForScriptHandles()
456
-    {
457
-        if (empty($this->script_handles_with_data)) {
458
-            return;
459
-        }
460
-        foreach ($this->script_handles_with_data as $script_handle) {
461
-            $this->removeAlreadyRegisteredDataForScriptHandle($script_handle);
462
-        }
463
-    }
464
-
465
-
466
-    /**
467
-     * Removes any data dependency registered in WP_Scripts if its set.
468
-     * @param string $script_handle
469
-     */
470
-    private function removeAlreadyRegisteredDataForScriptHandle($script_handle)
471
-    {
472
-        if (isset($this->script_handles_with_data[$script_handle])) {
473
-            global $wp_scripts;
474
-            if ($wp_scripts->get_data($script_handle, 'data')) {
475
-                unset($wp_scripts->registered[$script_handle]->extra['data']);
476
-                unset($this->script_handles_with_data[$script_handle]);
477
-            }
478
-        }
479
-    }
290
+						'event_espresso'
291
+					),
292
+					$key
293
+				)
294
+			);
295
+		}
296
+		return true;
297
+	}
298
+
299
+
300
+
301
+	/**
302
+	 * registers core default stylesheets
303
+	 */
304
+	private function loadCoreCss()
305
+	{
306
+		if ($this->template_config->enable_default_style) {
307
+			$default_stylesheet_path = is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
308
+				? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css'
309
+				: EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css';
310
+			wp_register_style(
311
+				'espresso_default',
312
+				$default_stylesheet_path,
313
+				array('dashicons'),
314
+				EVENT_ESPRESSO_VERSION
315
+			);
316
+			//Load custom style sheet if available
317
+			if ($this->template_config->custom_style_sheet !== null) {
318
+				wp_register_style(
319
+					'espresso_custom_css',
320
+					EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
321
+					array('espresso_default'),
322
+					EVENT_ESPRESSO_VERSION
323
+				);
324
+			}
325
+		}
326
+	}
327
+
328
+
329
+
330
+	/**
331
+	 * registers core default javascript
332
+	 */
333
+	private function loadCoreJs()
334
+	{
335
+		// load core js
336
+		wp_register_script(
337
+			'espresso_core',
338
+			EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
339
+			array('jquery'),
340
+			EVENT_ESPRESSO_VERSION,
341
+			true
342
+		);
343
+	}
344
+
345
+
346
+
347
+	/**
348
+	 * registers jQuery Validate for form validation
349
+	 */
350
+	private function loadJqueryValidate()
351
+	{
352
+		// register jQuery Validate and additional methods
353
+		wp_register_script(
354
+			'jquery-validate',
355
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
356
+			array('jquery'),
357
+			'1.15.0',
358
+			true
359
+		);
360
+		wp_register_script(
361
+			'jquery-validate-extra-methods',
362
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
363
+			array('jquery', 'jquery-validate'),
364
+			'1.15.0',
365
+			true
366
+		);
367
+	}
368
+
369
+
370
+
371
+	/**
372
+	 * registers accounting.js for performing client-side calculations
373
+	 */
374
+	private function loadAccountingJs()
375
+	{
376
+		//accounting.js library
377
+		// @link http://josscrowcroft.github.io/accounting.js/
378
+		wp_register_script(
379
+			'ee-accounting-core',
380
+			EE_THIRD_PARTY_URL . 'accounting/accounting.js',
381
+			array('underscore'),
382
+			'0.3.2',
383
+			true
384
+		);
385
+		wp_register_script(
386
+			'ee-accounting',
387
+			EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js',
388
+			array('ee-accounting-core'),
389
+			EVENT_ESPRESSO_VERSION,
390
+			true
391
+		);
392
+	}
393
+
394
+
395
+
396
+	/**
397
+	 * registers accounting.js for performing client-side calculations
398
+	 */
399
+	private function localizeAccountingJs()
400
+	{
401
+		wp_localize_script(
402
+			'ee-accounting',
403
+			'EE_ACCOUNTING_CFG',
404
+			array(
405
+				'currency' => array(
406
+					'symbol'    => $this->currency_config->sign,
407
+					'format'    => array(
408
+						'pos'  => $this->currency_config->sign_b4 ? '%s%v' : '%v%s',
409
+						'neg'  => $this->currency_config->sign_b4 ? '- %s%v' : '- %v%s',
410
+						'zero' => $this->currency_config->sign_b4 ? '%s--' : '--%s',
411
+					),
412
+					'decimal'   => $this->currency_config->dec_mrk,
413
+					'thousand'  => $this->currency_config->thsnds,
414
+					'precision' => $this->currency_config->dec_plc,
415
+				),
416
+				'number'   => array(
417
+					'precision' => $this->currency_config->dec_plc,
418
+					'thousand'  => $this->currency_config->thsnds,
419
+					'decimal'   => $this->currency_config->dec_mrk,
420
+				),
421
+			)
422
+		);
423
+		$this->addRegisteredScriptHandlesWithData('ee-accounting');
424
+	}
425
+
426
+
427
+
428
+	/**
429
+	 * registers assets for cleaning your ears
430
+	 */
431
+	private function loadQtipJs()
432
+	{
433
+		// qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook,
434
+		// can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' );
435
+		if (apply_filters('FHEE_load_qtip', false)) {
436
+			EEH_Qtip_Loader::instance()->register_and_enqueue();
437
+		}
438
+	}
439
+
440
+
441
+	/**
442
+	 * This is used to set registered script handles that have data.
443
+	 * @param string $script_handle
444
+	 */
445
+	private function addRegisteredScriptHandlesWithData($script_handle)
446
+	{
447
+		$this->script_handles_with_data[$script_handle] = $script_handle;
448
+	}
449
+
450
+
451
+	/**
452
+	 * Checks WP_Scripts for all of each script handle registered internally as having data and unsets from the
453
+	 * Dependency stored in WP_Scripts if its set.
454
+	 */
455
+	private function removeAlreadyRegisteredDataForScriptHandles()
456
+	{
457
+		if (empty($this->script_handles_with_data)) {
458
+			return;
459
+		}
460
+		foreach ($this->script_handles_with_data as $script_handle) {
461
+			$this->removeAlreadyRegisteredDataForScriptHandle($script_handle);
462
+		}
463
+	}
464
+
465
+
466
+	/**
467
+	 * Removes any data dependency registered in WP_Scripts if its set.
468
+	 * @param string $script_handle
469
+	 */
470
+	private function removeAlreadyRegisteredDataForScriptHandle($script_handle)
471
+	{
472
+		if (isset($this->script_handles_with_data[$script_handle])) {
473
+			global $wp_scripts;
474
+			if ($wp_scripts->get_data($script_handle, 'data')) {
475
+				unset($wp_scripts->registered[$script_handle]->extra['data']);
476
+				unset($this->script_handles_with_data[$script_handle]);
477
+			}
478
+		}
479
+	}
480 480
 
481 481
 
482 482
 }
Please login to merge, or discard this patch.
core/services/bootstrap/BootstrapCore.php 1 patch
Indentation   +228 added lines, -228 removed lines patch added patch discarded remove patch
@@ -52,234 +52,234 @@
 block discarded – undo
52 52
 class BootstrapCore
53 53
 {
54 54
 
55
-    /**
56
-     * @type LoaderInterface $loader
57
-     */
58
-    private $loader;
59
-
60
-    /**
61
-     * @var RequestInterface $request
62
-     */
63
-    protected $request;
64
-
65
-    /**
66
-     * @var ResponseInterface $response
67
-     */
68
-    protected $response;
69
-
70
-    /**
71
-     * @var RequestStackBuilder $request_stack_builder
72
-     */
73
-    protected $request_stack_builder;
74
-
75
-    /**
76
-     * @var RequestStack $request_stack
77
-     */
78
-    protected $request_stack;
79
-
80
-
81
-    /**
82
-     * BootstrapCore constructor.
83
-     */
84
-    public function __construct()
85
-    {
86
-        // construct request stack and run middleware apps as soon as all WP plugins are loaded
87
-        add_action('plugins_loaded', array($this, 'initialize'), 0);
88
-    }
89
-
90
-
91
-    /**
92
-     * @throws InvalidRequestStackMiddlewareException
93
-     * @throws InvalidClassException
94
-     * @throws DomainException
95
-     * @throws EE_Error
96
-     * @throws InvalidArgumentException
97
-     * @throws InvalidDataTypeException
98
-     * @throws InvalidInterfaceException
99
-     * @throws ReflectionException
100
-     */
101
-    public function initialize()
102
-    {
103
-        $this->bootstrapDependencyInjectionContainer();
104
-        $this->bootstrapDomain();
105
-        $bootstrap_request = $this->bootstrapRequestResponseObjects();
106
-        add_action(
107
-            'EE_Load_Espresso_Core__handle_request__initialize_core_loading',
108
-            array($bootstrap_request, 'setupLegacyRequest')
109
-        );
110
-        $this->runRequestStack();
111
-    }
112
-
113
-
114
-    /**
115
-     * @throws ReflectionException
116
-     * @throws EE_Error
117
-     * @throws InvalidArgumentException
118
-     * @throws InvalidDataTypeException
119
-     * @throws InvalidInterfaceException
120
-     */
121
-    private function bootstrapDependencyInjectionContainer()
122
-    {
123
-        $bootstrap_di = new BootstrapDependencyInjectionContainer();
124
-        $bootstrap_di->buildLegacyDependencyInjectionContainer();
125
-        $bootstrap_di->buildLoader();
126
-        $registry = $bootstrap_di->getRegistry();
127
-        $dependency_map = $bootstrap_di->getDependencyMap();
128
-        $dependency_map->initialize();
129
-        $registry->initialize();
130
-        $this->loader = $bootstrap_di->getLoader();
131
-    }
132
-
133
-
134
-    /**
135
-     * configures the Domain object for core
136
-     *
137
-     * @return void
138
-     * @throws DomainException
139
-     * @throws InvalidArgumentException
140
-     * @throws InvalidDataTypeException
141
-     * @throws InvalidClassException
142
-     * @throws InvalidFilePathException
143
-     * @throws InvalidInterfaceException
144
-     */
145
-    private function bootstrapDomain()
146
-    {
147
-        DomainFactory::getShared(
148
-            new FullyQualifiedName(
149
-                'EventEspresso\core\domain\Domain'
150
-            ),
151
-            array(
152
-                new FilePath(EVENT_ESPRESSO_MAIN_FILE),
153
-                Version::fromString(espresso_version())
154
-            )
155
-        );
156
-    }
157
-
158
-
159
-    /**
160
-     * sets up the request and response objects
161
-     *
162
-     * @return BootstrapRequestResponseObjects
163
-     * @throws InvalidArgumentException
164
-     */
165
-    private function bootstrapRequestResponseObjects()
166
-    {
167
-        /** @var BootstrapRequestResponseObjects $bootstrap_request */
168
-        $bootstrap_request = $this->loader->getShared(
169
-            'EventEspresso\core\services\bootstrap\BootstrapRequestResponseObjects',
170
-            array($this->loader)
171
-        );
172
-        $bootstrap_request->buildRequestResponse();
173
-        $bootstrap_request->shareRequestResponse();
174
-        $this->request  = $this->loader->getShared('EventEspresso\core\services\request\Request');
175
-        $this->response = $this->loader->getShared('EventEspresso\core\services\request\Response');
176
-        return $bootstrap_request;
177
-    }
178
-
179
-
180
-    /**
181
-     * run_request_stack
182
-     * construct request stack and run middleware apps
183
-     *
184
-     * @throws InvalidRequestStackMiddlewareException
185
-     * @throws InvalidInterfaceException
186
-     * @throws InvalidDataTypeException
187
-     * @throws EE_Error
188
-     */
189
-    public function runRequestStack()
190
-    {
191
-        $this->loadAutoloader();
192
-        $this->setAutoloadersForRequiredFiles();
193
-        $this->request_stack_builder = $this->buildRequestStack();
194
-        $this->request_stack         = $this->request_stack_builder->resolve(
195
-            new RequestStackCoreApp()
196
-        );
197
-        $this->request_stack->handleRequest($this->request, $this->response);
198
-        $this->request_stack->handleResponse();
199
-    }
200
-
201
-
202
-    /**
203
-     * load_autoloader
204
-     *
205
-     * @throws EE_Error
206
-     */
207
-    protected function loadAutoloader()
208
-    {
209
-        // load interfaces
210
-        espresso_load_required(
211
-            'EEH_Autoloader',
212
-            EE_CORE . 'helpers' . DS . 'EEH_Autoloader.helper.php'
213
-        );
214
-        EEH_Autoloader::instance();
215
-    }
216
-
217
-
218
-
219
-    /**
220
-     * load_required_files
221
-     *
222
-     * @throws EE_Error
223
-     */
224
-    protected function setAutoloadersForRequiredFiles()
225
-    {
226
-        // load interfaces
227
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'interfaces', true);
228
-        // load helpers
229
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_HELPERS);
230
-        // load request stack
231
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'request_stack' . DS);
232
-        // load middleware
233
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'middleware' . DS);
234
-    }
235
-
236
-
237
-
238
-    /**
239
-     * build_request_stack
240
-     *
241
-     * @return RequestStackBuilder
242
-     */
243
-    public function buildRequestStack()
244
-    {
245
-        $request_stack_builder = new RequestStackBuilder($this->loader);
246
-        /**
247
-         * ! IMPORTANT ! The middleware stack operates FILO : FIRST IN LAST OUT
248
-         * so items at the beginning of the final middleware stack will run last.
249
-         * First parameter is the middleware classname, second is an array of arguments
250
-         */
251
-        $stack_apps            = apply_filters(
252
-            'FHEE__EventEspresso_core_services_bootstrap_BootstrapCore__buildRequestStack__stack_apps',
253
-            array(
254
-                // first in last out
255
-                'EventEspresso\core\services\request\middleware\BotDetector' => array(),
256
-                'EventEspresso\core\services\request\middleware\DetectFileEditorRequest' => array(),
257
-                'EventEspresso\core\services\request\middleware\PreProductionVersionWarning' => array(),
258
-                'EventEspresso\core\services\request\middleware\RecommendedVersions' => array(),
259
-                // last in first out
260
-                'EventEspresso\core\services\request\middleware\DetectLogin' => array(),
261
-            )
262
-        );
263
-        // legacy filter for backwards compatibility
264
-        $stack_apps            = apply_filters(
265
-            'FHEE__EE_Bootstrap__build_request_stack__stack_apps',
266
-            $stack_apps
267
-        );
268
-        // load middleware onto stack : FILO (First In Last Out)
269
-        // items at the beginning of the $stack_apps array will run last
270
-        foreach ((array) $stack_apps as $stack_app => $stack_app_args) {
271
-            $request_stack_builder->push(array($stack_app, $stack_app_args));
272
-        }
273
-        // finally, we'll add this on its own because we need it to always be part of the stack
274
-        // and we also need it to always run first because the rest of the system relies on it
275
-        $request_stack_builder->push(
276
-            array('EventEspresso\core\services\request\middleware\SetRequestTypeContextChecker', array())
277
-        );
278
-        return apply_filters(
279
-            'FHEE__EE_Bootstrap__build_request_stack__request_stack_builder',
280
-            $request_stack_builder
281
-        );
282
-    }
55
+	/**
56
+	 * @type LoaderInterface $loader
57
+	 */
58
+	private $loader;
59
+
60
+	/**
61
+	 * @var RequestInterface $request
62
+	 */
63
+	protected $request;
64
+
65
+	/**
66
+	 * @var ResponseInterface $response
67
+	 */
68
+	protected $response;
69
+
70
+	/**
71
+	 * @var RequestStackBuilder $request_stack_builder
72
+	 */
73
+	protected $request_stack_builder;
74
+
75
+	/**
76
+	 * @var RequestStack $request_stack
77
+	 */
78
+	protected $request_stack;
79
+
80
+
81
+	/**
82
+	 * BootstrapCore constructor.
83
+	 */
84
+	public function __construct()
85
+	{
86
+		// construct request stack and run middleware apps as soon as all WP plugins are loaded
87
+		add_action('plugins_loaded', array($this, 'initialize'), 0);
88
+	}
89
+
90
+
91
+	/**
92
+	 * @throws InvalidRequestStackMiddlewareException
93
+	 * @throws InvalidClassException
94
+	 * @throws DomainException
95
+	 * @throws EE_Error
96
+	 * @throws InvalidArgumentException
97
+	 * @throws InvalidDataTypeException
98
+	 * @throws InvalidInterfaceException
99
+	 * @throws ReflectionException
100
+	 */
101
+	public function initialize()
102
+	{
103
+		$this->bootstrapDependencyInjectionContainer();
104
+		$this->bootstrapDomain();
105
+		$bootstrap_request = $this->bootstrapRequestResponseObjects();
106
+		add_action(
107
+			'EE_Load_Espresso_Core__handle_request__initialize_core_loading',
108
+			array($bootstrap_request, 'setupLegacyRequest')
109
+		);
110
+		$this->runRequestStack();
111
+	}
112
+
113
+
114
+	/**
115
+	 * @throws ReflectionException
116
+	 * @throws EE_Error
117
+	 * @throws InvalidArgumentException
118
+	 * @throws InvalidDataTypeException
119
+	 * @throws InvalidInterfaceException
120
+	 */
121
+	private function bootstrapDependencyInjectionContainer()
122
+	{
123
+		$bootstrap_di = new BootstrapDependencyInjectionContainer();
124
+		$bootstrap_di->buildLegacyDependencyInjectionContainer();
125
+		$bootstrap_di->buildLoader();
126
+		$registry = $bootstrap_di->getRegistry();
127
+		$dependency_map = $bootstrap_di->getDependencyMap();
128
+		$dependency_map->initialize();
129
+		$registry->initialize();
130
+		$this->loader = $bootstrap_di->getLoader();
131
+	}
132
+
133
+
134
+	/**
135
+	 * configures the Domain object for core
136
+	 *
137
+	 * @return void
138
+	 * @throws DomainException
139
+	 * @throws InvalidArgumentException
140
+	 * @throws InvalidDataTypeException
141
+	 * @throws InvalidClassException
142
+	 * @throws InvalidFilePathException
143
+	 * @throws InvalidInterfaceException
144
+	 */
145
+	private function bootstrapDomain()
146
+	{
147
+		DomainFactory::getShared(
148
+			new FullyQualifiedName(
149
+				'EventEspresso\core\domain\Domain'
150
+			),
151
+			array(
152
+				new FilePath(EVENT_ESPRESSO_MAIN_FILE),
153
+				Version::fromString(espresso_version())
154
+			)
155
+		);
156
+	}
157
+
158
+
159
+	/**
160
+	 * sets up the request and response objects
161
+	 *
162
+	 * @return BootstrapRequestResponseObjects
163
+	 * @throws InvalidArgumentException
164
+	 */
165
+	private function bootstrapRequestResponseObjects()
166
+	{
167
+		/** @var BootstrapRequestResponseObjects $bootstrap_request */
168
+		$bootstrap_request = $this->loader->getShared(
169
+			'EventEspresso\core\services\bootstrap\BootstrapRequestResponseObjects',
170
+			array($this->loader)
171
+		);
172
+		$bootstrap_request->buildRequestResponse();
173
+		$bootstrap_request->shareRequestResponse();
174
+		$this->request  = $this->loader->getShared('EventEspresso\core\services\request\Request');
175
+		$this->response = $this->loader->getShared('EventEspresso\core\services\request\Response');
176
+		return $bootstrap_request;
177
+	}
178
+
179
+
180
+	/**
181
+	 * run_request_stack
182
+	 * construct request stack and run middleware apps
183
+	 *
184
+	 * @throws InvalidRequestStackMiddlewareException
185
+	 * @throws InvalidInterfaceException
186
+	 * @throws InvalidDataTypeException
187
+	 * @throws EE_Error
188
+	 */
189
+	public function runRequestStack()
190
+	{
191
+		$this->loadAutoloader();
192
+		$this->setAutoloadersForRequiredFiles();
193
+		$this->request_stack_builder = $this->buildRequestStack();
194
+		$this->request_stack         = $this->request_stack_builder->resolve(
195
+			new RequestStackCoreApp()
196
+		);
197
+		$this->request_stack->handleRequest($this->request, $this->response);
198
+		$this->request_stack->handleResponse();
199
+	}
200
+
201
+
202
+	/**
203
+	 * load_autoloader
204
+	 *
205
+	 * @throws EE_Error
206
+	 */
207
+	protected function loadAutoloader()
208
+	{
209
+		// load interfaces
210
+		espresso_load_required(
211
+			'EEH_Autoloader',
212
+			EE_CORE . 'helpers' . DS . 'EEH_Autoloader.helper.php'
213
+		);
214
+		EEH_Autoloader::instance();
215
+	}
216
+
217
+
218
+
219
+	/**
220
+	 * load_required_files
221
+	 *
222
+	 * @throws EE_Error
223
+	 */
224
+	protected function setAutoloadersForRequiredFiles()
225
+	{
226
+		// load interfaces
227
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'interfaces', true);
228
+		// load helpers
229
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_HELPERS);
230
+		// load request stack
231
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'request_stack' . DS);
232
+		// load middleware
233
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'middleware' . DS);
234
+	}
235
+
236
+
237
+
238
+	/**
239
+	 * build_request_stack
240
+	 *
241
+	 * @return RequestStackBuilder
242
+	 */
243
+	public function buildRequestStack()
244
+	{
245
+		$request_stack_builder = new RequestStackBuilder($this->loader);
246
+		/**
247
+		 * ! IMPORTANT ! The middleware stack operates FILO : FIRST IN LAST OUT
248
+		 * so items at the beginning of the final middleware stack will run last.
249
+		 * First parameter is the middleware classname, second is an array of arguments
250
+		 */
251
+		$stack_apps            = apply_filters(
252
+			'FHEE__EventEspresso_core_services_bootstrap_BootstrapCore__buildRequestStack__stack_apps',
253
+			array(
254
+				// first in last out
255
+				'EventEspresso\core\services\request\middleware\BotDetector' => array(),
256
+				'EventEspresso\core\services\request\middleware\DetectFileEditorRequest' => array(),
257
+				'EventEspresso\core\services\request\middleware\PreProductionVersionWarning' => array(),
258
+				'EventEspresso\core\services\request\middleware\RecommendedVersions' => array(),
259
+				// last in first out
260
+				'EventEspresso\core\services\request\middleware\DetectLogin' => array(),
261
+			)
262
+		);
263
+		// legacy filter for backwards compatibility
264
+		$stack_apps            = apply_filters(
265
+			'FHEE__EE_Bootstrap__build_request_stack__stack_apps',
266
+			$stack_apps
267
+		);
268
+		// load middleware onto stack : FILO (First In Last Out)
269
+		// items at the beginning of the $stack_apps array will run last
270
+		foreach ((array) $stack_apps as $stack_app => $stack_app_args) {
271
+			$request_stack_builder->push(array($stack_app, $stack_app_args));
272
+		}
273
+		// finally, we'll add this on its own because we need it to always be part of the stack
274
+		// and we also need it to always run first because the rest of the system relies on it
275
+		$request_stack_builder->push(
276
+			array('EventEspresso\core\services\request\middleware\SetRequestTypeContextChecker', array())
277
+		);
278
+		return apply_filters(
279
+			'FHEE__EE_Bootstrap__build_request_stack__request_stack_builder',
280
+			$request_stack_builder
281
+		);
282
+	}
283 283
 
284 284
 
285 285
 }
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +79 added lines, -79 removed lines patch added patch discarded remove patch
@@ -38,103 +38,103 @@
 block discarded – undo
38 38
  * @since       4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 
64 64
 } else {
65
-    define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
66
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
67
-        /**
68
-         * espresso_minimum_php_version_error
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
65
+	define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
66
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
67
+		/**
68
+		 * espresso_minimum_php_version_error
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                        esc_html__(
79
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
-                            'event_espresso'
81
-                        ),
82
-                        EE_MIN_PHP_VER_REQUIRED,
83
-                        PHP_VERSION,
84
-                        '<br/>',
85
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+						esc_html__(
79
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
+							'event_espresso'
81
+						),
82
+						EE_MIN_PHP_VER_REQUIRED,
83
+						PHP_VERSION,
84
+						'<br/>',
85
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
-        /**
98
-         * espresso_version
99
-         * Returns the plugin version
100
-         *
101
-         * @return string
102
-         */
103
-        function espresso_version()
104
-        {
105
-            return apply_filters('FHEE__espresso__espresso_version', '4.9.59.rc.031');
106
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
+		/**
98
+		 * espresso_version
99
+		 * Returns the plugin version
100
+		 *
101
+		 * @return string
102
+		 */
103
+		function espresso_version()
104
+		{
105
+			return apply_filters('FHEE__espresso__espresso_version', '4.9.59.rc.031');
106
+		}
107 107
 
108
-        /**
109
-         * espresso_plugin_activation
110
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
-         */
112
-        function espresso_plugin_activation()
113
-        {
114
-            update_option('ee_espresso_activation', true);
115
-        }
108
+		/**
109
+		 * espresso_plugin_activation
110
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
+		 */
112
+		function espresso_plugin_activation()
113
+		{
114
+			update_option('ee_espresso_activation', true);
115
+		}
116 116
 
117
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
117
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
118 118
 
119
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
120
-        bootstrap_espresso();
121
-    }
119
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
120
+		bootstrap_espresso();
121
+	}
122 122
 }
123 123
 if (! function_exists('espresso_deactivate_plugin')) {
124
-    /**
125
-     *    deactivate_plugin
126
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
-     *
128
-     * @access public
129
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
-     * @return    void
131
-     */
132
-    function espresso_deactivate_plugin($plugin_basename = '')
133
-    {
134
-        if (! function_exists('deactivate_plugins')) {
135
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
-        }
137
-        unset($_GET['activate'], $_REQUEST['activate']);
138
-        deactivate_plugins($plugin_basename);
139
-    }
124
+	/**
125
+	 *    deactivate_plugin
126
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
+	 *
128
+	 * @access public
129
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
+	 * @return    void
131
+	 */
132
+	function espresso_deactivate_plugin($plugin_basename = '')
133
+	{
134
+		if (! function_exists('deactivate_plugins')) {
135
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
+		}
137
+		unset($_GET['activate'], $_REQUEST['activate']);
138
+		deactivate_plugins($plugin_basename);
139
+	}
140 140
 }
Please login to merge, or discard this patch.
message_type/newsletter/EE_Messages_Email_Newsletter_Validator.class.php 2 patches
Indentation   +53 added lines, -53 removed lines patch added patch discarded remove patch
@@ -7,7 +7,7 @@  discard block
 block discarded – undo
7 7
  * @since           4.3.0
8 8
  */
9 9
 if (! defined('EVENT_ESPRESSO_VERSION')) {
10
-    exit('No direct script access allowed');
10
+	exit('No direct script access allowed');
11 11
 }
12 12
 
13 13
 /**
@@ -21,59 +21,59 @@  discard block
 block discarded – undo
21 21
  */
22 22
 class EE_Messages_Email_Newsletter_Validator extends EE_Messages_Validator
23 23
 {
24
-    public function __construct($fields, $context)
25
-    {
26
-        $this->_m_name = 'email';
27
-        $this->_mt_name = 'newsletter';
24
+	public function __construct($fields, $context)
25
+	{
26
+		$this->_m_name = 'email';
27
+		$this->_mt_name = 'newsletter';
28 28
 
29
-        parent::__construct($fields, $context);
30
-    }
29
+		parent::__construct($fields, $context);
30
+	}
31 31
 
32
-    /**
33
-     * custom validator (restricting what was originally set by the messenger)
34
-     */
35
-    protected function _modify_validator()
36
-    {
37
-        if ($this->_context == 'attendee') {
38
-            $this->_valid_shortcodes_modifier[$this->_context]['from'] = array(
39
-                'recipient_details',
40
-                'email',
41
-                'organization',
42
-            );
43
-        }
32
+	/**
33
+	 * custom validator (restricting what was originally set by the messenger)
34
+	 */
35
+	protected function _modify_validator()
36
+	{
37
+		if ($this->_context == 'attendee') {
38
+			$this->_valid_shortcodes_modifier[$this->_context]['from'] = array(
39
+				'recipient_details',
40
+				'email',
41
+				'organization',
42
+			);
43
+		}
44 44
 
45
-        //excluded shortcodes
46
-        $fields = array('to', 'from', 'subject', 'content', 'newsletter_content');
47
-        foreach ($fields as $field) {
48
-            $this->_specific_shortcode_excludes[$field] = array(
49
-                '[RECIPIENT_REGISTRATION_CODE]',
50
-                '[EVENT_AUTHOR_FORMATTED_EMAIL]',
51
-                '[EVENT_AUTHOR_EMAIL]',
52
-            );
53
-        }
54
-        $add_excludes = array(
55
-            '[RECIPIENT_FNAME]',
56
-            '[RECIPIENT_LNAME]',
57
-            '[RECIPIENT_EMAIL]',
58
-            '[COMPANY]',
59
-            '[CO_ADD1]',
60
-            '[CO_ADD2]',
61
-            '[CO_CITY]',
62
-            '[CO_STATE]',
63
-            '[CO_ZIP]',
64
-            '[CO_LOGO]',
65
-            '[CO_PHONE]',
66
-            '[CO_LOGO_URL]',
67
-            '[CO_FACEBOOK_URL]',
68
-            '[CO_TWITTER_URL]',
69
-            '[CO_PINTEREST_URL]',
70
-            '[CO_GOOGLE_URL]',
71
-            '[CO_LINKEDIN_URL]',
72
-            '[CO_INSTAGRAM_URL]',
73
-        );
74
-        $this->_specific_shortcode_excludes['from'] = array_merge($this->_specific_shortcode_excludes['from'],
75
-            $add_excludes);
76
-        $this->_specific_shortcode_excludes['content'] = array_merge($this->_specific_shortcode_excludes['content'],
77
-            array('[DISPLAY_PDF_URL]', '[DISPLAY_PDF_BUTTON]'));
78
-    }
45
+		//excluded shortcodes
46
+		$fields = array('to', 'from', 'subject', 'content', 'newsletter_content');
47
+		foreach ($fields as $field) {
48
+			$this->_specific_shortcode_excludes[$field] = array(
49
+				'[RECIPIENT_REGISTRATION_CODE]',
50
+				'[EVENT_AUTHOR_FORMATTED_EMAIL]',
51
+				'[EVENT_AUTHOR_EMAIL]',
52
+			);
53
+		}
54
+		$add_excludes = array(
55
+			'[RECIPIENT_FNAME]',
56
+			'[RECIPIENT_LNAME]',
57
+			'[RECIPIENT_EMAIL]',
58
+			'[COMPANY]',
59
+			'[CO_ADD1]',
60
+			'[CO_ADD2]',
61
+			'[CO_CITY]',
62
+			'[CO_STATE]',
63
+			'[CO_ZIP]',
64
+			'[CO_LOGO]',
65
+			'[CO_PHONE]',
66
+			'[CO_LOGO_URL]',
67
+			'[CO_FACEBOOK_URL]',
68
+			'[CO_TWITTER_URL]',
69
+			'[CO_PINTEREST_URL]',
70
+			'[CO_GOOGLE_URL]',
71
+			'[CO_LINKEDIN_URL]',
72
+			'[CO_INSTAGRAM_URL]',
73
+		);
74
+		$this->_specific_shortcode_excludes['from'] = array_merge($this->_specific_shortcode_excludes['from'],
75
+			$add_excludes);
76
+		$this->_specific_shortcode_excludes['content'] = array_merge($this->_specific_shortcode_excludes['content'],
77
+			array('[DISPLAY_PDF_URL]', '[DISPLAY_PDF_BUTTON]'));
78
+	}
79 79
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -6,7 +6,7 @@
 block discarded – undo
6 6
  * @subpackage      helpers
7 7
  * @since           4.3.0
8 8
  */
9
-if (! defined('EVENT_ESPRESSO_VERSION')) {
9
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
10 10
     exit('No direct script access allowed');
11 11
 }
12 12
 
Please login to merge, or discard this patch.
messages/message_type/newsletter/EE_Newsletter_message_type.class.php 2 patches
Indentation   +147 added lines, -147 removed lines patch added patch discarded remove patch
@@ -7,7 +7,7 @@  discard block
 block discarded – undo
7 7
  * @since           4.3.0
8 8
  */
9 9
 if (! defined('EVENT_ESPRESSO_VERSION')) {
10
-    exit('No direct script access allowed');
10
+	exit('No direct script access allowed');
11 11
 }
12 12
 
13 13
 /**
@@ -23,152 +23,152 @@  discard block
 block discarded – undo
23 23
 class EE_Newsletter_message_type extends EE_message_type
24 24
 {
25 25
 
26
-    public function __construct()
27
-    {
28
-        $this->name = 'newsletter';
29
-        $this->description = __('Batch message type messages are triggered manually by the admin for sending notifications to a selected group of recipients. This should only be used for more general notification type messages that contain information specific for the recipients. For "newsletter" type messages we recommend using an email list service like MailChimp, because sending non-related mail-outs to contacts increases the risk of your site domain getting added to spam lists, which will prevent messages getting to users.',
30
-            'event_espresso');
31
-        $this->label = array(
32
-            'singular' => __('batch', 'event_espresso'),
33
-            'plural'   => __('batches', 'event_espresso'),
34
-        );
35
-        $this->_master_templates = array(
36
-            'email' => 'registration',
37
-        );
38
-
39
-        parent::__construct();
40
-    }
41
-
42
-
43
-    protected function _set_admin_pages()
44
-    {
45
-        $this->admin_registered_pages = array(); //no admin pages to register this with.
46
-    }
47
-
48
-
49
-    protected function _set_data_handler()
50
-    {
51
-        $this->_data_handler = 'Registrations';
52
-        $this->_single_message = $this->_data instanceof EE_Registration;
53
-    }
54
-
55
-
56
-    protected function _get_data_for_context($context, EE_Registration $registration, $id)
57
-    {
58
-        //newsletter message type data handler is 'Registrations' and it expects an array of EE_Registration objects.
59
-        return array($registration);
60
-    }
61
-
62
-
63
-    protected function _set_admin_settings_fields()
64
-    {
65
-        $this->_admin_settings_fields = array();
66
-    }
67
-
68
-
69
-    protected function _set_contexts()
70
-    {
71
-        $this->_context_label = array(
72
-            'label'       => __('recipient', 'event_espresso'),
73
-            'plural'      => __('recipients', 'event_espresso'),
74
-            'description' => __('Recipient\'s are who will receive the message.', 'event_espresso'),
75
-        );
76
-
77
-        $this->_contexts = array(
78
-            'attendee' => array(
79
-                'label'       => __('Registrant', 'event_espresso'),
80
-                'description' => __('This template goes to selected registrants.', 'event_espresso'),
81
-            ),
82
-        );
83
-    }
84
-
85
-
86
-    /**
87
-     * used to set the valid shortcodes.
88
-     * For the newsletter message type we only have two valid shortcode libraries in use, recipient details and
89
-     * organization.  That's it!
90
-     *
91
-     * @since   4.3.0
92
-     * @return  void
93
-     */
94
-    protected function _set_valid_shortcodes()
95
-    {
96
-        parent::_set_valid_shortcodes();
97
-
98
-        $included_shortcodes = array(
99
-            'recipient_details',
100
-            'organization',
101
-            'newsletter',
102
-        );
103
-
104
-        foreach ($this->_valid_shortcodes as $context => $shortcodes) {
105
-            foreach ($shortcodes as $key => $shortcode) {
106
-                if (! in_array($shortcode, $included_shortcodes)) {
107
-                    unset($this->_valid_shortcodes[$context][$key]);
108
-                }
109
-            }
110
-            $this->_valid_shortcodes[$context][] = 'newsletter';
111
-        }
112
-
113
-    }
114
-
115
-
116
-    /**
117
-     * Override default _attendee_addressees in EE_message_type because we want to loop through the registrations
118
-     * for EE_message_type.
119
-     */
120
-    protected function _attendee_addressees()
121
-    {
122
-        $addressee = array();
123
-
124
-        //looping through registrations
125
-        foreach ($this->_data->registrations as $reg_id => $details) {
126
-            //set $attendee array to blank on each loop
127
-            $aee = array();
128
-
129
-            //need to get the attendee from this registration.
130
-            $attendee = isset($details['att_obj']) && $details['att_obj'] instanceof EE_Attendee
131
-                ? $details['att_obj']
132
-                : null;
133
-
134
-            if (! $attendee instanceof EE_Attendee) {
135
-                continue;
136
-            }
137
-
138
-            //set $aee from attendee object
139
-            $aee['att_obj'] = $attendee;
140
-            $aee['reg_objs'] = isset($this->_data->attendees[$attendee->ID()]['reg_objs'])
141
-                ? $this->_data->attendees[$attendee->ID()]['reg_objs']
142
-                : array();
143
-            $aee['attendee_email'] = $attendee->email();
144
-            $aee['tkt_objs'] = isset($this->_data->attendees[$attendee->ID()]['tkt_objs'])
145
-                ? $this->_data->attendees[$attendee->ID()]['tkt_objs']
146
-                : array();
147
-
148
-            if (isset($this->_data->attendees[$attendee->ID()]['evt_objs'])) {
149
-                $aee['evt_objs'] = $this->_data->attendees[$attendee->ID()]['evt_objs'];
150
-                $aee['events'] = $this->_data->attendees[$attendee->ID()]['evt_objs'];
151
-            } else {
152
-                $aee['evt_objs'] = $aee['events'] = array();
153
-            }
154
-
155
-            $aee['reg_obj'] = isset($details['reg_obj'])
156
-                ? $details['reg_obj']
157
-                : null;
158
-            $aee['attendees'] = $this->_data->attendees;
159
-
160
-            //merge in the primary attendee data
161
-            $aee = array_merge($this->_default_addressee_data, $aee);
162
-
163
-            //make sure txn is set
164
-            if (empty($aee['txn']) && $aee['reg_obj'] instanceof EE_Registration) {
165
-                $aee['txn'] = $aee['reg_obj']->transaction();
166
-            }
167
-
168
-            $addressee[] = new EE_Messages_Addressee($aee);
169
-        }
170
-        return $addressee;
171
-    }
26
+	public function __construct()
27
+	{
28
+		$this->name = 'newsletter';
29
+		$this->description = __('Batch message type messages are triggered manually by the admin for sending notifications to a selected group of recipients. This should only be used for more general notification type messages that contain information specific for the recipients. For "newsletter" type messages we recommend using an email list service like MailChimp, because sending non-related mail-outs to contacts increases the risk of your site domain getting added to spam lists, which will prevent messages getting to users.',
30
+			'event_espresso');
31
+		$this->label = array(
32
+			'singular' => __('batch', 'event_espresso'),
33
+			'plural'   => __('batches', 'event_espresso'),
34
+		);
35
+		$this->_master_templates = array(
36
+			'email' => 'registration',
37
+		);
38
+
39
+		parent::__construct();
40
+	}
41
+
42
+
43
+	protected function _set_admin_pages()
44
+	{
45
+		$this->admin_registered_pages = array(); //no admin pages to register this with.
46
+	}
47
+
48
+
49
+	protected function _set_data_handler()
50
+	{
51
+		$this->_data_handler = 'Registrations';
52
+		$this->_single_message = $this->_data instanceof EE_Registration;
53
+	}
54
+
55
+
56
+	protected function _get_data_for_context($context, EE_Registration $registration, $id)
57
+	{
58
+		//newsletter message type data handler is 'Registrations' and it expects an array of EE_Registration objects.
59
+		return array($registration);
60
+	}
61
+
62
+
63
+	protected function _set_admin_settings_fields()
64
+	{
65
+		$this->_admin_settings_fields = array();
66
+	}
67
+
68
+
69
+	protected function _set_contexts()
70
+	{
71
+		$this->_context_label = array(
72
+			'label'       => __('recipient', 'event_espresso'),
73
+			'plural'      => __('recipients', 'event_espresso'),
74
+			'description' => __('Recipient\'s are who will receive the message.', 'event_espresso'),
75
+		);
76
+
77
+		$this->_contexts = array(
78
+			'attendee' => array(
79
+				'label'       => __('Registrant', 'event_espresso'),
80
+				'description' => __('This template goes to selected registrants.', 'event_espresso'),
81
+			),
82
+		);
83
+	}
84
+
85
+
86
+	/**
87
+	 * used to set the valid shortcodes.
88
+	 * For the newsletter message type we only have two valid shortcode libraries in use, recipient details and
89
+	 * organization.  That's it!
90
+	 *
91
+	 * @since   4.3.0
92
+	 * @return  void
93
+	 */
94
+	protected function _set_valid_shortcodes()
95
+	{
96
+		parent::_set_valid_shortcodes();
97
+
98
+		$included_shortcodes = array(
99
+			'recipient_details',
100
+			'organization',
101
+			'newsletter',
102
+		);
103
+
104
+		foreach ($this->_valid_shortcodes as $context => $shortcodes) {
105
+			foreach ($shortcodes as $key => $shortcode) {
106
+				if (! in_array($shortcode, $included_shortcodes)) {
107
+					unset($this->_valid_shortcodes[$context][$key]);
108
+				}
109
+			}
110
+			$this->_valid_shortcodes[$context][] = 'newsletter';
111
+		}
112
+
113
+	}
114
+
115
+
116
+	/**
117
+	 * Override default _attendee_addressees in EE_message_type because we want to loop through the registrations
118
+	 * for EE_message_type.
119
+	 */
120
+	protected function _attendee_addressees()
121
+	{
122
+		$addressee = array();
123
+
124
+		//looping through registrations
125
+		foreach ($this->_data->registrations as $reg_id => $details) {
126
+			//set $attendee array to blank on each loop
127
+			$aee = array();
128
+
129
+			//need to get the attendee from this registration.
130
+			$attendee = isset($details['att_obj']) && $details['att_obj'] instanceof EE_Attendee
131
+				? $details['att_obj']
132
+				: null;
133
+
134
+			if (! $attendee instanceof EE_Attendee) {
135
+				continue;
136
+			}
137
+
138
+			//set $aee from attendee object
139
+			$aee['att_obj'] = $attendee;
140
+			$aee['reg_objs'] = isset($this->_data->attendees[$attendee->ID()]['reg_objs'])
141
+				? $this->_data->attendees[$attendee->ID()]['reg_objs']
142
+				: array();
143
+			$aee['attendee_email'] = $attendee->email();
144
+			$aee['tkt_objs'] = isset($this->_data->attendees[$attendee->ID()]['tkt_objs'])
145
+				? $this->_data->attendees[$attendee->ID()]['tkt_objs']
146
+				: array();
147
+
148
+			if (isset($this->_data->attendees[$attendee->ID()]['evt_objs'])) {
149
+				$aee['evt_objs'] = $this->_data->attendees[$attendee->ID()]['evt_objs'];
150
+				$aee['events'] = $this->_data->attendees[$attendee->ID()]['evt_objs'];
151
+			} else {
152
+				$aee['evt_objs'] = $aee['events'] = array();
153
+			}
154
+
155
+			$aee['reg_obj'] = isset($details['reg_obj'])
156
+				? $details['reg_obj']
157
+				: null;
158
+			$aee['attendees'] = $this->_data->attendees;
159
+
160
+			//merge in the primary attendee data
161
+			$aee = array_merge($this->_default_addressee_data, $aee);
162
+
163
+			//make sure txn is set
164
+			if (empty($aee['txn']) && $aee['reg_obj'] instanceof EE_Registration) {
165
+				$aee['txn'] = $aee['reg_obj']->transaction();
166
+			}
167
+
168
+			$addressee[] = new EE_Messages_Addressee($aee);
169
+		}
170
+		return $addressee;
171
+	}
172 172
 
173 173
 
174 174
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -6,7 +6,7 @@  discard block
 block discarded – undo
6 6
  * @subpackage      helpers
7 7
  * @since           4.3.0
8 8
  */
9
-if (! defined('EVENT_ESPRESSO_VERSION')) {
9
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
10 10
     exit('No direct script access allowed');
11 11
 }
12 12
 
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
 
104 104
         foreach ($this->_valid_shortcodes as $context => $shortcodes) {
105 105
             foreach ($shortcodes as $key => $shortcode) {
106
-                if (! in_array($shortcode, $included_shortcodes)) {
106
+                if ( ! in_array($shortcode, $included_shortcodes)) {
107 107
                     unset($this->_valid_shortcodes[$context][$key]);
108 108
                 }
109 109
             }
@@ -131,7 +131,7 @@  discard block
 block discarded – undo
131 131
                 ? $details['att_obj']
132 132
                 : null;
133 133
 
134
-            if (! $attendee instanceof EE_Attendee) {
134
+            if ( ! $attendee instanceof EE_Attendee) {
135 135
                 continue;
136 136
             }
137 137
 
Please login to merge, or discard this patch.