Completed
Branch 973/fix-visible-recaptcha (0580c7)
by
unknown
03:03 queued 30s
created
core/libraries/rest_api/Capabilities.php 2 patches
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
     ) {
100 100
         $has_password = $model->hasPassword();
101 101
         if ($has_password) {
102
-            $entity[ $model->getPasswordField()->get_name() ] = ModelDataTranslator::prepareFieldValueForJson(
102
+            $entity[$model->getPasswordField()->get_name()] = ModelDataTranslator::prepareFieldValueForJson(
103 103
                 $model->getPasswordField(),
104 104
                 $model->getPasswordField()->get_default_value(),
105 105
                 $model_version_info->requestedVersion()
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
             if (
110 110
                 $has_password
111 111
                 && $model->getPasswordField()->fieldIsProtected($field_name)
112
-                && $entity[ $field_name ]
112
+                && $entity[$field_name]
113 113
             ) {
114 114
                 $replacement_value = ModelDataTranslator::prepareFieldValueForJson(
115 115
                     $field_obj,
@@ -117,10 +117,10 @@  discard block
 block discarded – undo
117 117
                     $model_version_info->requestedVersion()
118 118
                 );
119 119
                 if ($model_version_info->fieldHasRenderedFormat($field_obj)) {
120
-                    $entity[ $field_name ]['rendered'] = $replacement_value;
120
+                    $entity[$field_name]['rendered'] = $replacement_value;
121 121
                 } elseif ($model_version_info->fieldHasPrettyFormat($field_obj)) {
122
-                    $entity[ $field_name ]['raw'] = $replacement_value;
123
-                    $entity[ $field_name ]['pretty'] = ModelDataTranslator::prepareFieldValueForJson(
122
+                    $entity[$field_name]['raw'] = $replacement_value;
123
+                    $entity[$field_name]['pretty'] = ModelDataTranslator::prepareFieldValueForJson(
124 124
                         $field_obj,
125 125
                         $field_obj->prepare_for_pretty_echoing($field_obj->get_default_value()),
126 126
                         $model_version_info->requestedVersion()
@@ -131,7 +131,7 @@  discard block
 block discarded – undo
131 131
                     // so just remove it (or rather, set its default)
132 132
                     // API clients will just need to look to fields with rendered formats to know if these have
133 133
                     // been redacted. Sorry.
134
-                    $entity[ $field_name ] = $replacement_value;
134
+                    $entity[$field_name] = $replacement_value;
135 135
                 }
136 136
             }
137 137
         }
@@ -160,11 +160,11 @@  discard block
 block discarded – undo
160 160
         foreach ($model->field_settings() as $field_name => $field_obj) {
161 161
             if (
162 162
                 $model_version_info->fieldHasRenderedFormat($field_obj)
163
-                && isset($entity[ $field_name ])
164
-                && is_array($entity[ $field_name ])
165
-                && isset($entity[ $field_name ]['raw'])
163
+                && isset($entity[$field_name])
164
+                && is_array($entity[$field_name])
165
+                && isset($entity[$field_name]['raw'])
166 166
             ) {
167
-                unset($entity[ $field_name ]['raw']);
167
+                unset($entity[$field_name]['raw']);
168 168
             }
169 169
         }
170 170
         // theoretically we may want to filter out specific fields for specific models
@@ -190,7 +190,7 @@  discard block
 block discarded – undo
190 190
      */
191 191
     public static function verifyAtLeastPartialAccessTo($model, $model_action_context, $action_name = 'list')
192 192
     {
193
-        if (! Capabilities::currentUserHasPartialAccessTo($model, $model_action_context)) {
193
+        if ( ! Capabilities::currentUserHasPartialAccessTo($model, $model_action_context)) {
194 194
             $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
195 195
             throw new RestException(
196 196
                 sprintf('rest_cannot_%s_%s', strtolower($action_name), $model_name_plural),
Please login to merge, or discard this patch.
Indentation   +177 added lines, -177 removed lines patch added patch discarded remove patch
@@ -18,190 +18,190 @@
 block discarded – undo
18 18
 class Capabilities
19 19
 {
20 20
 
21
-    /**
22
-     * The current user can see at least SOME of these entities.
23
-     *
24
-     * @param EEM_Base $model
25
-     * @param string   $model_context one of the return values from EEM_Base::valid_cap_contexts()
26
-     * @return boolean
27
-     */
28
-    public static function currentUserHasPartialAccessTo($model, $model_context = EEM_Base::caps_read)
29
-    {
30
-        if (
31
-            apply_filters(
32
-                'FHEE__Capabilities__current_user_has_partial_access_to__override_begin',
33
-                false,
34
-                $model,
35
-                $model
36
-            )
37
-        ) {
38
-            return true;
39
-        }
40
-        foreach ($model->caps_missing($model_context) as $capability_name => $restriction_obj) {
41
-            if ($restriction_obj instanceof \EE_Return_None_Where_Conditions) {
42
-                return false;
43
-            }
44
-        }
45
-        if (
46
-            apply_filters(
47
-                'FHEE__Capabilities__current_user_has_partial_access_to__override_end',
48
-                false,
49
-                $model,
50
-                $model
51
-            )
52
-        ) {
53
-            return false;
54
-        }
55
-        return true;
56
-    }
21
+	/**
22
+	 * The current user can see at least SOME of these entities.
23
+	 *
24
+	 * @param EEM_Base $model
25
+	 * @param string   $model_context one of the return values from EEM_Base::valid_cap_contexts()
26
+	 * @return boolean
27
+	 */
28
+	public static function currentUserHasPartialAccessTo($model, $model_context = EEM_Base::caps_read)
29
+	{
30
+		if (
31
+			apply_filters(
32
+				'FHEE__Capabilities__current_user_has_partial_access_to__override_begin',
33
+				false,
34
+				$model,
35
+				$model
36
+			)
37
+		) {
38
+			return true;
39
+		}
40
+		foreach ($model->caps_missing($model_context) as $capability_name => $restriction_obj) {
41
+			if ($restriction_obj instanceof \EE_Return_None_Where_Conditions) {
42
+				return false;
43
+			}
44
+		}
45
+		if (
46
+			apply_filters(
47
+				'FHEE__Capabilities__current_user_has_partial_access_to__override_end',
48
+				false,
49
+				$model,
50
+				$model
51
+			)
52
+		) {
53
+			return false;
54
+		}
55
+		return true;
56
+	}
57 57
 
58 58
 
59
-    /**
60
-     * Gets an array of all the capabilities the current user is missing that affected
61
-     * the query
62
-     *
63
-     * @param EEM_Base $model
64
-     * @param string   $request_type one of the constants on WP_JSON_Server
65
-     * @return array
66
-     */
67
-    public static function getMissingPermissions($model, $request_type = EEM_Base::caps_read)
68
-    {
69
-        return $model->caps_missing($request_type);
70
-    }
59
+	/**
60
+	 * Gets an array of all the capabilities the current user is missing that affected
61
+	 * the query
62
+	 *
63
+	 * @param EEM_Base $model
64
+	 * @param string   $request_type one of the constants on WP_JSON_Server
65
+	 * @return array
66
+	 */
67
+	public static function getMissingPermissions($model, $request_type = EEM_Base::caps_read)
68
+	{
69
+		return $model->caps_missing($request_type);
70
+	}
71 71
 
72 72
 
73
-    /**
74
-     * Gets a string of all the capabilities the current user is missing that affected
75
-     * the query
76
-     *
77
-     * @param EEM_Base $model
78
-     * @param string   $model_context one of the return values from EEM_Base::valid_cap_contexts()
79
-     * @return string
80
-     */
81
-    public static function getMissingPermissionsString($model, $model_context = EEM_Base::caps_read)
82
-    {
83
-        return implode(',', array_keys(self::getMissingPermissions($model, $model_context)));
84
-    }
73
+	/**
74
+	 * Gets a string of all the capabilities the current user is missing that affected
75
+	 * the query
76
+	 *
77
+	 * @param EEM_Base $model
78
+	 * @param string   $model_context one of the return values from EEM_Base::valid_cap_contexts()
79
+	 * @return string
80
+	 */
81
+	public static function getMissingPermissionsString($model, $model_context = EEM_Base::caps_read)
82
+	{
83
+		return implode(',', array_keys(self::getMissingPermissions($model, $model_context)));
84
+	}
85 85
 
86
-    /**
87
-     * "Removes" password-protected fields. Currently that means setting their values to their default.
88
-     * @since 4.9.74.p
89
-     * @param array $entity
90
-     * @param EEM_Base $model
91
-     * @param ModelVersionInfo $model_version_info
92
-     * @return array
93
-     * @throws EE_Error
94
-     */
95
-    public static function filterOutPasswordProtectedFields(
96
-        $entity,
97
-        EEM_Base $model,
98
-        ModelVersionInfo $model_version_info
99
-    ) {
100
-        $has_password = $model->hasPassword();
101
-        if ($has_password) {
102
-            $entity[ $model->getPasswordField()->get_name() ] = ModelDataTranslator::prepareFieldValueForJson(
103
-                $model->getPasswordField(),
104
-                $model->getPasswordField()->get_default_value(),
105
-                $model_version_info->requestedVersion()
106
-            );
107
-        }
108
-        foreach ($model->field_settings() as $field_name => $field_obj) {
109
-            if (
110
-                $has_password
111
-                && $model->getPasswordField()->fieldIsProtected($field_name)
112
-                && $entity[ $field_name ]
113
-            ) {
114
-                $replacement_value = ModelDataTranslator::prepareFieldValueForJson(
115
-                    $field_obj,
116
-                    $field_obj->get_default_value(),
117
-                    $model_version_info->requestedVersion()
118
-                );
119
-                if ($model_version_info->fieldHasRenderedFormat($field_obj)) {
120
-                    $entity[ $field_name ]['rendered'] = $replacement_value;
121
-                } elseif ($model_version_info->fieldHasPrettyFormat($field_obj)) {
122
-                    $entity[ $field_name ]['raw'] = $replacement_value;
123
-                    $entity[ $field_name ]['pretty'] = ModelDataTranslator::prepareFieldValueForJson(
124
-                        $field_obj,
125
-                        $field_obj->prepare_for_pretty_echoing($field_obj->get_default_value()),
126
-                        $model_version_info->requestedVersion()
127
-                    );
128
-                } else {
129
-                    // this is most likely an excerpt field. (These should have also had "rendered" and "raw"
130
-                    // versions, but we missed that, and can't change it without breaking backward compatibility)
131
-                    // so just remove it (or rather, set its default)
132
-                    // API clients will just need to look to fields with rendered formats to know if these have
133
-                    // been redacted. Sorry.
134
-                    $entity[ $field_name ] = $replacement_value;
135
-                }
136
-            }
137
-        }
138
-        return $entity;
139
-    }
86
+	/**
87
+	 * "Removes" password-protected fields. Currently that means setting their values to their default.
88
+	 * @since 4.9.74.p
89
+	 * @param array $entity
90
+	 * @param EEM_Base $model
91
+	 * @param ModelVersionInfo $model_version_info
92
+	 * @return array
93
+	 * @throws EE_Error
94
+	 */
95
+	public static function filterOutPasswordProtectedFields(
96
+		$entity,
97
+		EEM_Base $model,
98
+		ModelVersionInfo $model_version_info
99
+	) {
100
+		$has_password = $model->hasPassword();
101
+		if ($has_password) {
102
+			$entity[ $model->getPasswordField()->get_name() ] = ModelDataTranslator::prepareFieldValueForJson(
103
+				$model->getPasswordField(),
104
+				$model->getPasswordField()->get_default_value(),
105
+				$model_version_info->requestedVersion()
106
+			);
107
+		}
108
+		foreach ($model->field_settings() as $field_name => $field_obj) {
109
+			if (
110
+				$has_password
111
+				&& $model->getPasswordField()->fieldIsProtected($field_name)
112
+				&& $entity[ $field_name ]
113
+			) {
114
+				$replacement_value = ModelDataTranslator::prepareFieldValueForJson(
115
+					$field_obj,
116
+					$field_obj->get_default_value(),
117
+					$model_version_info->requestedVersion()
118
+				);
119
+				if ($model_version_info->fieldHasRenderedFormat($field_obj)) {
120
+					$entity[ $field_name ]['rendered'] = $replacement_value;
121
+				} elseif ($model_version_info->fieldHasPrettyFormat($field_obj)) {
122
+					$entity[ $field_name ]['raw'] = $replacement_value;
123
+					$entity[ $field_name ]['pretty'] = ModelDataTranslator::prepareFieldValueForJson(
124
+						$field_obj,
125
+						$field_obj->prepare_for_pretty_echoing($field_obj->get_default_value()),
126
+						$model_version_info->requestedVersion()
127
+					);
128
+				} else {
129
+					// this is most likely an excerpt field. (These should have also had "rendered" and "raw"
130
+					// versions, but we missed that, and can't change it without breaking backward compatibility)
131
+					// so just remove it (or rather, set its default)
132
+					// API clients will just need to look to fields with rendered formats to know if these have
133
+					// been redacted. Sorry.
134
+					$entity[ $field_name ] = $replacement_value;
135
+				}
136
+			}
137
+		}
138
+		return $entity;
139
+	}
140 140
 
141 141
 
142
-    /**
143
-     * Takes a entity that's ready to be returned and removes fields which the user shouldn't be able to access.
144
-     *
145
-     * @param array $entity
146
-     * @param EEM_Base $model
147
-     * @param string $request_type one of the return values from EEM_Base::valid_cap_contexts()
148
-     * @param ModelVersionInfo $model_version_info
149
-     * @param string $primary_key_string result of EEM_Base::get_index_primary_key_string(), so that we can
150
-     *                                               use this with models that have no primary key
151
-     * @return array ready for converting into json
152
-     */
153
-    public static function filterOutInaccessibleEntityFields(
154
-        $entity,
155
-        $model,
156
-        $request_type,
157
-        $model_version_info,
158
-        $primary_key_string = null
159
-    ) {
160
-        foreach ($model->field_settings() as $field_name => $field_obj) {
161
-            if (
162
-                $model_version_info->fieldHasRenderedFormat($field_obj)
163
-                && isset($entity[ $field_name ])
164
-                && is_array($entity[ $field_name ])
165
-                && isset($entity[ $field_name ]['raw'])
166
-            ) {
167
-                unset($entity[ $field_name ]['raw']);
168
-            }
169
-        }
170
-        // theoretically we may want to filter out specific fields for specific models
171
-        return apply_filters(
172
-            'FHEE__Capabilities__filter_out_inaccessible_entity_fields',
173
-            $entity,
174
-            $model,
175
-            $request_type
176
-        );
177
-    }
142
+	/**
143
+	 * Takes a entity that's ready to be returned and removes fields which the user shouldn't be able to access.
144
+	 *
145
+	 * @param array $entity
146
+	 * @param EEM_Base $model
147
+	 * @param string $request_type one of the return values from EEM_Base::valid_cap_contexts()
148
+	 * @param ModelVersionInfo $model_version_info
149
+	 * @param string $primary_key_string result of EEM_Base::get_index_primary_key_string(), so that we can
150
+	 *                                               use this with models that have no primary key
151
+	 * @return array ready for converting into json
152
+	 */
153
+	public static function filterOutInaccessibleEntityFields(
154
+		$entity,
155
+		$model,
156
+		$request_type,
157
+		$model_version_info,
158
+		$primary_key_string = null
159
+	) {
160
+		foreach ($model->field_settings() as $field_name => $field_obj) {
161
+			if (
162
+				$model_version_info->fieldHasRenderedFormat($field_obj)
163
+				&& isset($entity[ $field_name ])
164
+				&& is_array($entity[ $field_name ])
165
+				&& isset($entity[ $field_name ]['raw'])
166
+			) {
167
+				unset($entity[ $field_name ]['raw']);
168
+			}
169
+		}
170
+		// theoretically we may want to filter out specific fields for specific models
171
+		return apply_filters(
172
+			'FHEE__Capabilities__filter_out_inaccessible_entity_fields',
173
+			$entity,
174
+			$model,
175
+			$request_type
176
+		);
177
+	}
178 178
 
179 179
 
180
-    /**
181
-     * Verifies the current user has at least partial access to do this action on this model.
182
-     * If not, throws an exception (so we can define the code that sets up this error object
183
-     * once)
184
-     *
185
-     * @param EEM_Base $model
186
-     * @param string   $model_action_context
187
-     * @param string   $action_name
188
-     * @return void
189
-     * @throws RestException
190
-     */
191
-    public static function verifyAtLeastPartialAccessTo($model, $model_action_context, $action_name = 'list')
192
-    {
193
-        if (! Capabilities::currentUserHasPartialAccessTo($model, $model_action_context)) {
194
-            $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
195
-            throw new RestException(
196
-                sprintf('rest_cannot_%s_%s', strtolower($action_name), $model_name_plural),
197
-                sprintf(
198
-                    esc_html__('Sorry, you are not allowed to %1$s %2$s. Missing permissions: %3$s', 'event_espresso'),
199
-                    $action_name,
200
-                    $model_name_plural,
201
-                    Capabilities::getMissingPermissionsString($model, $model_action_context)
202
-                ),
203
-                array('status' => 403)
204
-            );
205
-        }
206
-    }
180
+	/**
181
+	 * Verifies the current user has at least partial access to do this action on this model.
182
+	 * If not, throws an exception (so we can define the code that sets up this error object
183
+	 * once)
184
+	 *
185
+	 * @param EEM_Base $model
186
+	 * @param string   $model_action_context
187
+	 * @param string   $action_name
188
+	 * @return void
189
+	 * @throws RestException
190
+	 */
191
+	public static function verifyAtLeastPartialAccessTo($model, $model_action_context, $action_name = 'list')
192
+	{
193
+		if (! Capabilities::currentUserHasPartialAccessTo($model, $model_action_context)) {
194
+			$model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
195
+			throw new RestException(
196
+				sprintf('rest_cannot_%s_%s', strtolower($action_name), $model_name_plural),
197
+				sprintf(
198
+					esc_html__('Sorry, you are not allowed to %1$s %2$s. Missing permissions: %3$s', 'event_espresso'),
199
+					$action_name,
200
+					$model_name_plural,
201
+					Capabilities::getMissingPermissionsString($model, $model_action_context)
202
+				),
203
+				array('status' => 403)
204
+			);
205
+		}
206
+	}
207 207
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/RestIncomingQueryParamMetadata.php 2 patches
Indentation   +701 added lines, -701 removed lines patch added patch discarded remove patch
@@ -28,707 +28,707 @@
 block discarded – undo
28 28
  */
29 29
 class RestIncomingQueryParamMetadata
30 30
 {
31
-    private $query_param_key;
32
-    private $query_param_value;
33
-    /**
34
-     * @var RestIncomingQueryParamContext
35
-     */
36
-    private $context;
37
-
38
-    /**
39
-     * @var EE_Model_Field_Base|null
40
-     */
41
-    private $field;
42
-
43
-    /**
44
-     * @var string same as $query_param_key but has the * and anything after it removed
45
-     */
46
-    private $query_param_key_sans_stars;
47
-
48
-    /**
49
-     * @var string for timezone or timezone offset
50
-     */
51
-    private $timezone;
52
-
53
-    /**
54
-     * @var boolean if the field in $query_param_key is for a GMT field (eg `EVT_modified_gmt`)
55
-     */
56
-    private $is_gmt_field = false;
57
-
58
-    /**
59
-     * RestIncomingQueryParamMetadata constructor.
60
-     * You probably want to call
61
-     * @param string $query_param_key
62
-     * @param string $query_param_value
63
-     * @param RestIncomingQueryParamContext $context
64
-     */
65
-    public function __construct($query_param_key, $query_param_value, RestIncomingQueryParamContext $context)
66
-    {
67
-        $this->query_param_key = $query_param_key;
68
-        $this->query_param_value = $query_param_value;
69
-        $this->context = $context;
70
-        $this->determineFieldAndTimezone();
71
-    }
72
-
73
-    /**
74
-     * Gets the query parameter key. This may have been modified (see setQueryParamValue())
75
-     * @return string
76
-     */
77
-    public function getQueryParamKey()
78
-    {
79
-        return $this->query_param_key;
80
-    }
81
-
82
-    /**
83
-     * Modifies the query parameter key passed in (Eg this is done when rewriting the simplified specified operator REST
84
-     * query parameters into the legacy structure)
85
-     * @param string|array|int|float $query_param_value
86
-     */
87
-    private function setQueryParamValue($query_param_value)
88
-    {
89
-        $this->query_param_value = $query_param_value;
90
-    }
91
-
92
-    /**
93
-     * Gets the original query parameter value passed in.
94
-     * @return string
95
-     */
96
-    public function getQueryParamValue()
97
-    {
98
-        return $this->query_param_value;
99
-    }
100
-
101
-    /**
102
-     * Gets the context object.
103
-     * @return RestIncomingQueryParamContext
104
-     */
105
-    public function getContext()
106
-    {
107
-        return $this->context;
108
-    }
109
-
110
-    /**
111
-     * Sets the query parameter key. This may be used to rewrite a key into its non-GMT alternative.
112
-     * @param string $query_param_key
113
-     */
114
-    private function setQueryParamKey($query_param_key)
115
-    {
116
-        $this->query_param_key = $query_param_key;
117
-    }
118
-
119
-    /**
120
-     * Gets the field the query parameter key indicated. This may be null (in cases where the query parameter key
121
-     * did not indicate a field, eg if it were `OR`).
122
-     * @return EE_Model_Field_Base|null
123
-     */
124
-    public function getField()
125
-    {
126
-        return $this->field;
127
-    }
128
-
129
-    /**
130
-     * Gets the query parameter key (with the star and everything afterwards removed).
131
-     * @return string
132
-     */
133
-    public function getQueryParamKeySansStars()
134
-    {
135
-        return $this->query_param_key_sans_stars;
136
-    }
137
-
138
-    /**
139
-     * Gets the timezone associated with this model (the site timezone, except for GMT datetime fields).
140
-     * @return string
141
-     */
142
-    public function getTimezone()
143
-    {
144
-        return $this->timezone;
145
-    }
146
-
147
-    /**
148
-     * Returns whether or not this is a GMT field
149
-     * @return boolean
150
-     */
151
-    public function isGmtField()
152
-    {
153
-        return $this->is_gmt_field;
154
-    }
155
-
156
-    /**
157
-     * Sets the field indicated by the query parameter key (might be null).
158
-     * @param EE_Model_Field_Base|null $field
159
-     */
160
-    private function setField(EE_Model_Field_Base $field = null)
161
-    {
162
-        $this->field = $field;
163
-    }
164
-
165
-    /**
166
-     * Sets the query parameter key-with-stars-removed.
167
-     * @param string $query_param_key_sans_stars
168
-     */
169
-    private function setQueryParamKeySansStars($query_param_key_sans_stars)
170
-    {
171
-        $this->query_param_key_sans_stars = $query_param_key_sans_stars;
172
-    }
173
-
174
-    /**
175
-     * Sets the timezone (this could be a timezeon offset string).
176
-     * @param string $timezone
177
-     */
178
-    private function setTimezone($timezone)
179
-    {
180
-        $this->timezone = $timezone;
181
-    }
182
-
183
-    /**
184
-     * @param mixed $is_gmt_field
185
-     */
186
-    private function setIsGmtField($is_gmt_field)
187
-    {
188
-        $this->is_gmt_field = $is_gmt_field;
189
-    }
190
-
191
-    /**
192
-     * Determines what field, query param name, and query param name without stars, and timezone to use.
193
-     * @since 4.9.72.p
194
-     * @type EE_Model_Field_Base $field
195
-     * @return void {
196
-     * @throws EE_Error
197
-     * @throws InvalidDataTypeException
198
-     * @throws InvalidInterfaceException
199
-     * @throws InvalidArgumentException
200
-     */
201
-    private function determineFieldAndTimezone()
202
-    {
203
-        $this->setQueryParamKeySansStars(ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
204
-            $this->getQueryParamKey()
205
-        ));
206
-        $this->setField(ModelDataTranslator::deduceFieldFromQueryParam(
207
-            $this->getQueryParamKeySansStars(),
208
-            $this->getContext()->getModel()
209
-        ));
210
-        // double-check is it a *_gmt field?
211
-        if (
212
-            !$this->getField() instanceof EE_Model_Field_Base
213
-            && ModelDataTranslator::isGmtDateFieldName($this->getQueryParamKeySansStars())
214
-        ) {
215
-            // yep, take off '_gmt', and find the field
216
-            $this->setQueryParamKey(ModelDataTranslator::removeGmtFromFieldName($this->getQueryParamKeySansStars()));
217
-            $this->setField(ModelDataTranslator::deduceFieldFromQueryParam(
218
-                $this->getQueryParamKey(),
219
-                $this->context->getModel()
220
-            ));
221
-            $this->setTimezone('UTC');
222
-            $this->setIsGmtField(true);
223
-        } elseif ($this->getField() instanceof EE_Datetime_Field) {
224
-            // so it's not a GMT field. Set the timezone on the model to the default
225
-            $this->setTimezone(EEH_DTT_Helper::get_valid_timezone_string());
226
-        } else {
227
-            // just keep using what's already set for the timezone
228
-            $this->setTimezone($this->context->getModel()->get_timezone());
229
-        }
230
-        $this->assertOnlyAdminCanReadPasswordFields();
231
-    }
232
-
233
-    /**
234
-     * Throws an exception if a non-admin is trying to query by password.
235
-     * @since 4.9.74.p
236
-     * @throws RestException
237
-     */
238
-    private function assertOnlyAdminCanReadPasswordFields()
239
-    {
240
-        if (
241
-            $this->getField() instanceof EE_Password_Field
242
-            && ! current_user_can(EE_Restriction_Generator_Base::get_default_restrictions_cap())
243
-        ) {
244
-            // only full admins can query by password. sorry bub!
245
-            throw new RestException(
246
-                'only_admins_can_query_by_password',
247
-                // @codingStandardsIgnoreStart
248
-                esc_html__('You attempted to filter by a password field without the needed privileges. Only a full admin is allowed to do that.', 'event_espresso'),
249
-                // @codingStandardsIgnoreEnd
250
-                array(
251
-                    'status' => 403
252
-                )
253
-            );
254
-        }
255
-    }
256
-
257
-    /**
258
-     * Given a ton of input, determines the value to use for the models.
259
-     * @since 4.9.72.p
260
-     * @return array|null
261
-     * @throws DomainException
262
-     * @throws EE_Error
263
-     * @throws RestException
264
-     * @throws DomainException
265
-     */
266
-    public function determineConditionsQueryParameterValue()
267
-    {
268
-        if ($this->valueIsArrayDuringRead()) {
269
-            return $this->determineModelValueGivenRestInputArray();
270
-        }
271
-        return ModelDataTranslator::prepareFieldValueFromJson(
272
-            $this->getField(),
273
-            $this->getQueryParamValue(),
274
-            $this->getContext()->getRequestedVersion(),
275
-            $this->getTimezone()
276
-        );
277
-    }
278
-
279
-    /**
280
-     * Given that the array value provided was itself an array, handles finding the correct value to pass to the model.
281
-     * @since 4.9.72.p
282
-     * @return array|null
283
-     * @throws RestException
284
-     */
285
-    private function determineModelValueGivenRestInputArray()
286
-    {
287
-        $this->transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax();
288
-        // did they specify an operator?
289
-        if ($this->valueIsLegacySpecifiedOperator()) {
290
-            $query_param_value = $this->getQueryParamValue();
291
-            $sub_array_key = $query_param_value[0];
292
-            $translated_value = array($sub_array_key);
293
-            if ($this->operatorIsNAry($sub_array_key)) {
294
-                $translated_value[] = $this->prepareValuesFromJson($query_param_value[1]);
295
-            } elseif ($this->operatorIsTernary($sub_array_key)) {
296
-                $translated_value[] = array(
297
-                    $this->prepareValuesFromJson($query_param_value[1][0]),
298
-                    $this->prepareValuesFromJson($query_param_value[1][1])
299
-                );
300
-            } elseif ($this->operatorIsLike($sub_array_key)) {
301
-                // we want to leave this value mostly-as-is (eg don't force it to be a float
302
-                // or a boolean or an enum value. Leave it as-is with wildcards etc)
303
-                // but do verify it at least doesn't have any serialized data
304
-                ModelDataTranslator::throwExceptionIfContainsSerializedData($query_param_value[1]);
305
-                $translated_value[] = $query_param_value[1];
306
-            } elseif ($this->operatorIsUnary($sub_array_key)) {
307
-                // no arguments should have been provided, so don't look for any
308
-            } elseif ($this->operatorisBinary($sub_array_key)) {
309
-                // it's a valid operator, but none of the exceptions. Treat it normally.
310
-                $translated_value[] = $this->prepareValuesFromJson($query_param_value[1]);
311
-            } else {
312
-                // so they provided a valid operator, but wrong number of arguments
313
-                $this->throwWrongNumberOfArgsExceptionIfDebugging($sub_array_key);
314
-                $translated_value = null;
315
-            }
316
-        } else {
317
-            // so they didn't provide a valid operator
318
-            // if we aren't in debug mode, then just try our best to fulfill the user's request
319
-            $this->throwInvalidOperatorExceptionIfDebugging();
320
-            $translated_value = null;
321
-        }
322
-        return $translated_value;
323
-    }
324
-
325
-    /**
326
-     * Returns if this request is a "read" request and the value provided was an array.
327
-     * This will indicate is such things as `array('<', 123)` and `array('IN', array(1,2,3))` are acceptable or not.
328
-     * @since 4.9.72.p
329
-     * @return boolean
330
-     */
331
-    private function valueIsArrayDuringRead()
332
-    {
333
-        return !$this->getContext()->isWriting() && is_array($this->getQueryParamValue());
334
-    }
335
-
336
-    /**
337
-     * Returns if the value provided was an associative array (we should have already verified it's an array of some
338
-     * sort). If the value is an associative array, it had better be in the simplified specified operator structure.
339
-     * @since 4.9.72.p
340
-     * @return boolean
341
-     */
342
-    private function valueIsAssociativeArray()
343
-    {
344
-        return !EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue());
345
-    }
346
-
347
-    /**
348
-     * Checks if the array value is itself an array that fits into the simplified specified operator structure
349
-     * (eg `array('!=' => 123)`).
350
-     * @since 4.9.72.p
351
-     * @return boolean
352
-     */
353
-    private function valueIsSimplifiedSpecifiedOperator()
354
-    {
355
-        return count($this->getQueryParamValue()) === 1
356
-            && array_key_exists(
357
-                key($this->getQueryParamValue()),
358
-                $this->getContext()->getModel()->valid_operators()
359
-            );
360
-    }
361
-
362
-    /**
363
-     * Throws an exception if the sub-value is an array (eg `array('!=' => array())`). It needs to just be a string,
364
-     * of either comma-separated-values, or a JSON array.
365
-     * @since 4.9.72.p
366
-     * @param $sub_array_key
367
-     * @param $sub_array_value
368
-     * @throws RestException
369
-     */
370
-    private function assertSubValueIsntArray($sub_array_key, $sub_array_value)
371
-    {
372
-        if (is_array($sub_array_value) && EED_Core_Rest_Api::debugMode()) {
373
-            throw new RestException(
374
-                'csv_or_json_string_only',
375
-                sprintf(
376
-                    /* translators: 1: variable name*/
377
-                    esc_html__(
378
-                        'The value provided for the operator "%1$s" should be comma-separated value string or a JSON array.',
379
-                        'event_espresso'
380
-                    ),
381
-                    $sub_array_key
382
-                ),
383
-                array(
384
-                    'status' => 400,
385
-                )
386
-            );
387
-        }
388
-    }
389
-
390
-    /**
391
-     * Determines if the sub-array key is an operator taking 3 or more operators.
392
-     * @since 4.9.72.p
393
-     * @param $sub_array_key
394
-     * @return boolean
395
-     */
396
-    private function subArrayKeyIsNonBinaryOperator($sub_array_key)
397
-    {
398
-        return array_key_exists(
399
-            $sub_array_key,
400
-            array_merge(
401
-                $this->getContext()->getModel()->valid_in_style_operators(),
402
-                $this->getContext()->getModel()->valid_between_style_operators()
403
-            )
404
-        );
405
-    }
406
-
407
-    /**
408
-     * Given that the $sub_array_key is a string, checks if it's an operator taking only 1 argument.
409
-     * @since 4.9.72.p
410
-     * @param string $sub_array_key
411
-     * @return boolean
412
-     */
413
-    private function subArrayKeyIsUnaryOperator($sub_array_key)
414
-    {
415
-        return array_key_exists(
416
-            $sub_array_key,
417
-            $this->getContext()->getModel()->valid_null_style_operators()
418
-        );
419
-    }
420
-
421
-    /**
422
-     * Parses the $sub_array_value string into an array (given it could either be a comma-separated-list or a JSON
423
-     * array). eg `"1,2,3"` or `"[1,2,3]"` into `array(1,2,3)`.
424
-     * @since 4.9.72.p
425
-     * @param $sub_array_value
426
-     * @return array|mixed|object
427
-     */
428
-    private function extractQuickStyleSpecifiedOperatorValue($sub_array_value)
429
-    {
430
-        // the value should be JSON or CSV
431
-        $values = json_decode($sub_array_value);
432
-        if (!is_array($values)) {
433
-            $values = array_filter(
434
-                array_map(
435
-                    'trim',
436
-                    explode(
437
-                        ',',
438
-                        $sub_array_value
439
-                    )
440
-                )
441
-            );
442
-        }
443
-        return $values;
444
-    }
445
-
446
-    /**
447
-     * Throws an exception if the value isn't a simplified specified operator (only called when we expect that).
448
-     * @since 4.9.72.p
449
-     * @throws RestException
450
-     */
451
-    private function assertSimplifiedSpecifiedOperator()
452
-    {
453
-        if (!$this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) {
454
-            throw new RestException(
455
-                'numerically_indexed_array_of_values_only',
456
-                sprintf(
457
-                    /* translators: 1: variable name*/
458
-                    esc_html__(
459
-                        'The array provided for the parameter "%1$s" should be numerically indexed.',
460
-                        'event_espresso'
461
-                    ),
462
-                    $this->getQueryParamKey()
463
-                ),
464
-                array(
465
-                    'status' => 400,
466
-                )
467
-            );
468
-        }
469
-    }
470
-
471
-    /**
472
-     * If query_param_value were in the simplified specific operator structure, change it into the legacy structure.
473
-     * @since 4.9.72.p
474
-     * @throws RestException
475
-     */
476
-    private function transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax()
477
-    {
478
-        if ($this->valueIsAssociativeArray()) {
479
-            $this->assertSimplifiedSpecifiedOperator();
480
-            $query_param_value = $this->getQueryParamValue();
481
-            $sub_array_value = reset($query_param_value);
482
-            $sub_array_key = key($query_param_value);
483
-            $this->assertSubValueIsntArray($sub_array_key, $sub_array_value);
484
-            // they're doing something like "&where[EVT_ID][IN]=1,2,3" or "&where[EVT_ID][>]=5"
485
-            if ($this->subArrayKeyIsNonBinaryOperator($sub_array_key)) {
486
-                $this->setQueryParamValue(array(
487
-                    $sub_array_key,
488
-                    $this->extractQuickStyleSpecifiedOperatorValue($sub_array_value)
489
-                ));
490
-            } elseif ($this->subArrayKeyIsUnaryOperator($sub_array_key)) {
491
-                $this->setQueryParamValue(array($sub_array_key));
492
-            } else {
493
-                $this->setQueryParamValue(array($sub_array_key, $sub_array_value));
494
-            }
495
-        }
496
-    }
497
-
498
-    /**
499
-     * Returns true is the value is an array using the legacy structure to specify the operator. Eg `array('!=',123)`.
500
-     * @since 4.9.72.p
501
-     * @return boolean
502
-     */
503
-    private function valueIsLegacySpecifiedOperator()
504
-    {
505
-        $valid_operators = $this->getContext()->getModel()->valid_operators();
506
-        $query_param_value = $this->getQueryParamValue();
507
-        return isset($query_param_value[0])
508
-            && isset($valid_operators[ $query_param_value[0] ]);
509
-    }
510
-
511
-    /**
512
-     * Returns true if the value specified operator accepts arbitrary number of arguments, like "IN".
513
-     * @since 4.9.72.p
514
-     * @param $operator
515
-     * @return boolean
516
-     */
517
-    private function operatorIsNAry($operator)
518
-    {
519
-        $valueArray = $this->getQueryParamValue();
520
-        return array_key_exists(
521
-            $operator,
522
-            $this->getContext()->getModel()->valid_in_style_operators()
523
-        )
524
-            && isset($valueArray[1])
525
-            && is_array($valueArray[1])
526
-            && !isset($valueArray[2]);
527
-    }
528
-
529
-    /**
530
-     * Returns true if the operator accepts 3 arguments (eg "BETWEEN").
531
-     * So we're looking for a value that looks like
532
-     * `array('BETWEEN', array('2015-01-01T00:00:00', '2016-01-01T00:00:00'))`.
533
-     * @since 4.9.72.p
534
-     * @param $operator
535
-     * @return boolean
536
-     */
537
-    private function operatorIsTernary($operator)
538
-    {
539
-        $query_param_value = $this->getQueryParamValue();
540
-        return array_key_exists($operator, $this->getContext()->getModel()->valid_between_style_operators())
541
-            && isset($query_param_value[1])
542
-            && is_array($query_param_value[1])
543
-            && isset($query_param_value[1][0], $query_param_value[1][1])
544
-            && !isset($query_param_value[1][2])
545
-            && !isset($query_param_value[2]);
546
-    }
547
-
548
-    /**
549
-     * Returns true if the operator is a similar to LIKE, indicating the value may have wildcards we should leave alone.
550
-     * @since 4.9.72.p
551
-     * @param $operator
552
-     * @return boolean
553
-     */
554
-    private function operatorIsLike($operator)
555
-    {
556
-        $query_param_value = $this->getQueryParamValue();
557
-        return array_key_exists($operator, $this->getContext()->getModel()->valid_like_style_operators())
558
-            && isset($query_param_value[1])
559
-            && !isset($query_param_value[2]);
560
-    }
561
-
562
-    /**
563
-     * Returns true if the operator only takes one argument (eg it's like `IS NULL`).
564
-     * @since 4.9.72.p
565
-     * @param $operator
566
-     * @return boolean
567
-     */
568
-    private function operatorIsUnary($operator)
569
-    {
570
-        $query_param_value = $this->getQueryParamValue();
571
-        return array_key_exists($operator, $this->getContext()->getModel()->valid_null_style_operators())
572
-            && !isset($query_param_value[1]);
573
-    }
574
-
575
-    /**
576
-     * Returns true if the operator specified is a binary opeator (eg `=`, `!=`)
577
-     * @since 4.9.72.p
578
-     * @param $operator
579
-     * @return boolean
580
-     */
581
-    private function operatorisBinary($operator)
582
-    {
583
-        $query_param_value = $this->getQueryParamValue();
584
-        $model = $this->getContext()->getModel();
585
-        return isset($query_param_value[1])
586
-            && !isset($query_param_value[2])
587
-            && !array_key_exists(
588
-                $operator,
589
-                array_merge(
590
-                    $model->valid_in_style_operators(),
591
-                    $model->valid_null_style_operators(),
592
-                    $model->valid_like_style_operators(),
593
-                    $model->valid_between_style_operators()
594
-                )
595
-            );
596
-    }
597
-
598
-    /**
599
-     * If we're debugging, throws an exception saying that the wrong number of arguments was provided.
600
-     * @since 4.9.72.p
601
-     * @param $operator
602
-     * @throws RestException
603
-     */
604
-    private function throwWrongNumberOfArgsExceptionIfDebugging($operator)
605
-    {
606
-        if (EED_Core_Rest_Api::debugMode()) {
607
-            throw new RestException(
608
-                'wrong_number_of_arguments',
609
-                sprintf(
610
-                    esc_html__(
611
-                        'The operator you provided, "%1$s" had the wrong number of arguments',
612
-                        'event_espresso'
613
-                    ),
614
-                    $operator
615
-                ),
616
-                array(
617
-                    'status' => 400,
618
-                )
619
-            );
620
-        }
621
-    }
622
-
623
-    /**
624
-     * Wrapper for ModelDataTranslator::prepareFieldValuesFromJson(), just a tad more DRY.
625
-     * @since 4.9.72.p
626
-     * @param $value
627
-     * @return mixed
628
-     * @throws RestException
629
-     */
630
-    private function prepareValuesFromJson($value)
631
-    {
632
-        return ModelDataTranslator::prepareFieldValuesFromJson(
633
-            $this->getField(),
634
-            $value,
635
-            $this->getContext()->getRequestedVersion(),
636
-            $this->getTimezone()
637
-        );
638
-    }
639
-
640
-    /**
641
-     * Throws an exception if an invalid operator was specified and we're debugging.
642
-     * @since 4.9.72.p
643
-     * @throws RestException
644
-     */
645
-    private function throwInvalidOperatorExceptionIfDebugging()
646
-    {
647
-        // so they didn't provide a valid operator
648
-        if (EED_Core_Rest_Api::debugMode()) {
649
-            throw new RestException(
650
-                'invalid_operator',
651
-                sprintf(
652
-                    esc_html__(
653
-                        'You provided an invalid parameter, with key "%1$s" and value "%2$s"',
654
-                        'event_espresso'
655
-                    ),
656
-                    $this->getQueryParamKey(),
657
-                    $this->getQueryParamValue()
658
-                ),
659
-                array(
660
-                    'status' => 400,
661
-                )
662
-            );
663
-        }
664
-    }
665
-
666
-    /**
667
-     * Returns true if the query_param_key was a logic query parameter, eg `OR`, `AND`, `NOT`, `OR*`, etc.
668
-     * @since 4.9.72.p
669
-     * @return boolean
670
-     */
671
-    private function isLogicQueryParam()
672
-    {
673
-        return in_array($this->getQueryParamKeySansStars(), $this->getContext()->getModel()->logic_query_param_keys());
674
-    }
675
-
676
-
677
-    /**
678
-     * If the query param isn't for a field, it must be a nested query parameter which requires different logic.
679
-     * @since 4.9.72.p
680
-     * @return array
681
-     * @throws DomainException
682
-     * @throws EE_Error
683
-     * @throws RestException
684
-     * @throws InvalidDataTypeException
685
-     * @throws InvalidInterfaceException
686
-     * @throws InvalidArgumentException
687
-     */
688
-    public function determineNestedConditionQueryParameters()
689
-    {
690
-
691
-        // so this param doesn't correspond to a field eh?
692
-        if ($this->getContext()->isWriting()) {
693
-            // always tell API clients about invalid parameters when they're creating data. Otherwise,
694
-            // they are probably going to create invalid data
695
-            throw new RestException(
696
-                'invalid_field',
697
-                sprintf(
698
-                    /* translators: 1: variable name */
699
-                    esc_html__('You have provided an invalid parameter: "%1$s"', 'event_espresso'),
700
-                    $this->getQueryParamKey()
701
-                )
702
-            );
703
-        }
704
-        // so it's not for a field, is it a logic query param key?
705
-        if ($this->isLogicQueryParam()) {
706
-            return ModelDataTranslator::prepareConditionsQueryParamsForModels(
707
-                $this->getQueryParamValue(),
708
-                $this->getContext()->getModel(),
709
-                $this->getContext()->getRequestedVersion()
710
-            );
711
-        }
712
-        if (EED_Core_Rest_Api::debugMode()) {
713
-            // only tell API clients they got it wrong if we're in debug mode
714
-            // otherwise try our best ot fulfill their request by ignoring this invalid data
715
-            throw new RestException(
716
-                'invalid_parameter',
717
-                sprintf(
718
-                    /* translators: 1: variable name */
719
-                    esc_html__(
720
-                        'You provided an invalid parameter, with key "%1$s"',
721
-                        'event_espresso'
722
-                    ),
723
-                    $this->getQueryParamKey()
724
-                ),
725
-                array(
726
-                    'status' => 400,
727
-                )
728
-            );
729
-        }
730
-        return null;
731
-    }
31
+	private $query_param_key;
32
+	private $query_param_value;
33
+	/**
34
+	 * @var RestIncomingQueryParamContext
35
+	 */
36
+	private $context;
37
+
38
+	/**
39
+	 * @var EE_Model_Field_Base|null
40
+	 */
41
+	private $field;
42
+
43
+	/**
44
+	 * @var string same as $query_param_key but has the * and anything after it removed
45
+	 */
46
+	private $query_param_key_sans_stars;
47
+
48
+	/**
49
+	 * @var string for timezone or timezone offset
50
+	 */
51
+	private $timezone;
52
+
53
+	/**
54
+	 * @var boolean if the field in $query_param_key is for a GMT field (eg `EVT_modified_gmt`)
55
+	 */
56
+	private $is_gmt_field = false;
57
+
58
+	/**
59
+	 * RestIncomingQueryParamMetadata constructor.
60
+	 * You probably want to call
61
+	 * @param string $query_param_key
62
+	 * @param string $query_param_value
63
+	 * @param RestIncomingQueryParamContext $context
64
+	 */
65
+	public function __construct($query_param_key, $query_param_value, RestIncomingQueryParamContext $context)
66
+	{
67
+		$this->query_param_key = $query_param_key;
68
+		$this->query_param_value = $query_param_value;
69
+		$this->context = $context;
70
+		$this->determineFieldAndTimezone();
71
+	}
72
+
73
+	/**
74
+	 * Gets the query parameter key. This may have been modified (see setQueryParamValue())
75
+	 * @return string
76
+	 */
77
+	public function getQueryParamKey()
78
+	{
79
+		return $this->query_param_key;
80
+	}
81
+
82
+	/**
83
+	 * Modifies the query parameter key passed in (Eg this is done when rewriting the simplified specified operator REST
84
+	 * query parameters into the legacy structure)
85
+	 * @param string|array|int|float $query_param_value
86
+	 */
87
+	private function setQueryParamValue($query_param_value)
88
+	{
89
+		$this->query_param_value = $query_param_value;
90
+	}
91
+
92
+	/**
93
+	 * Gets the original query parameter value passed in.
94
+	 * @return string
95
+	 */
96
+	public function getQueryParamValue()
97
+	{
98
+		return $this->query_param_value;
99
+	}
100
+
101
+	/**
102
+	 * Gets the context object.
103
+	 * @return RestIncomingQueryParamContext
104
+	 */
105
+	public function getContext()
106
+	{
107
+		return $this->context;
108
+	}
109
+
110
+	/**
111
+	 * Sets the query parameter key. This may be used to rewrite a key into its non-GMT alternative.
112
+	 * @param string $query_param_key
113
+	 */
114
+	private function setQueryParamKey($query_param_key)
115
+	{
116
+		$this->query_param_key = $query_param_key;
117
+	}
118
+
119
+	/**
120
+	 * Gets the field the query parameter key indicated. This may be null (in cases where the query parameter key
121
+	 * did not indicate a field, eg if it were `OR`).
122
+	 * @return EE_Model_Field_Base|null
123
+	 */
124
+	public function getField()
125
+	{
126
+		return $this->field;
127
+	}
128
+
129
+	/**
130
+	 * Gets the query parameter key (with the star and everything afterwards removed).
131
+	 * @return string
132
+	 */
133
+	public function getQueryParamKeySansStars()
134
+	{
135
+		return $this->query_param_key_sans_stars;
136
+	}
137
+
138
+	/**
139
+	 * Gets the timezone associated with this model (the site timezone, except for GMT datetime fields).
140
+	 * @return string
141
+	 */
142
+	public function getTimezone()
143
+	{
144
+		return $this->timezone;
145
+	}
146
+
147
+	/**
148
+	 * Returns whether or not this is a GMT field
149
+	 * @return boolean
150
+	 */
151
+	public function isGmtField()
152
+	{
153
+		return $this->is_gmt_field;
154
+	}
155
+
156
+	/**
157
+	 * Sets the field indicated by the query parameter key (might be null).
158
+	 * @param EE_Model_Field_Base|null $field
159
+	 */
160
+	private function setField(EE_Model_Field_Base $field = null)
161
+	{
162
+		$this->field = $field;
163
+	}
164
+
165
+	/**
166
+	 * Sets the query parameter key-with-stars-removed.
167
+	 * @param string $query_param_key_sans_stars
168
+	 */
169
+	private function setQueryParamKeySansStars($query_param_key_sans_stars)
170
+	{
171
+		$this->query_param_key_sans_stars = $query_param_key_sans_stars;
172
+	}
173
+
174
+	/**
175
+	 * Sets the timezone (this could be a timezeon offset string).
176
+	 * @param string $timezone
177
+	 */
178
+	private function setTimezone($timezone)
179
+	{
180
+		$this->timezone = $timezone;
181
+	}
182
+
183
+	/**
184
+	 * @param mixed $is_gmt_field
185
+	 */
186
+	private function setIsGmtField($is_gmt_field)
187
+	{
188
+		$this->is_gmt_field = $is_gmt_field;
189
+	}
190
+
191
+	/**
192
+	 * Determines what field, query param name, and query param name without stars, and timezone to use.
193
+	 * @since 4.9.72.p
194
+	 * @type EE_Model_Field_Base $field
195
+	 * @return void {
196
+	 * @throws EE_Error
197
+	 * @throws InvalidDataTypeException
198
+	 * @throws InvalidInterfaceException
199
+	 * @throws InvalidArgumentException
200
+	 */
201
+	private function determineFieldAndTimezone()
202
+	{
203
+		$this->setQueryParamKeySansStars(ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
204
+			$this->getQueryParamKey()
205
+		));
206
+		$this->setField(ModelDataTranslator::deduceFieldFromQueryParam(
207
+			$this->getQueryParamKeySansStars(),
208
+			$this->getContext()->getModel()
209
+		));
210
+		// double-check is it a *_gmt field?
211
+		if (
212
+			!$this->getField() instanceof EE_Model_Field_Base
213
+			&& ModelDataTranslator::isGmtDateFieldName($this->getQueryParamKeySansStars())
214
+		) {
215
+			// yep, take off '_gmt', and find the field
216
+			$this->setQueryParamKey(ModelDataTranslator::removeGmtFromFieldName($this->getQueryParamKeySansStars()));
217
+			$this->setField(ModelDataTranslator::deduceFieldFromQueryParam(
218
+				$this->getQueryParamKey(),
219
+				$this->context->getModel()
220
+			));
221
+			$this->setTimezone('UTC');
222
+			$this->setIsGmtField(true);
223
+		} elseif ($this->getField() instanceof EE_Datetime_Field) {
224
+			// so it's not a GMT field. Set the timezone on the model to the default
225
+			$this->setTimezone(EEH_DTT_Helper::get_valid_timezone_string());
226
+		} else {
227
+			// just keep using what's already set for the timezone
228
+			$this->setTimezone($this->context->getModel()->get_timezone());
229
+		}
230
+		$this->assertOnlyAdminCanReadPasswordFields();
231
+	}
232
+
233
+	/**
234
+	 * Throws an exception if a non-admin is trying to query by password.
235
+	 * @since 4.9.74.p
236
+	 * @throws RestException
237
+	 */
238
+	private function assertOnlyAdminCanReadPasswordFields()
239
+	{
240
+		if (
241
+			$this->getField() instanceof EE_Password_Field
242
+			&& ! current_user_can(EE_Restriction_Generator_Base::get_default_restrictions_cap())
243
+		) {
244
+			// only full admins can query by password. sorry bub!
245
+			throw new RestException(
246
+				'only_admins_can_query_by_password',
247
+				// @codingStandardsIgnoreStart
248
+				esc_html__('You attempted to filter by a password field without the needed privileges. Only a full admin is allowed to do that.', 'event_espresso'),
249
+				// @codingStandardsIgnoreEnd
250
+				array(
251
+					'status' => 403
252
+				)
253
+			);
254
+		}
255
+	}
256
+
257
+	/**
258
+	 * Given a ton of input, determines the value to use for the models.
259
+	 * @since 4.9.72.p
260
+	 * @return array|null
261
+	 * @throws DomainException
262
+	 * @throws EE_Error
263
+	 * @throws RestException
264
+	 * @throws DomainException
265
+	 */
266
+	public function determineConditionsQueryParameterValue()
267
+	{
268
+		if ($this->valueIsArrayDuringRead()) {
269
+			return $this->determineModelValueGivenRestInputArray();
270
+		}
271
+		return ModelDataTranslator::prepareFieldValueFromJson(
272
+			$this->getField(),
273
+			$this->getQueryParamValue(),
274
+			$this->getContext()->getRequestedVersion(),
275
+			$this->getTimezone()
276
+		);
277
+	}
278
+
279
+	/**
280
+	 * Given that the array value provided was itself an array, handles finding the correct value to pass to the model.
281
+	 * @since 4.9.72.p
282
+	 * @return array|null
283
+	 * @throws RestException
284
+	 */
285
+	private function determineModelValueGivenRestInputArray()
286
+	{
287
+		$this->transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax();
288
+		// did they specify an operator?
289
+		if ($this->valueIsLegacySpecifiedOperator()) {
290
+			$query_param_value = $this->getQueryParamValue();
291
+			$sub_array_key = $query_param_value[0];
292
+			$translated_value = array($sub_array_key);
293
+			if ($this->operatorIsNAry($sub_array_key)) {
294
+				$translated_value[] = $this->prepareValuesFromJson($query_param_value[1]);
295
+			} elseif ($this->operatorIsTernary($sub_array_key)) {
296
+				$translated_value[] = array(
297
+					$this->prepareValuesFromJson($query_param_value[1][0]),
298
+					$this->prepareValuesFromJson($query_param_value[1][1])
299
+				);
300
+			} elseif ($this->operatorIsLike($sub_array_key)) {
301
+				// we want to leave this value mostly-as-is (eg don't force it to be a float
302
+				// or a boolean or an enum value. Leave it as-is with wildcards etc)
303
+				// but do verify it at least doesn't have any serialized data
304
+				ModelDataTranslator::throwExceptionIfContainsSerializedData($query_param_value[1]);
305
+				$translated_value[] = $query_param_value[1];
306
+			} elseif ($this->operatorIsUnary($sub_array_key)) {
307
+				// no arguments should have been provided, so don't look for any
308
+			} elseif ($this->operatorisBinary($sub_array_key)) {
309
+				// it's a valid operator, but none of the exceptions. Treat it normally.
310
+				$translated_value[] = $this->prepareValuesFromJson($query_param_value[1]);
311
+			} else {
312
+				// so they provided a valid operator, but wrong number of arguments
313
+				$this->throwWrongNumberOfArgsExceptionIfDebugging($sub_array_key);
314
+				$translated_value = null;
315
+			}
316
+		} else {
317
+			// so they didn't provide a valid operator
318
+			// if we aren't in debug mode, then just try our best to fulfill the user's request
319
+			$this->throwInvalidOperatorExceptionIfDebugging();
320
+			$translated_value = null;
321
+		}
322
+		return $translated_value;
323
+	}
324
+
325
+	/**
326
+	 * Returns if this request is a "read" request and the value provided was an array.
327
+	 * This will indicate is such things as `array('<', 123)` and `array('IN', array(1,2,3))` are acceptable or not.
328
+	 * @since 4.9.72.p
329
+	 * @return boolean
330
+	 */
331
+	private function valueIsArrayDuringRead()
332
+	{
333
+		return !$this->getContext()->isWriting() && is_array($this->getQueryParamValue());
334
+	}
335
+
336
+	/**
337
+	 * Returns if the value provided was an associative array (we should have already verified it's an array of some
338
+	 * sort). If the value is an associative array, it had better be in the simplified specified operator structure.
339
+	 * @since 4.9.72.p
340
+	 * @return boolean
341
+	 */
342
+	private function valueIsAssociativeArray()
343
+	{
344
+		return !EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue());
345
+	}
346
+
347
+	/**
348
+	 * Checks if the array value is itself an array that fits into the simplified specified operator structure
349
+	 * (eg `array('!=' => 123)`).
350
+	 * @since 4.9.72.p
351
+	 * @return boolean
352
+	 */
353
+	private function valueIsSimplifiedSpecifiedOperator()
354
+	{
355
+		return count($this->getQueryParamValue()) === 1
356
+			&& array_key_exists(
357
+				key($this->getQueryParamValue()),
358
+				$this->getContext()->getModel()->valid_operators()
359
+			);
360
+	}
361
+
362
+	/**
363
+	 * Throws an exception if the sub-value is an array (eg `array('!=' => array())`). It needs to just be a string,
364
+	 * of either comma-separated-values, or a JSON array.
365
+	 * @since 4.9.72.p
366
+	 * @param $sub_array_key
367
+	 * @param $sub_array_value
368
+	 * @throws RestException
369
+	 */
370
+	private function assertSubValueIsntArray($sub_array_key, $sub_array_value)
371
+	{
372
+		if (is_array($sub_array_value) && EED_Core_Rest_Api::debugMode()) {
373
+			throw new RestException(
374
+				'csv_or_json_string_only',
375
+				sprintf(
376
+					/* translators: 1: variable name*/
377
+					esc_html__(
378
+						'The value provided for the operator "%1$s" should be comma-separated value string or a JSON array.',
379
+						'event_espresso'
380
+					),
381
+					$sub_array_key
382
+				),
383
+				array(
384
+					'status' => 400,
385
+				)
386
+			);
387
+		}
388
+	}
389
+
390
+	/**
391
+	 * Determines if the sub-array key is an operator taking 3 or more operators.
392
+	 * @since 4.9.72.p
393
+	 * @param $sub_array_key
394
+	 * @return boolean
395
+	 */
396
+	private function subArrayKeyIsNonBinaryOperator($sub_array_key)
397
+	{
398
+		return array_key_exists(
399
+			$sub_array_key,
400
+			array_merge(
401
+				$this->getContext()->getModel()->valid_in_style_operators(),
402
+				$this->getContext()->getModel()->valid_between_style_operators()
403
+			)
404
+		);
405
+	}
406
+
407
+	/**
408
+	 * Given that the $sub_array_key is a string, checks if it's an operator taking only 1 argument.
409
+	 * @since 4.9.72.p
410
+	 * @param string $sub_array_key
411
+	 * @return boolean
412
+	 */
413
+	private function subArrayKeyIsUnaryOperator($sub_array_key)
414
+	{
415
+		return array_key_exists(
416
+			$sub_array_key,
417
+			$this->getContext()->getModel()->valid_null_style_operators()
418
+		);
419
+	}
420
+
421
+	/**
422
+	 * Parses the $sub_array_value string into an array (given it could either be a comma-separated-list or a JSON
423
+	 * array). eg `"1,2,3"` or `"[1,2,3]"` into `array(1,2,3)`.
424
+	 * @since 4.9.72.p
425
+	 * @param $sub_array_value
426
+	 * @return array|mixed|object
427
+	 */
428
+	private function extractQuickStyleSpecifiedOperatorValue($sub_array_value)
429
+	{
430
+		// the value should be JSON or CSV
431
+		$values = json_decode($sub_array_value);
432
+		if (!is_array($values)) {
433
+			$values = array_filter(
434
+				array_map(
435
+					'trim',
436
+					explode(
437
+						',',
438
+						$sub_array_value
439
+					)
440
+				)
441
+			);
442
+		}
443
+		return $values;
444
+	}
445
+
446
+	/**
447
+	 * Throws an exception if the value isn't a simplified specified operator (only called when we expect that).
448
+	 * @since 4.9.72.p
449
+	 * @throws RestException
450
+	 */
451
+	private function assertSimplifiedSpecifiedOperator()
452
+	{
453
+		if (!$this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) {
454
+			throw new RestException(
455
+				'numerically_indexed_array_of_values_only',
456
+				sprintf(
457
+					/* translators: 1: variable name*/
458
+					esc_html__(
459
+						'The array provided for the parameter "%1$s" should be numerically indexed.',
460
+						'event_espresso'
461
+					),
462
+					$this->getQueryParamKey()
463
+				),
464
+				array(
465
+					'status' => 400,
466
+				)
467
+			);
468
+		}
469
+	}
470
+
471
+	/**
472
+	 * If query_param_value were in the simplified specific operator structure, change it into the legacy structure.
473
+	 * @since 4.9.72.p
474
+	 * @throws RestException
475
+	 */
476
+	private function transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax()
477
+	{
478
+		if ($this->valueIsAssociativeArray()) {
479
+			$this->assertSimplifiedSpecifiedOperator();
480
+			$query_param_value = $this->getQueryParamValue();
481
+			$sub_array_value = reset($query_param_value);
482
+			$sub_array_key = key($query_param_value);
483
+			$this->assertSubValueIsntArray($sub_array_key, $sub_array_value);
484
+			// they're doing something like "&where[EVT_ID][IN]=1,2,3" or "&where[EVT_ID][>]=5"
485
+			if ($this->subArrayKeyIsNonBinaryOperator($sub_array_key)) {
486
+				$this->setQueryParamValue(array(
487
+					$sub_array_key,
488
+					$this->extractQuickStyleSpecifiedOperatorValue($sub_array_value)
489
+				));
490
+			} elseif ($this->subArrayKeyIsUnaryOperator($sub_array_key)) {
491
+				$this->setQueryParamValue(array($sub_array_key));
492
+			} else {
493
+				$this->setQueryParamValue(array($sub_array_key, $sub_array_value));
494
+			}
495
+		}
496
+	}
497
+
498
+	/**
499
+	 * Returns true is the value is an array using the legacy structure to specify the operator. Eg `array('!=',123)`.
500
+	 * @since 4.9.72.p
501
+	 * @return boolean
502
+	 */
503
+	private function valueIsLegacySpecifiedOperator()
504
+	{
505
+		$valid_operators = $this->getContext()->getModel()->valid_operators();
506
+		$query_param_value = $this->getQueryParamValue();
507
+		return isset($query_param_value[0])
508
+			&& isset($valid_operators[ $query_param_value[0] ]);
509
+	}
510
+
511
+	/**
512
+	 * Returns true if the value specified operator accepts arbitrary number of arguments, like "IN".
513
+	 * @since 4.9.72.p
514
+	 * @param $operator
515
+	 * @return boolean
516
+	 */
517
+	private function operatorIsNAry($operator)
518
+	{
519
+		$valueArray = $this->getQueryParamValue();
520
+		return array_key_exists(
521
+			$operator,
522
+			$this->getContext()->getModel()->valid_in_style_operators()
523
+		)
524
+			&& isset($valueArray[1])
525
+			&& is_array($valueArray[1])
526
+			&& !isset($valueArray[2]);
527
+	}
528
+
529
+	/**
530
+	 * Returns true if the operator accepts 3 arguments (eg "BETWEEN").
531
+	 * So we're looking for a value that looks like
532
+	 * `array('BETWEEN', array('2015-01-01T00:00:00', '2016-01-01T00:00:00'))`.
533
+	 * @since 4.9.72.p
534
+	 * @param $operator
535
+	 * @return boolean
536
+	 */
537
+	private function operatorIsTernary($operator)
538
+	{
539
+		$query_param_value = $this->getQueryParamValue();
540
+		return array_key_exists($operator, $this->getContext()->getModel()->valid_between_style_operators())
541
+			&& isset($query_param_value[1])
542
+			&& is_array($query_param_value[1])
543
+			&& isset($query_param_value[1][0], $query_param_value[1][1])
544
+			&& !isset($query_param_value[1][2])
545
+			&& !isset($query_param_value[2]);
546
+	}
547
+
548
+	/**
549
+	 * Returns true if the operator is a similar to LIKE, indicating the value may have wildcards we should leave alone.
550
+	 * @since 4.9.72.p
551
+	 * @param $operator
552
+	 * @return boolean
553
+	 */
554
+	private function operatorIsLike($operator)
555
+	{
556
+		$query_param_value = $this->getQueryParamValue();
557
+		return array_key_exists($operator, $this->getContext()->getModel()->valid_like_style_operators())
558
+			&& isset($query_param_value[1])
559
+			&& !isset($query_param_value[2]);
560
+	}
561
+
562
+	/**
563
+	 * Returns true if the operator only takes one argument (eg it's like `IS NULL`).
564
+	 * @since 4.9.72.p
565
+	 * @param $operator
566
+	 * @return boolean
567
+	 */
568
+	private function operatorIsUnary($operator)
569
+	{
570
+		$query_param_value = $this->getQueryParamValue();
571
+		return array_key_exists($operator, $this->getContext()->getModel()->valid_null_style_operators())
572
+			&& !isset($query_param_value[1]);
573
+	}
574
+
575
+	/**
576
+	 * Returns true if the operator specified is a binary opeator (eg `=`, `!=`)
577
+	 * @since 4.9.72.p
578
+	 * @param $operator
579
+	 * @return boolean
580
+	 */
581
+	private function operatorisBinary($operator)
582
+	{
583
+		$query_param_value = $this->getQueryParamValue();
584
+		$model = $this->getContext()->getModel();
585
+		return isset($query_param_value[1])
586
+			&& !isset($query_param_value[2])
587
+			&& !array_key_exists(
588
+				$operator,
589
+				array_merge(
590
+					$model->valid_in_style_operators(),
591
+					$model->valid_null_style_operators(),
592
+					$model->valid_like_style_operators(),
593
+					$model->valid_between_style_operators()
594
+				)
595
+			);
596
+	}
597
+
598
+	/**
599
+	 * If we're debugging, throws an exception saying that the wrong number of arguments was provided.
600
+	 * @since 4.9.72.p
601
+	 * @param $operator
602
+	 * @throws RestException
603
+	 */
604
+	private function throwWrongNumberOfArgsExceptionIfDebugging($operator)
605
+	{
606
+		if (EED_Core_Rest_Api::debugMode()) {
607
+			throw new RestException(
608
+				'wrong_number_of_arguments',
609
+				sprintf(
610
+					esc_html__(
611
+						'The operator you provided, "%1$s" had the wrong number of arguments',
612
+						'event_espresso'
613
+					),
614
+					$operator
615
+				),
616
+				array(
617
+					'status' => 400,
618
+				)
619
+			);
620
+		}
621
+	}
622
+
623
+	/**
624
+	 * Wrapper for ModelDataTranslator::prepareFieldValuesFromJson(), just a tad more DRY.
625
+	 * @since 4.9.72.p
626
+	 * @param $value
627
+	 * @return mixed
628
+	 * @throws RestException
629
+	 */
630
+	private function prepareValuesFromJson($value)
631
+	{
632
+		return ModelDataTranslator::prepareFieldValuesFromJson(
633
+			$this->getField(),
634
+			$value,
635
+			$this->getContext()->getRequestedVersion(),
636
+			$this->getTimezone()
637
+		);
638
+	}
639
+
640
+	/**
641
+	 * Throws an exception if an invalid operator was specified and we're debugging.
642
+	 * @since 4.9.72.p
643
+	 * @throws RestException
644
+	 */
645
+	private function throwInvalidOperatorExceptionIfDebugging()
646
+	{
647
+		// so they didn't provide a valid operator
648
+		if (EED_Core_Rest_Api::debugMode()) {
649
+			throw new RestException(
650
+				'invalid_operator',
651
+				sprintf(
652
+					esc_html__(
653
+						'You provided an invalid parameter, with key "%1$s" and value "%2$s"',
654
+						'event_espresso'
655
+					),
656
+					$this->getQueryParamKey(),
657
+					$this->getQueryParamValue()
658
+				),
659
+				array(
660
+					'status' => 400,
661
+				)
662
+			);
663
+		}
664
+	}
665
+
666
+	/**
667
+	 * Returns true if the query_param_key was a logic query parameter, eg `OR`, `AND`, `NOT`, `OR*`, etc.
668
+	 * @since 4.9.72.p
669
+	 * @return boolean
670
+	 */
671
+	private function isLogicQueryParam()
672
+	{
673
+		return in_array($this->getQueryParamKeySansStars(), $this->getContext()->getModel()->logic_query_param_keys());
674
+	}
675
+
676
+
677
+	/**
678
+	 * If the query param isn't for a field, it must be a nested query parameter which requires different logic.
679
+	 * @since 4.9.72.p
680
+	 * @return array
681
+	 * @throws DomainException
682
+	 * @throws EE_Error
683
+	 * @throws RestException
684
+	 * @throws InvalidDataTypeException
685
+	 * @throws InvalidInterfaceException
686
+	 * @throws InvalidArgumentException
687
+	 */
688
+	public function determineNestedConditionQueryParameters()
689
+	{
690
+
691
+		// so this param doesn't correspond to a field eh?
692
+		if ($this->getContext()->isWriting()) {
693
+			// always tell API clients about invalid parameters when they're creating data. Otherwise,
694
+			// they are probably going to create invalid data
695
+			throw new RestException(
696
+				'invalid_field',
697
+				sprintf(
698
+					/* translators: 1: variable name */
699
+					esc_html__('You have provided an invalid parameter: "%1$s"', 'event_espresso'),
700
+					$this->getQueryParamKey()
701
+				)
702
+			);
703
+		}
704
+		// so it's not for a field, is it a logic query param key?
705
+		if ($this->isLogicQueryParam()) {
706
+			return ModelDataTranslator::prepareConditionsQueryParamsForModels(
707
+				$this->getQueryParamValue(),
708
+				$this->getContext()->getModel(),
709
+				$this->getContext()->getRequestedVersion()
710
+			);
711
+		}
712
+		if (EED_Core_Rest_Api::debugMode()) {
713
+			// only tell API clients they got it wrong if we're in debug mode
714
+			// otherwise try our best ot fulfill their request by ignoring this invalid data
715
+			throw new RestException(
716
+				'invalid_parameter',
717
+				sprintf(
718
+					/* translators: 1: variable name */
719
+					esc_html__(
720
+						'You provided an invalid parameter, with key "%1$s"',
721
+						'event_espresso'
722
+					),
723
+					$this->getQueryParamKey()
724
+				),
725
+				array(
726
+					'status' => 400,
727
+				)
728
+			);
729
+		}
730
+		return null;
731
+	}
732 732
 }
733 733
 // End of file RestQueryParamMetadata.php
734 734
 // Location: EventEspresso\core\libraries\rest_api/RestQueryParamMetadata.php
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
         ));
210 210
         // double-check is it a *_gmt field?
211 211
         if (
212
-            !$this->getField() instanceof EE_Model_Field_Base
212
+            ! $this->getField() instanceof EE_Model_Field_Base
213 213
             && ModelDataTranslator::isGmtDateFieldName($this->getQueryParamKeySansStars())
214 214
         ) {
215 215
             // yep, take off '_gmt', and find the field
@@ -330,7 +330,7 @@  discard block
 block discarded – undo
330 330
      */
331 331
     private function valueIsArrayDuringRead()
332 332
     {
333
-        return !$this->getContext()->isWriting() && is_array($this->getQueryParamValue());
333
+        return ! $this->getContext()->isWriting() && is_array($this->getQueryParamValue());
334 334
     }
335 335
 
336 336
     /**
@@ -341,7 +341,7 @@  discard block
 block discarded – undo
341 341
      */
342 342
     private function valueIsAssociativeArray()
343 343
     {
344
-        return !EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue());
344
+        return ! EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue());
345 345
     }
346 346
 
347 347
     /**
@@ -429,7 +429,7 @@  discard block
 block discarded – undo
429 429
     {
430 430
         // the value should be JSON or CSV
431 431
         $values = json_decode($sub_array_value);
432
-        if (!is_array($values)) {
432
+        if ( ! is_array($values)) {
433 433
             $values = array_filter(
434 434
                 array_map(
435 435
                     'trim',
@@ -450,7 +450,7 @@  discard block
 block discarded – undo
450 450
      */
451 451
     private function assertSimplifiedSpecifiedOperator()
452 452
     {
453
-        if (!$this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) {
453
+        if ( ! $this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) {
454 454
             throw new RestException(
455 455
                 'numerically_indexed_array_of_values_only',
456 456
                 sprintf(
@@ -505,7 +505,7 @@  discard block
 block discarded – undo
505 505
         $valid_operators = $this->getContext()->getModel()->valid_operators();
506 506
         $query_param_value = $this->getQueryParamValue();
507 507
         return isset($query_param_value[0])
508
-            && isset($valid_operators[ $query_param_value[0] ]);
508
+            && isset($valid_operators[$query_param_value[0]]);
509 509
     }
510 510
 
511 511
     /**
@@ -523,7 +523,7 @@  discard block
 block discarded – undo
523 523
         )
524 524
             && isset($valueArray[1])
525 525
             && is_array($valueArray[1])
526
-            && !isset($valueArray[2]);
526
+            && ! isset($valueArray[2]);
527 527
     }
528 528
 
529 529
     /**
@@ -541,8 +541,8 @@  discard block
 block discarded – undo
541 541
             && isset($query_param_value[1])
542 542
             && is_array($query_param_value[1])
543 543
             && isset($query_param_value[1][0], $query_param_value[1][1])
544
-            && !isset($query_param_value[1][2])
545
-            && !isset($query_param_value[2]);
544
+            && ! isset($query_param_value[1][2])
545
+            && ! isset($query_param_value[2]);
546 546
     }
547 547
 
548 548
     /**
@@ -556,7 +556,7 @@  discard block
 block discarded – undo
556 556
         $query_param_value = $this->getQueryParamValue();
557 557
         return array_key_exists($operator, $this->getContext()->getModel()->valid_like_style_operators())
558 558
             && isset($query_param_value[1])
559
-            && !isset($query_param_value[2]);
559
+            && ! isset($query_param_value[2]);
560 560
     }
561 561
 
562 562
     /**
@@ -569,7 +569,7 @@  discard block
 block discarded – undo
569 569
     {
570 570
         $query_param_value = $this->getQueryParamValue();
571 571
         return array_key_exists($operator, $this->getContext()->getModel()->valid_null_style_operators())
572
-            && !isset($query_param_value[1]);
572
+            && ! isset($query_param_value[1]);
573 573
     }
574 574
 
575 575
     /**
@@ -583,8 +583,8 @@  discard block
 block discarded – undo
583 583
         $query_param_value = $this->getQueryParamValue();
584 584
         $model = $this->getContext()->getModel();
585 585
         return isset($query_param_value[1])
586
-            && !isset($query_param_value[2])
587
-            && !array_key_exists(
586
+            && ! isset($query_param_value[2])
587
+            && ! array_key_exists(
588 588
                 $operator,
589 589
                 array_merge(
590 590
                     $model->valid_in_style_operators(),
Please login to merge, or discard this patch.
core/libraries/rest_api/changes/ChangesIn40834.php 1 patch
Indentation   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -12,39 +12,39 @@
 block discarded – undo
12 12
 class ChangesIn40834 extends ChangesInBase
13 13
 {
14 14
 
15
-    /**
16
-     * Adds hooks so requests to 4.8.29 don't have the checkin endpoints
17
-     */
18
-    public function setHooks()
19
-    {
20
-        // set a hook to remove the checkout/checkout endpoints if the request
21
-        // is for lower than 4.8.33
22
-        add_filter(
23
-            'FHEE__EventEspresso\core\libraries\rest_api\controllers\Base___get_response_headers',
24
-            array($this, 'removeResponseHeaders'),
25
-            10,
26
-            3
27
-        );
28
-    }
15
+	/**
16
+	 * Adds hooks so requests to 4.8.29 don't have the checkin endpoints
17
+	 */
18
+	public function setHooks()
19
+	{
20
+		// set a hook to remove the checkout/checkout endpoints if the request
21
+		// is for lower than 4.8.33
22
+		add_filter(
23
+			'FHEE__EventEspresso\core\libraries\rest_api\controllers\Base___get_response_headers',
24
+			array($this, 'removeResponseHeaders'),
25
+			10,
26
+			3
27
+		);
28
+	}
29 29
 
30 30
 
31
-    /**
32
-     * Removes the checkin and checkout endpoints from the index for requests
33
-     * to api versions lowers than 4.8.33
34
-     *
35
-     * @param array  $response_headers
36
-     * @param Base   $controller
37
-     * @param string $requested_version
38
-     * @return array like $routes_on_this_version
39
-     */
40
-    public function removeResponseHeaders($response_headers, $controller, $requested_version)
41
-    {
42
-        if (
43
-            $controller instanceof Base
44
-            && $this->appliesToVersion($requested_version)
45
-        ) {
46
-            return array();
47
-        }
48
-        return $response_headers;
49
-    }
31
+	/**
32
+	 * Removes the checkin and checkout endpoints from the index for requests
33
+	 * to api versions lowers than 4.8.33
34
+	 *
35
+	 * @param array  $response_headers
36
+	 * @param Base   $controller
37
+	 * @param string $requested_version
38
+	 * @return array like $routes_on_this_version
39
+	 */
40
+	public function removeResponseHeaders($response_headers, $controller, $requested_version)
41
+	{
42
+		if (
43
+			$controller instanceof Base
44
+			&& $this->appliesToVersion($requested_version)
45
+		) {
46
+			return array();
47
+		}
48
+		return $response_headers;
49
+	}
50 50
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/RestException.php 1 patch
Indentation   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -15,55 +15,55 @@
 block discarded – undo
15 15
 class RestException extends \EE_Error
16 16
 {
17 17
 
18
-    /**
19
-     * @var array
20
-     */
21
-    protected $wp_error_data = array();
18
+	/**
19
+	 * @var array
20
+	 */
21
+	protected $wp_error_data = array();
22 22
 
23
-    protected $wp_error_code = '';
23
+	protected $wp_error_code = '';
24 24
 
25 25
 
26 26
 
27
-    public function __construct($string_code, $message, $wp_error_data = array(), $previous = null)
28
-    {
29
-        if (
30
-            is_array($wp_error_data)
31
-            && isset($wp_error_data['status'])
32
-        ) {
33
-            $http_status_number = $wp_error_data['status'];
34
-        } else {
35
-            $http_status_number = 500;
36
-        }
37
-        parent::__construct(
38
-            $message,
39
-            $http_status_number,
40
-            $previous
41
-        );
42
-        $this->wp_error_data = $wp_error_data;
43
-        $this->wp_error_code = $string_code;
44
-    }
27
+	public function __construct($string_code, $message, $wp_error_data = array(), $previous = null)
28
+	{
29
+		if (
30
+			is_array($wp_error_data)
31
+			&& isset($wp_error_data['status'])
32
+		) {
33
+			$http_status_number = $wp_error_data['status'];
34
+		} else {
35
+			$http_status_number = 500;
36
+		}
37
+		parent::__construct(
38
+			$message,
39
+			$http_status_number,
40
+			$previous
41
+		);
42
+		$this->wp_error_data = $wp_error_data;
43
+		$this->wp_error_code = $string_code;
44
+	}
45 45
 
46 46
 
47 47
 
48
-    /**
49
-     * Array of data that may have been set during the constructor, intended for WP_Error's data
50
-     *
51
-     * @return array
52
-     */
53
-    public function getData()
54
-    {
55
-        return $this->wp_error_data;
56
-    }
48
+	/**
49
+	 * Array of data that may have been set during the constructor, intended for WP_Error's data
50
+	 *
51
+	 * @return array
52
+	 */
53
+	public function getData()
54
+	{
55
+		return $this->wp_error_data;
56
+	}
57 57
 
58 58
 
59 59
 
60
-    /**
61
-     * Gets the error string
62
-     *
63
-     * @return string
64
-     */
65
-    public function getStringCode()
66
-    {
67
-        return $this->wp_error_code;
68
-    }
60
+	/**
61
+	 * Gets the error string
62
+	 *
63
+	 * @return string
64
+	 */
65
+	public function getStringCode()
66
+	{
67
+		return $this->wp_error_code;
68
+	}
69 69
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/calculations/Registration.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -96,7 +96,7 @@
 block discarded – undo
96 96
                     $status_pretty = 'NEVER';
97 97
                     break;
98 98
             }
99
-            $checkin_stati[ $datetime_id ] = $status_pretty;
99
+            $checkin_stati[$datetime_id] = $status_pretty;
100 100
         }
101 101
         return $checkin_stati;
102 102
     }
Please login to merge, or discard this patch.
Indentation   +101 added lines, -101 removed lines patch added patch discarded remove patch
@@ -24,109 +24,109 @@
 block discarded – undo
24 24
  */
25 25
 class Registration extends RegistrationCalculationBase
26 26
 {
27
-    /**
28
-     * @var EEM_Registration
29
-     */
30
-    protected $registration_model;
27
+	/**
28
+	 * @var EEM_Registration
29
+	 */
30
+	protected $registration_model;
31 31
 
32
-    /**
33
-     * Registration constructor.
34
-     * @param EEM_Registration $registration_model
35
-     */
36
-    public function __construct(EEM_Registration $registration_model)
37
-    {
38
-        $this->registration_model = $registration_model;
39
-    }
32
+	/**
33
+	 * Registration constructor.
34
+	 * @param EEM_Registration $registration_model
35
+	 */
36
+	public function __construct(EEM_Registration $registration_model)
37
+	{
38
+		$this->registration_model = $registration_model;
39
+	}
40 40
 
41
-    /**
42
-     * Calculates the checkin status for each datetime this registration has access to
43
-     *
44
-     * @param array            $wpdb_row
45
-     * @param WP_REST_Request $request
46
-     * @param RegistrationControllerBase $controller
47
-     * @return array
48
-     * @throws EE_Error
49
-     * @throws InvalidDataTypeException
50
-     * @throws InvalidInterfaceException
51
-     * @throws InvalidArgumentException
52
-     */
53
-    public function datetimeCheckinStati($wpdb_row, $request, $controller)
54
-    {
55
-        if (is_array($wpdb_row) && isset($wpdb_row['Registration.REG_ID'])) {
56
-            $reg = $this->registration_model->get_one_by_ID($wpdb_row['Registration.REG_ID']);
57
-        } else {
58
-            $reg = null;
59
-        }
60
-        if (
61
-            ! $reg instanceof EE_Registration
62
-        ) {
63
-            throw new EE_Error(
64
-                sprintf(
65
-                    esc_html__(
66
-                    // @codingStandardsIgnoreStart
67
-                        'Cannot calculate datetime_checkin_stati because the registration with ID %1$s (from database row %2$s) was not found',
68
-                        // @codingStandardsIgnoreEnd
69
-                        'event_espresso'
70
-                    ),
71
-                    $wpdb_row['Registration.REG_ID'],
72
-                    print_r($wpdb_row, true)
73
-                )
74
-            );
75
-        }
76
-        $datetime_ids = EEM_Datetime::instance()->get_col(
77
-            [
78
-                [
79
-                    'Ticket.TKT_ID' => $reg->ticket_ID(),
80
-                ],
81
-                'default_where_conditions' => EEM_Base::default_where_conditions_minimum_all,
82
-            ]
83
-        );
84
-        $checkin_stati = array();
85
-        foreach ($datetime_ids as $datetime_id) {
86
-            $status = $reg->check_in_status_for_datetime($datetime_id);
87
-            switch ($status) {
88
-                case EE_Checkin::status_checked_out:
89
-                    $status_pretty = 'OUT';
90
-                    break;
91
-                case EE_Checkin::status_checked_in:
92
-                    $status_pretty = 'IN';
93
-                    break;
94
-                case EE_Checkin::status_checked_never:
95
-                default:
96
-                    $status_pretty = 'NEVER';
97
-                    break;
98
-            }
99
-            $checkin_stati[ $datetime_id ] = $status_pretty;
100
-        }
101
-        return $checkin_stati;
102
-    }
41
+	/**
42
+	 * Calculates the checkin status for each datetime this registration has access to
43
+	 *
44
+	 * @param array            $wpdb_row
45
+	 * @param WP_REST_Request $request
46
+	 * @param RegistrationControllerBase $controller
47
+	 * @return array
48
+	 * @throws EE_Error
49
+	 * @throws InvalidDataTypeException
50
+	 * @throws InvalidInterfaceException
51
+	 * @throws InvalidArgumentException
52
+	 */
53
+	public function datetimeCheckinStati($wpdb_row, $request, $controller)
54
+	{
55
+		if (is_array($wpdb_row) && isset($wpdb_row['Registration.REG_ID'])) {
56
+			$reg = $this->registration_model->get_one_by_ID($wpdb_row['Registration.REG_ID']);
57
+		} else {
58
+			$reg = null;
59
+		}
60
+		if (
61
+			! $reg instanceof EE_Registration
62
+		) {
63
+			throw new EE_Error(
64
+				sprintf(
65
+					esc_html__(
66
+					// @codingStandardsIgnoreStart
67
+						'Cannot calculate datetime_checkin_stati because the registration with ID %1$s (from database row %2$s) was not found',
68
+						// @codingStandardsIgnoreEnd
69
+						'event_espresso'
70
+					),
71
+					$wpdb_row['Registration.REG_ID'],
72
+					print_r($wpdb_row, true)
73
+				)
74
+			);
75
+		}
76
+		$datetime_ids = EEM_Datetime::instance()->get_col(
77
+			[
78
+				[
79
+					'Ticket.TKT_ID' => $reg->ticket_ID(),
80
+				],
81
+				'default_where_conditions' => EEM_Base::default_where_conditions_minimum_all,
82
+			]
83
+		);
84
+		$checkin_stati = array();
85
+		foreach ($datetime_ids as $datetime_id) {
86
+			$status = $reg->check_in_status_for_datetime($datetime_id);
87
+			switch ($status) {
88
+				case EE_Checkin::status_checked_out:
89
+					$status_pretty = 'OUT';
90
+					break;
91
+				case EE_Checkin::status_checked_in:
92
+					$status_pretty = 'IN';
93
+					break;
94
+				case EE_Checkin::status_checked_never:
95
+				default:
96
+					$status_pretty = 'NEVER';
97
+					break;
98
+			}
99
+			$checkin_stati[ $datetime_id ] = $status_pretty;
100
+		}
101
+		return $checkin_stati;
102
+	}
103 103
 
104 104
 
105
-    /**
106
-     * Provides an array for all the calculations possible that outlines a json schema for those calculations.
107
-     * Array is indexed by calculation (snake case) and value is the schema for that calculation.
108
-     *
109
-     * @since 4.9.68.p
110
-     * @return array
111
-     */
112
-    public function schemaForCalculations()
113
-    {
114
-        return array(
115
-            'datetime_checkin_stati' => array(
116
-                'description' => esc_html__(
117
-                    'Returns the checkin status for each datetime this registration has access to.',
118
-                    'event_espresso'
119
-                ),
120
-                'type' => 'object',
121
-                'properties' => array(),
122
-                'additionalProperties' => array(
123
-                    'description' => esc_html__(
124
-                        'Keys are date-time ids and values are the check-in status',
125
-                        'event_espresso'
126
-                    ),
127
-                    'type' => 'string'
128
-                ),
129
-            ),
130
-        );
131
-    }
105
+	/**
106
+	 * Provides an array for all the calculations possible that outlines a json schema for those calculations.
107
+	 * Array is indexed by calculation (snake case) and value is the schema for that calculation.
108
+	 *
109
+	 * @since 4.9.68.p
110
+	 * @return array
111
+	 */
112
+	public function schemaForCalculations()
113
+	{
114
+		return array(
115
+			'datetime_checkin_stati' => array(
116
+				'description' => esc_html__(
117
+					'Returns the checkin status for each datetime this registration has access to.',
118
+					'event_espresso'
119
+				),
120
+				'type' => 'object',
121
+				'properties' => array(),
122
+				'additionalProperties' => array(
123
+					'description' => esc_html__(
124
+						'Keys are date-time ids and values are the check-in status',
125
+						'event_espresso'
126
+					),
127
+					'type' => 'string'
128
+				),
129
+			),
130
+		);
131
+	}
132 132
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/CalculatedModelFields.php 2 patches
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -57,7 +57,7 @@  discard block
 block discarded – undo
57 57
      */
58 58
     public function mapping($refresh = false)
59 59
     {
60
-        if (! $this->mapping || $refresh) {
60
+        if ( ! $this->mapping || $refresh) {
61 61
             $this->mapping = $this->generateNewMapping();
62 62
         }
63 63
         return $this->mapping;
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
         foreach ($models_with_calculated_fields as $model_name) {
82 82
             $calculator = $this->factory->createFromModel($model_name);
83 83
             foreach (array_keys(call_user_func(array($calculator, 'schemaForCalculations'))) as $field_name) {
84
-                $mapping[ $model_name ][ $field_name ] = get_class($calculator);
84
+                $mapping[$model_name][$field_name] = get_class($calculator);
85 85
             }
86 86
         }
87 87
         return apply_filters(
@@ -108,8 +108,8 @@  discard block
 block discarded – undo
108 108
             foreach ($map_for_model as $calculation_index => $calculations_class) {
109 109
                 $calculator = $this->factory->createFromClassname($calculations_class);
110 110
                 $schema = call_user_func(array($calculator, 'schemaForCalculation'), $calculation_index);
111
-                if (! empty($schema)) {
112
-                    $schema_map[ $map_model ][ $calculation_index ] = $schema;
111
+                if ( ! empty($schema)) {
112
+                    $schema_map[$map_model][$calculation_index] = $schema;
113 113
                 }
114 114
             }
115 115
         }
@@ -126,8 +126,8 @@  discard block
 block discarded – undo
126 126
     public function retrieveCalculatedFieldsForModel(EEM_Base $model)
127 127
     {
128 128
         $mapping = $this->mapping();
129
-        if (isset($mapping[ $model->get_this_model_name() ])) {
130
-            return array_keys($mapping[ $model->get_this_model_name() ]);
129
+        if (isset($mapping[$model->get_this_model_name()])) {
130
+            return array_keys($mapping[$model->get_this_model_name()]);
131 131
         }
132 132
         return array();
133 133
     }
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
      */
141 141
     public function getJsonSchemaForModel(EEM_Base $model)
142 142
     {
143
-        if (! $this->mapping_schema) {
143
+        if ( ! $this->mapping_schema) {
144 144
             $this->mapping_schema = $this->generateNewMappingSchema();
145 145
         }
146 146
         return array(
@@ -149,8 +149,8 @@  discard block
 block discarded – undo
149 149
                 'event_espresso'
150 150
             ),
151 151
             'type' => 'object',
152
-            'properties' => isset($this->mapping_schema[ $model->get_this_model_name() ])
153
-                ? $this->mapping_schema[ $model->get_this_model_name() ]
152
+            'properties' => isset($this->mapping_schema[$model->get_this_model_name()])
153
+                ? $this->mapping_schema[$model->get_this_model_name()]
154 154
                 : array(),
155 155
             'additionalProperties' => false,
156 156
             'readonly' => true,
@@ -179,10 +179,10 @@  discard block
 block discarded – undo
179 179
     ) {
180 180
         $mapping = $this->mapping();
181 181
         if (
182
-            isset($mapping[ $model->get_this_model_name() ])
183
-            && isset($mapping[ $model->get_this_model_name() ][ $field_name ])
182
+            isset($mapping[$model->get_this_model_name()])
183
+            && isset($mapping[$model->get_this_model_name()][$field_name])
184 184
         ) {
185
-            $classname = $mapping[ $model->get_this_model_name() ][ $field_name ];
185
+            $classname = $mapping[$model->get_this_model_name()][$field_name];
186 186
             $calculator = $this->factory->createFromClassname($classname);
187 187
             $class_method_name = EEH_Inflector::camelize_all_but_first($field_name);
188 188
             return call_user_func(array($calculator, $class_method_name), $wpdb_row, $rest_request, $controller);
Please login to merge, or discard this patch.
Indentation   +174 added lines, -174 removed lines patch added patch discarded remove patch
@@ -22,178 +22,178 @@
 block discarded – undo
22 22
 class CalculatedModelFields
23 23
 {
24 24
 
25
-    /**
26
-     * @var array
27
-     */
28
-    protected $mapping;
29
-
30
-    /**
31
-     * @var array
32
-     */
33
-    protected $mapping_schema;
34
-
35
-    /**
36
-     * @var CalculatedModelFieldsFactory
37
-     */
38
-    private $factory;
39
-
40
-    /**
41
-     * CalculatedModelFields constructor.
42
-     * @param CalculatedModelFieldsFactory $factory
43
-     */
44
-    public function __construct(CalculatedModelFieldsFactory $factory)
45
-    {
46
-        $this->factory = $factory;
47
-    }
48
-    /**
49
-     * @param bool $refresh
50
-     * @return array top-level-keys are model names (eg "Event")
51
-     * next-level are the calculated field names AND method names on classes
52
-     * which perform calculations, values are the fully qualified classnames which do the calculations
53
-     * These callbacks should accept as arguments:
54
-     * the wpdb row results,
55
-     * the WP_Request object,
56
-     * the controller object
57
-     */
58
-    public function mapping($refresh = false)
59
-    {
60
-        if (! $this->mapping || $refresh) {
61
-            $this->mapping = $this->generateNewMapping();
62
-        }
63
-        return $this->mapping;
64
-    }
65
-
66
-
67
-    /**
68
-     * Generates a new mapping between model calculated fields and their callbacks
69
-     *
70
-     * @return array
71
-     */
72
-    protected function generateNewMapping()
73
-    {
74
-        $mapping = array();
75
-        $models_with_calculated_fields = array(
76
-            'Attendee',
77
-            'Datetime',
78
-            'Event',
79
-            'Registration'
80
-        );
81
-        foreach ($models_with_calculated_fields as $model_name) {
82
-            $calculator = $this->factory->createFromModel($model_name);
83
-            foreach (array_keys(call_user_func(array($calculator, 'schemaForCalculations'))) as $field_name) {
84
-                $mapping[ $model_name ][ $field_name ] = get_class($calculator);
85
-            }
86
-        }
87
-        return apply_filters(
88
-            'FHEE__EventEspresso\core\libraries\rest_api\Calculated_Model_Fields__mapping',
89
-            $mapping
90
-        );
91
-    }
92
-
93
-
94
-    /**
95
-     * Generates the schema for each calculation index in the calculation map.
96
-     *
97
-     * @return array
98
-     * @throws UnexpectedEntityException
99
-     */
100
-    protected function generateNewMappingSchema()
101
-    {
102
-        $schema_map = array();
103
-        foreach ($this->mapping() as $map_model => $map_for_model) {
104
-            /**
105
-             * @var string $calculation_index
106
-             * @var string $calculations_class
107
-             */
108
-            foreach ($map_for_model as $calculation_index => $calculations_class) {
109
-                $calculator = $this->factory->createFromClassname($calculations_class);
110
-                $schema = call_user_func(array($calculator, 'schemaForCalculation'), $calculation_index);
111
-                if (! empty($schema)) {
112
-                    $schema_map[ $map_model ][ $calculation_index ] = $schema;
113
-                }
114
-            }
115
-        }
116
-        return $schema_map;
117
-    }
118
-
119
-
120
-    /**
121
-     * Gets the known calculated fields for model
122
-     *
123
-     * @param EEM_Base $model
124
-     * @return array allowable values for this field
125
-     */
126
-    public function retrieveCalculatedFieldsForModel(EEM_Base $model)
127
-    {
128
-        $mapping = $this->mapping();
129
-        if (isset($mapping[ $model->get_this_model_name() ])) {
130
-            return array_keys($mapping[ $model->get_this_model_name() ]);
131
-        }
132
-        return array();
133
-    }
134
-
135
-
136
-    /**
137
-     * Returns the JsonSchema for the calculated fields on the given model.
138
-     * @param EEM_Base $model
139
-     * @return array
140
-     */
141
-    public function getJsonSchemaForModel(EEM_Base $model)
142
-    {
143
-        if (! $this->mapping_schema) {
144
-            $this->mapping_schema = $this->generateNewMappingSchema();
145
-        }
146
-        return array(
147
-            'description' => esc_html__(
148
-                'Available calculated fields for this model.  Fields are only present in the response if explicitly requested',
149
-                'event_espresso'
150
-            ),
151
-            'type' => 'object',
152
-            'properties' => isset($this->mapping_schema[ $model->get_this_model_name() ])
153
-                ? $this->mapping_schema[ $model->get_this_model_name() ]
154
-                : array(),
155
-            'additionalProperties' => false,
156
-            'readonly' => true,
157
-        );
158
-    }
159
-
160
-
161
-    /**
162
-     * Retrieves the value for this calculation
163
-     *
164
-     * @param EEM_Base $model
165
-     * @param string $field_name
166
-     * @param array $wpdb_row
167
-     * @param $rest_request
168
-     * @param BaseController $controller
169
-     * @return mixed|null
170
-     * @throws RestException
171
-     * @throws UnexpectedEntityException
172
-     */
173
-    public function retrieveCalculatedFieldValue(
174
-        EEM_Base $model,
175
-        $field_name,
176
-        $wpdb_row,
177
-        $rest_request,
178
-        Base $controller
179
-    ) {
180
-        $mapping = $this->mapping();
181
-        if (
182
-            isset($mapping[ $model->get_this_model_name() ])
183
-            && isset($mapping[ $model->get_this_model_name() ][ $field_name ])
184
-        ) {
185
-            $classname = $mapping[ $model->get_this_model_name() ][ $field_name ];
186
-            $calculator = $this->factory->createFromClassname($classname);
187
-            $class_method_name = EEH_Inflector::camelize_all_but_first($field_name);
188
-            return call_user_func(array($calculator, $class_method_name), $wpdb_row, $rest_request, $controller);
189
-        }
190
-        throw new RestException(
191
-            'calculated_field_does_not_exist',
192
-            sprintf(
193
-                esc_html__('There is no calculated field %1$s on resource %2$s', 'event_espresso'),
194
-                $field_name,
195
-                $model->get_this_model_name()
196
-            )
197
-        );
198
-    }
25
+	/**
26
+	 * @var array
27
+	 */
28
+	protected $mapping;
29
+
30
+	/**
31
+	 * @var array
32
+	 */
33
+	protected $mapping_schema;
34
+
35
+	/**
36
+	 * @var CalculatedModelFieldsFactory
37
+	 */
38
+	private $factory;
39
+
40
+	/**
41
+	 * CalculatedModelFields constructor.
42
+	 * @param CalculatedModelFieldsFactory $factory
43
+	 */
44
+	public function __construct(CalculatedModelFieldsFactory $factory)
45
+	{
46
+		$this->factory = $factory;
47
+	}
48
+	/**
49
+	 * @param bool $refresh
50
+	 * @return array top-level-keys are model names (eg "Event")
51
+	 * next-level are the calculated field names AND method names on classes
52
+	 * which perform calculations, values are the fully qualified classnames which do the calculations
53
+	 * These callbacks should accept as arguments:
54
+	 * the wpdb row results,
55
+	 * the WP_Request object,
56
+	 * the controller object
57
+	 */
58
+	public function mapping($refresh = false)
59
+	{
60
+		if (! $this->mapping || $refresh) {
61
+			$this->mapping = $this->generateNewMapping();
62
+		}
63
+		return $this->mapping;
64
+	}
65
+
66
+
67
+	/**
68
+	 * Generates a new mapping between model calculated fields and their callbacks
69
+	 *
70
+	 * @return array
71
+	 */
72
+	protected function generateNewMapping()
73
+	{
74
+		$mapping = array();
75
+		$models_with_calculated_fields = array(
76
+			'Attendee',
77
+			'Datetime',
78
+			'Event',
79
+			'Registration'
80
+		);
81
+		foreach ($models_with_calculated_fields as $model_name) {
82
+			$calculator = $this->factory->createFromModel($model_name);
83
+			foreach (array_keys(call_user_func(array($calculator, 'schemaForCalculations'))) as $field_name) {
84
+				$mapping[ $model_name ][ $field_name ] = get_class($calculator);
85
+			}
86
+		}
87
+		return apply_filters(
88
+			'FHEE__EventEspresso\core\libraries\rest_api\Calculated_Model_Fields__mapping',
89
+			$mapping
90
+		);
91
+	}
92
+
93
+
94
+	/**
95
+	 * Generates the schema for each calculation index in the calculation map.
96
+	 *
97
+	 * @return array
98
+	 * @throws UnexpectedEntityException
99
+	 */
100
+	protected function generateNewMappingSchema()
101
+	{
102
+		$schema_map = array();
103
+		foreach ($this->mapping() as $map_model => $map_for_model) {
104
+			/**
105
+			 * @var string $calculation_index
106
+			 * @var string $calculations_class
107
+			 */
108
+			foreach ($map_for_model as $calculation_index => $calculations_class) {
109
+				$calculator = $this->factory->createFromClassname($calculations_class);
110
+				$schema = call_user_func(array($calculator, 'schemaForCalculation'), $calculation_index);
111
+				if (! empty($schema)) {
112
+					$schema_map[ $map_model ][ $calculation_index ] = $schema;
113
+				}
114
+			}
115
+		}
116
+		return $schema_map;
117
+	}
118
+
119
+
120
+	/**
121
+	 * Gets the known calculated fields for model
122
+	 *
123
+	 * @param EEM_Base $model
124
+	 * @return array allowable values for this field
125
+	 */
126
+	public function retrieveCalculatedFieldsForModel(EEM_Base $model)
127
+	{
128
+		$mapping = $this->mapping();
129
+		if (isset($mapping[ $model->get_this_model_name() ])) {
130
+			return array_keys($mapping[ $model->get_this_model_name() ]);
131
+		}
132
+		return array();
133
+	}
134
+
135
+
136
+	/**
137
+	 * Returns the JsonSchema for the calculated fields on the given model.
138
+	 * @param EEM_Base $model
139
+	 * @return array
140
+	 */
141
+	public function getJsonSchemaForModel(EEM_Base $model)
142
+	{
143
+		if (! $this->mapping_schema) {
144
+			$this->mapping_schema = $this->generateNewMappingSchema();
145
+		}
146
+		return array(
147
+			'description' => esc_html__(
148
+				'Available calculated fields for this model.  Fields are only present in the response if explicitly requested',
149
+				'event_espresso'
150
+			),
151
+			'type' => 'object',
152
+			'properties' => isset($this->mapping_schema[ $model->get_this_model_name() ])
153
+				? $this->mapping_schema[ $model->get_this_model_name() ]
154
+				: array(),
155
+			'additionalProperties' => false,
156
+			'readonly' => true,
157
+		);
158
+	}
159
+
160
+
161
+	/**
162
+	 * Retrieves the value for this calculation
163
+	 *
164
+	 * @param EEM_Base $model
165
+	 * @param string $field_name
166
+	 * @param array $wpdb_row
167
+	 * @param $rest_request
168
+	 * @param BaseController $controller
169
+	 * @return mixed|null
170
+	 * @throws RestException
171
+	 * @throws UnexpectedEntityException
172
+	 */
173
+	public function retrieveCalculatedFieldValue(
174
+		EEM_Base $model,
175
+		$field_name,
176
+		$wpdb_row,
177
+		$rest_request,
178
+		Base $controller
179
+	) {
180
+		$mapping = $this->mapping();
181
+		if (
182
+			isset($mapping[ $model->get_this_model_name() ])
183
+			&& isset($mapping[ $model->get_this_model_name() ][ $field_name ])
184
+		) {
185
+			$classname = $mapping[ $model->get_this_model_name() ][ $field_name ];
186
+			$calculator = $this->factory->createFromClassname($classname);
187
+			$class_method_name = EEH_Inflector::camelize_all_but_first($field_name);
188
+			return call_user_func(array($calculator, $class_method_name), $wpdb_row, $rest_request, $controller);
189
+		}
190
+		throw new RestException(
191
+			'calculated_field_does_not_exist',
192
+			sprintf(
193
+				esc_html__('There is no calculated field %1$s on resource %2$s', 'event_espresso'),
194
+				$field_name,
195
+				$model->get_this_model_name()
196
+			)
197
+		);
198
+	}
199 199
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/ModelVersionInfo.php 2 patches
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -114,10 +114,10 @@  discard block
 block discarded – undo
114 114
         foreach ($this->resource_changes as $version => $model_classnames) {
115 115
             foreach ($model_classnames as $model_classname => $extra_fields) {
116 116
                 foreach ($extra_fields as $fieldname => $field_data) {
117
-                    $this->resource_changes[ $model_classname ][ $fieldname ]['name'] = $fieldname;
117
+                    $this->resource_changes[$model_classname][$fieldname]['name'] = $fieldname;
118 118
                     foreach ($defaults as $attribute => $default_value) {
119
-                        if (! isset($this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ])) {
120
-                            $this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ] = $default_value;
119
+                        if ( ! isset($this->resource_changes[$model_classname][$fieldname][$attribute])) {
120
+                            $this->resource_changes[$model_classname][$fieldname][$attribute] = $default_value;
121 121
                         }
122 122
                     }
123 123
                 }
@@ -139,7 +139,7 @@  discard block
 block discarded – undo
139 139
             $model_changes = array();
140 140
             foreach ($this->modelChanges() as $version => $models_changed_in_version) {
141 141
                 if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
142
-                    $model_changes[ $version ] = $models_changed_in_version;
142
+                    $model_changes[$version] = $models_changed_in_version;
143 143
                 }
144 144
             }
145 145
             $this->cached_model_changes_between_requested_version_and_current = $model_changes;
@@ -161,7 +161,7 @@  discard block
 block discarded – undo
161 161
             $resource_changes = array();
162 162
             foreach ($this->resourceChanges() as $version => $model_classnames) {
163 163
                 if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
164
-                    $resource_changes[ $version ] = $model_classnames;
164
+                    $resource_changes[$version] = $model_classnames;
165 165
                 }
166 166
             }
167 167
             $this->cached_resource_changes_between_requested_version_and_current = $resource_changes;
@@ -212,7 +212,7 @@  discard block
 block discarded – undo
212 212
             foreach ($this->modelChangesBetweenRequestedVersionAndCurrent() as $version => $models_changed) {
213 213
                 foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
214 214
                     if ($new_indicator_or_fields_added === ModelVersionInfo::MODEL_ADDED) {
215
-                        unset($all_models_in_current_version[ $model_name ]);
215
+                        unset($all_models_in_current_version[$model_name]);
216 216
                     }
217 217
                 }
218 218
             }
@@ -237,7 +237,7 @@  discard block
 block discarded – undo
237 237
     public function isModelNameInThisVersion($model_name)
238 238
     {
239 239
         $model_names = $this->modelsForRequestedVersion();
240
-        if (isset($model_names[ $model_name ])) {
240
+        if (isset($model_names[$model_name])) {
241 241
             return true;
242 242
         } else {
243 243
             return false;
@@ -280,7 +280,7 @@  discard block
 block discarded – undo
280 280
      */
281 281
     public function fieldsOnModelInThisVersion($model)
282 282
     {
283
-        if (! isset($this->cached_fields_on_models[ $model->get_this_model_name() ])) {
283
+        if ( ! isset($this->cached_fields_on_models[$model->get_this_model_name()])) {
284 284
             // get all model changes between the requested version and current core version
285 285
             $changes = $this->modelChangesBetweenRequestedVersionAndCurrent();
286 286
             // fetch all fields currently on this model
@@ -288,12 +288,12 @@  discard block
 block discarded – undo
288 288
             // remove all fields that have been added since
289 289
             foreach ($changes as $version => $changes_in_version) {
290 290
                 if (
291
-                    isset($changes_in_version[ $model->get_this_model_name() ])
292
-                    && $changes_in_version[ $model->get_this_model_name() ] !== ModelVersionInfo::MODEL_ADDED
291
+                    isset($changes_in_version[$model->get_this_model_name()])
292
+                    && $changes_in_version[$model->get_this_model_name()] !== ModelVersionInfo::MODEL_ADDED
293 293
                 ) {
294 294
                     $current_fields = array_diff_key(
295 295
                         $current_fields,
296
-                        array_flip($changes_in_version[ $model->get_this_model_name() ])
296
+                        array_flip($changes_in_version[$model->get_this_model_name()])
297 297
                     );
298 298
                 }
299 299
             }
@@ -448,7 +448,7 @@  discard block
 block discarded – undo
448 448
         $relations = array();
449 449
         foreach ($model->relation_settings() as $relation_name => $relation_obj) {
450 450
             if ($this->isModelNameInThisVersion($relation_name)) {
451
-                $relations[ $relation_name ] = $relation_obj;
451
+                $relations[$relation_name] = $relation_obj;
452 452
             }
453 453
         }
454 454
         // filter the results, but use the old filter name
Please login to merge, or discard this patch.
Indentation   +437 added lines, -437 removed lines patch added patch discarded remove patch
@@ -21,441 +21,441 @@
 block discarded – undo
21 21
 class ModelVersionInfo
22 22
 {
23 23
 
24
-    /**
25
-     * Constant used in the $_model_changes array to indicate that a model
26
-     * was completely new in this version
27
-     */
28
-    const MODEL_ADDED = 'model_added_in_this_version';
29
-
30
-    /**
31
-     * Top-level keys are versions (major and minor version numbers, eg "4.6")
32
-     * next-level keys are model names (eg "Event") that underwent some change in that version
33
-     * and the value is either Model_Version_Info::model_added (indicating the model is completely NEW in this version),
34
-     * or it's an array where the values are model field names,
35
-     * or API resource properties (ie, non-model fields that appear in REST API results)
36
-     * If a version is missing then we don't know anything about what changes it introduced from the previous version
37
-     *
38
-     * @var array
39
-     */
40
-    protected $model_changes = array();
41
-
42
-    /**
43
-     * top-level keys are version numbers,
44
-     * next-level keys are model CLASSNAMES (even parent classnames),
45
-     * and next-level keys are extra resource properties to attach to those models' resources,
46
-     * and next-level key-value pairs, where the keys are:
47
-     * 'raw', 'type', 'nullable', 'table_alias', 'table_column',  'always_available'
48
-     *
49
-     * @var array
50
-     */
51
-    protected $resource_changes = array();
52
-
53
-    /**
54
-     * @var string indicating what version of the API was requested
55
-     * (eg although core might be at version 4.8.11, they may have sent a request
56
-     * for 4.6)
57
-     */
58
-    protected $requested_version = null;
59
-
60
-    /**
61
-     * Keys are model names, values are their classnames.
62
-     * We cache this so we only need to calculate this once per request
63
-     *
64
-     * @var array
65
-     */
66
-    protected $cached_models_for_requested_version = null;
67
-
68
-    /**
69
-     * @var array
70
-     */
71
-    protected $cached_model_changes_between_requested_version_and_current = null;
72
-
73
-    /**
74
-     * @var array
75
-     */
76
-    protected $cached_resource_changes_between_requested_version_and_current = null;
77
-
78
-    /**
79
-     * 2d array where top-level keys are model names, 2nd-level keys are field names
80
-     * and values are the actual field objects
81
-     *
82
-     * @var array
83
-     */
84
-    protected $cached_fields_on_models = array();
85
-
86
-
87
-    /**
88
-     * Model_Version_Info constructor.
89
-     *
90
-     * @param string $requested_version
91
-     */
92
-    public function __construct($requested_version)
93
-    {
94
-        $this->requested_version = (string) $requested_version;
95
-        $this->model_changes = array(
96
-            '4.8.29' => array(
97
-                // first version where the REST API is in EE core, so no need
98
-                // to specify how its different from the previous
99
-            ),
100
-        );
101
-        // setup data for "extra" fields added onto resources which don't actually exist on models
102
-        $this->resource_changes = apply_filters(
103
-            'FHEE__Model_Version_Info___construct__extra_resource_properties_for_models',
104
-            array()
105
-        );
106
-        $defaults = array(
107
-            'raw'              => false,
108
-            'type'             => 'N/A',
109
-            'nullable'         => true,
110
-            'table_alias'      => 'N/A',
111
-            'table_column'     => 'N/A',
112
-            'always_available' => true,
113
-        );
114
-        foreach ($this->resource_changes as $version => $model_classnames) {
115
-            foreach ($model_classnames as $model_classname => $extra_fields) {
116
-                foreach ($extra_fields as $fieldname => $field_data) {
117
-                    $this->resource_changes[ $model_classname ][ $fieldname ]['name'] = $fieldname;
118
-                    foreach ($defaults as $attribute => $default_value) {
119
-                        if (! isset($this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ])) {
120
-                            $this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ] = $default_value;
121
-                        }
122
-                    }
123
-                }
124
-            }
125
-        }
126
-    }
127
-
128
-
129
-    /**
130
-     * Returns a slice of Model_Version_Info::model_changes()'s array
131
-     * indicating exactly what changes happened between the current core version,
132
-     * and the version requested
133
-     *
134
-     * @return array
135
-     */
136
-    public function modelChangesBetweenRequestedVersionAndCurrent()
137
-    {
138
-        if ($this->cached_model_changes_between_requested_version_and_current === null) {
139
-            $model_changes = array();
140
-            foreach ($this->modelChanges() as $version => $models_changed_in_version) {
141
-                if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
142
-                    $model_changes[ $version ] = $models_changed_in_version;
143
-                }
144
-            }
145
-            $this->cached_model_changes_between_requested_version_and_current = $model_changes;
146
-        }
147
-        return $this->cached_model_changes_between_requested_version_and_current;
148
-    }
149
-
150
-
151
-    /**
152
-     * Returns a slice of Model_Version_Info::model_changes()'s array
153
-     * indicating exactly what changes happened between the current core version,
154
-     * and the version requested
155
-     *
156
-     * @return array
157
-     */
158
-    public function resourceChangesBetweenRequestedVersionAndCurrent()
159
-    {
160
-        if ($this->cached_resource_changes_between_requested_version_and_current === null) {
161
-            $resource_changes = array();
162
-            foreach ($this->resourceChanges() as $version => $model_classnames) {
163
-                if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
164
-                    $resource_changes[ $version ] = $model_classnames;
165
-                }
166
-            }
167
-            $this->cached_resource_changes_between_requested_version_and_current = $resource_changes;
168
-        }
169
-        return $this->cached_resource_changes_between_requested_version_and_current;
170
-    }
171
-
172
-
173
-    /**
174
-     * If a request was sent to 'wp-json/ee/v4.7/events' this would be '4.7'
175
-     *
176
-     * @return string like '4.6'
177
-     */
178
-    public function requestedVersion()
179
-    {
180
-        return $this->requested_version;
181
-    }
182
-
183
-
184
-    /**
185
-     * Returns an array describing how the models have changed in each version of core
186
-     * that supports the API (starting at 4.6)
187
-     * Top-level keys are versions (major and minor version numbers, eg "4.6")
188
-     * next-level keys are model names (eg "Event") that underwent some change in that version
189
-     * and the value is either NULL (indicating the model is completely NEW in this version),
190
-     * or it's an array where fields are value names.
191
-     * If a version is missing then we don't know anything about what changes it introduced from the previous version
192
-     *
193
-     * @return array
194
-     */
195
-    public function modelChanges()
196
-    {
197
-        return $this->model_changes;
198
-    }
199
-
200
-
201
-    /**
202
-     * Takes into account the requested version, and the current version, and
203
-     * what changed between the two, and tries to return.
204
-     * Analogous to EE_Registry::instance()->non_abstract_db_models
205
-     *
206
-     * @return array keys are model names, values are their classname
207
-     */
208
-    public function modelsForRequestedVersion()
209
-    {
210
-        if ($this->cached_models_for_requested_version === null) {
211
-            $all_models_in_current_version = EE_Registry::instance()->non_abstract_db_models;
212
-            foreach ($this->modelChangesBetweenRequestedVersionAndCurrent() as $version => $models_changed) {
213
-                foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
214
-                    if ($new_indicator_or_fields_added === ModelVersionInfo::MODEL_ADDED) {
215
-                        unset($all_models_in_current_version[ $model_name ]);
216
-                    }
217
-                }
218
-            }
219
-            $this->cached_models_for_requested_version = apply_filters(
220
-                'FHEE__EventEspresso_core_libraries_rest_api__models_for_requested_version',
221
-                $all_models_in_current_version,
222
-                $this
223
-            );
224
-        }
225
-        return $this->cached_models_for_requested_version;
226
-    }
227
-
228
-
229
-    /**
230
-     * Determines if this is a valid model name in the requested version.
231
-     * Similar to EE_Registry::instance()->is_model_name(), but takes the requested
232
-     * version's models into account
233
-     *
234
-     * @param string $model_name eg 'Event'
235
-     * @return boolean
236
-     */
237
-    public function isModelNameInThisVersion($model_name)
238
-    {
239
-        $model_names = $this->modelsForRequestedVersion();
240
-        if (isset($model_names[ $model_name ])) {
241
-            return true;
242
-        } else {
243
-            return false;
244
-        }
245
-    }
246
-
247
-
248
-    /**
249
-     * Wrapper for EE_Registry::instance()->load_model(), but takes the requested
250
-     * version's models into account
251
-     *
252
-     * @param string $model_name
253
-     * @return \EEM_Base
254
-     * @throws \EE_Error
255
-     */
256
-    public function loadModel($model_name)
257
-    {
258
-        if ($this->isModelNameInThisVersion($model_name)) {
259
-            return EE_Registry::instance()->load_model($model_name);
260
-        } else {
261
-            throw new \EE_Error(
262
-                sprintf(
263
-                    esc_html__(
264
-                        'Cannot load model "%1$s" because it does not exist in version %2$s of Event Espresso',
265
-                        'event_espresso'
266
-                    ),
267
-                    $model_name,
268
-                    $this->requestedVersion()
269
-                )
270
-            );
271
-        }
272
-    }
273
-
274
-
275
-    /**
276
-     * Gets all the fields that should exist on this model right now
277
-     *
278
-     * @param \EEM_Base $model
279
-     * @return array|\EE_Model_Field_Base[]
280
-     */
281
-    public function fieldsOnModelInThisVersion($model)
282
-    {
283
-        if (! isset($this->cached_fields_on_models[ $model->get_this_model_name() ])) {
284
-            // get all model changes between the requested version and current core version
285
-            $changes = $this->modelChangesBetweenRequestedVersionAndCurrent();
286
-            // fetch all fields currently on this model
287
-            $current_fields = $model->field_settings();
288
-            // remove all fields that have been added since
289
-            foreach ($changes as $version => $changes_in_version) {
290
-                if (
291
-                    isset($changes_in_version[ $model->get_this_model_name() ])
292
-                    && $changes_in_version[ $model->get_this_model_name() ] !== ModelVersionInfo::MODEL_ADDED
293
-                ) {
294
-                    $current_fields = array_diff_key(
295
-                        $current_fields,
296
-                        array_flip($changes_in_version[ $model->get_this_model_name() ])
297
-                    );
298
-                }
299
-            }
300
-            $this->cached_fields_on_models = $current_fields;
301
-        }
302
-        return $this->cached_fields_on_models;
303
-    }
304
-
305
-
306
-    /**
307
-     * Determines if $object is of one of the classes of $classes. Similar to
308
-     * in_array(), except this checks if $object is a subclass of the classnames provided
309
-     * in $classnames
310
-     *
311
-     * @param object $object
312
-     * @param array  $classnames
313
-     * @return boolean
314
-     */
315
-    public function isSubclassOfOne($object, $classnames)
316
-    {
317
-        foreach ($classnames as $classname) {
318
-            if (is_a($object, $classname)) {
319
-                return true;
320
-            }
321
-        }
322
-        return false;
323
-    }
324
-
325
-
326
-    /**
327
-     * Returns the list of model field classes that that the API basically ignores
328
-     *
329
-     * @return array
330
-     */
331
-    public function fieldsIgnored()
332
-    {
333
-        return apply_filters(
334
-            'FHEE__Controller_Model_Read_fields_ignored',
335
-            array()
336
-        );
337
-    }
338
-
339
-
340
-    /**
341
-     * If this field one that should be ignored by the API?
342
-     *
343
-     * @param EE_Model_Field_Base
344
-     * @return boolean
345
-     */
346
-    public function fieldIsIgnored($field_obj)
347
-    {
348
-        return $this->isSubclassOfOne($field_obj, $this->fieldsIgnored());
349
-    }
350
-
351
-
352
-    /**
353
-     * Returns the list of model field classes that have a "raw" and non-raw formats.
354
-     * Normally the "raw" versions are only accessible to those who can edit them.
355
-     *
356
-     * @return array an array of EE_Model_Field_Base child classnames
357
-     */
358
-    public function fieldsThatHaveRenderedFormat()
359
-    {
360
-        return apply_filters(
361
-            'FHEE__Controller_Model_Read__fields_raw',
362
-            array('EE_Post_Content_Field', 'EE_Full_HTML_Field')
363
-        );
364
-    }
365
-
366
-
367
-    /**
368
-     * If this field one that has a raw format
369
-     *
370
-     * @param EE_Model_Field_Base
371
-     * @return boolean
372
-     */
373
-    public function fieldHasRenderedFormat($field_obj)
374
-    {
375
-        return $this->isSubclassOfOne($field_obj, $this->fieldsThatHaveRenderedFormat());
376
-    }
377
-
378
-
379
-    /**
380
-     * Returns the list of model field classes that have a "_pretty" and non-pretty versions.
381
-     * The pretty version of the field is NOT query-able or editable, but requires no extra permissions
382
-     * to view
383
-     *
384
-     * @return array an array of EE_Model_Field_Base child classnames
385
-     */
386
-    public function fieldsThatHavePrettyFormat()
387
-    {
388
-        return apply_filters(
389
-            'FHEE__Controller_Model_Read__fields_pretty',
390
-            array('EE_Enum_Integer_Field', 'EE_Enum_Text_Field', 'EE_Money_Field')
391
-        );
392
-    }
393
-
394
-
395
-    /**
396
-     * If this field one that has a pretty equivalent
397
-     *
398
-     * @param EE_Model_Field_Base
399
-     * @return boolean
400
-     */
401
-    public function fieldHasPrettyFormat($field_obj)
402
-    {
403
-        return $this->isSubclassOfOne($field_obj, $this->fieldsThatHavePrettyFormat());
404
-    }
405
-
406
-
407
-    /**
408
-     * Returns an array describing what extra API resource properties have been added through the versions
409
-     *
410
-     * @return array @see $this->_extra_resource_properties_for_models
411
-     */
412
-    public function resourceChanges()
413
-    {
414
-        return $this->resource_changes;
415
-    }
416
-
417
-
418
-    /**
419
-     * Returns an array where keys are extra resource properties in this version of the API,
420
-     * and values are key-value pairs describing the new properties. @see Model_Version::_resource_changes
421
-     *
422
-     * @param \EEM_Base $model
423
-     * @return array
424
-     */
425
-    public function extraResourcePropertiesForModel($model)
426
-    {
427
-        $extra_properties = array();
428
-        foreach ($this->resourceChangesBetweenRequestedVersionAndCurrent() as $version => $model_classnames) {
429
-            foreach ($model_classnames as $model_classname => $properties_added_in_this_version) {
430
-                if (is_subclass_of($model, $model_classname)) {
431
-                    $extra_properties = array_merge($extra_properties, $properties_added_in_this_version);
432
-                }
433
-            }
434
-        }
435
-        return $extra_properties;
436
-    }
437
-
438
-
439
-    /**
440
-     * Gets all the related models for the specified model. It's good to use this
441
-     * in case this model didn't exist for this version or something
442
-     *
443
-     * @param \EEM_Base $model
444
-     * @return \EE_Model_Relation_Base[]
445
-     */
446
-    public function relationSettings(\EEM_Base $model)
447
-    {
448
-        $relations = array();
449
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
450
-            if ($this->isModelNameInThisVersion($relation_name)) {
451
-                $relations[ $relation_name ] = $relation_obj;
452
-            }
453
-        }
454
-        // filter the results, but use the old filter name
455
-        return apply_filters(
456
-            'FHEE__Read__create_entity_from_wpdb_result__related_models_to_include',
457
-            $relations,
458
-            $model
459
-        );
460
-    }
24
+	/**
25
+	 * Constant used in the $_model_changes array to indicate that a model
26
+	 * was completely new in this version
27
+	 */
28
+	const MODEL_ADDED = 'model_added_in_this_version';
29
+
30
+	/**
31
+	 * Top-level keys are versions (major and minor version numbers, eg "4.6")
32
+	 * next-level keys are model names (eg "Event") that underwent some change in that version
33
+	 * and the value is either Model_Version_Info::model_added (indicating the model is completely NEW in this version),
34
+	 * or it's an array where the values are model field names,
35
+	 * or API resource properties (ie, non-model fields that appear in REST API results)
36
+	 * If a version is missing then we don't know anything about what changes it introduced from the previous version
37
+	 *
38
+	 * @var array
39
+	 */
40
+	protected $model_changes = array();
41
+
42
+	/**
43
+	 * top-level keys are version numbers,
44
+	 * next-level keys are model CLASSNAMES (even parent classnames),
45
+	 * and next-level keys are extra resource properties to attach to those models' resources,
46
+	 * and next-level key-value pairs, where the keys are:
47
+	 * 'raw', 'type', 'nullable', 'table_alias', 'table_column',  'always_available'
48
+	 *
49
+	 * @var array
50
+	 */
51
+	protected $resource_changes = array();
52
+
53
+	/**
54
+	 * @var string indicating what version of the API was requested
55
+	 * (eg although core might be at version 4.8.11, they may have sent a request
56
+	 * for 4.6)
57
+	 */
58
+	protected $requested_version = null;
59
+
60
+	/**
61
+	 * Keys are model names, values are their classnames.
62
+	 * We cache this so we only need to calculate this once per request
63
+	 *
64
+	 * @var array
65
+	 */
66
+	protected $cached_models_for_requested_version = null;
67
+
68
+	/**
69
+	 * @var array
70
+	 */
71
+	protected $cached_model_changes_between_requested_version_and_current = null;
72
+
73
+	/**
74
+	 * @var array
75
+	 */
76
+	protected $cached_resource_changes_between_requested_version_and_current = null;
77
+
78
+	/**
79
+	 * 2d array where top-level keys are model names, 2nd-level keys are field names
80
+	 * and values are the actual field objects
81
+	 *
82
+	 * @var array
83
+	 */
84
+	protected $cached_fields_on_models = array();
85
+
86
+
87
+	/**
88
+	 * Model_Version_Info constructor.
89
+	 *
90
+	 * @param string $requested_version
91
+	 */
92
+	public function __construct($requested_version)
93
+	{
94
+		$this->requested_version = (string) $requested_version;
95
+		$this->model_changes = array(
96
+			'4.8.29' => array(
97
+				// first version where the REST API is in EE core, so no need
98
+				// to specify how its different from the previous
99
+			),
100
+		);
101
+		// setup data for "extra" fields added onto resources which don't actually exist on models
102
+		$this->resource_changes = apply_filters(
103
+			'FHEE__Model_Version_Info___construct__extra_resource_properties_for_models',
104
+			array()
105
+		);
106
+		$defaults = array(
107
+			'raw'              => false,
108
+			'type'             => 'N/A',
109
+			'nullable'         => true,
110
+			'table_alias'      => 'N/A',
111
+			'table_column'     => 'N/A',
112
+			'always_available' => true,
113
+		);
114
+		foreach ($this->resource_changes as $version => $model_classnames) {
115
+			foreach ($model_classnames as $model_classname => $extra_fields) {
116
+				foreach ($extra_fields as $fieldname => $field_data) {
117
+					$this->resource_changes[ $model_classname ][ $fieldname ]['name'] = $fieldname;
118
+					foreach ($defaults as $attribute => $default_value) {
119
+						if (! isset($this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ])) {
120
+							$this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ] = $default_value;
121
+						}
122
+					}
123
+				}
124
+			}
125
+		}
126
+	}
127
+
128
+
129
+	/**
130
+	 * Returns a slice of Model_Version_Info::model_changes()'s array
131
+	 * indicating exactly what changes happened between the current core version,
132
+	 * and the version requested
133
+	 *
134
+	 * @return array
135
+	 */
136
+	public function modelChangesBetweenRequestedVersionAndCurrent()
137
+	{
138
+		if ($this->cached_model_changes_between_requested_version_and_current === null) {
139
+			$model_changes = array();
140
+			foreach ($this->modelChanges() as $version => $models_changed_in_version) {
141
+				if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
142
+					$model_changes[ $version ] = $models_changed_in_version;
143
+				}
144
+			}
145
+			$this->cached_model_changes_between_requested_version_and_current = $model_changes;
146
+		}
147
+		return $this->cached_model_changes_between_requested_version_and_current;
148
+	}
149
+
150
+
151
+	/**
152
+	 * Returns a slice of Model_Version_Info::model_changes()'s array
153
+	 * indicating exactly what changes happened between the current core version,
154
+	 * and the version requested
155
+	 *
156
+	 * @return array
157
+	 */
158
+	public function resourceChangesBetweenRequestedVersionAndCurrent()
159
+	{
160
+		if ($this->cached_resource_changes_between_requested_version_and_current === null) {
161
+			$resource_changes = array();
162
+			foreach ($this->resourceChanges() as $version => $model_classnames) {
163
+				if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
164
+					$resource_changes[ $version ] = $model_classnames;
165
+				}
166
+			}
167
+			$this->cached_resource_changes_between_requested_version_and_current = $resource_changes;
168
+		}
169
+		return $this->cached_resource_changes_between_requested_version_and_current;
170
+	}
171
+
172
+
173
+	/**
174
+	 * If a request was sent to 'wp-json/ee/v4.7/events' this would be '4.7'
175
+	 *
176
+	 * @return string like '4.6'
177
+	 */
178
+	public function requestedVersion()
179
+	{
180
+		return $this->requested_version;
181
+	}
182
+
183
+
184
+	/**
185
+	 * Returns an array describing how the models have changed in each version of core
186
+	 * that supports the API (starting at 4.6)
187
+	 * Top-level keys are versions (major and minor version numbers, eg "4.6")
188
+	 * next-level keys are model names (eg "Event") that underwent some change in that version
189
+	 * and the value is either NULL (indicating the model is completely NEW in this version),
190
+	 * or it's an array where fields are value names.
191
+	 * If a version is missing then we don't know anything about what changes it introduced from the previous version
192
+	 *
193
+	 * @return array
194
+	 */
195
+	public function modelChanges()
196
+	{
197
+		return $this->model_changes;
198
+	}
199
+
200
+
201
+	/**
202
+	 * Takes into account the requested version, and the current version, and
203
+	 * what changed between the two, and tries to return.
204
+	 * Analogous to EE_Registry::instance()->non_abstract_db_models
205
+	 *
206
+	 * @return array keys are model names, values are their classname
207
+	 */
208
+	public function modelsForRequestedVersion()
209
+	{
210
+		if ($this->cached_models_for_requested_version === null) {
211
+			$all_models_in_current_version = EE_Registry::instance()->non_abstract_db_models;
212
+			foreach ($this->modelChangesBetweenRequestedVersionAndCurrent() as $version => $models_changed) {
213
+				foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
214
+					if ($new_indicator_or_fields_added === ModelVersionInfo::MODEL_ADDED) {
215
+						unset($all_models_in_current_version[ $model_name ]);
216
+					}
217
+				}
218
+			}
219
+			$this->cached_models_for_requested_version = apply_filters(
220
+				'FHEE__EventEspresso_core_libraries_rest_api__models_for_requested_version',
221
+				$all_models_in_current_version,
222
+				$this
223
+			);
224
+		}
225
+		return $this->cached_models_for_requested_version;
226
+	}
227
+
228
+
229
+	/**
230
+	 * Determines if this is a valid model name in the requested version.
231
+	 * Similar to EE_Registry::instance()->is_model_name(), but takes the requested
232
+	 * version's models into account
233
+	 *
234
+	 * @param string $model_name eg 'Event'
235
+	 * @return boolean
236
+	 */
237
+	public function isModelNameInThisVersion($model_name)
238
+	{
239
+		$model_names = $this->modelsForRequestedVersion();
240
+		if (isset($model_names[ $model_name ])) {
241
+			return true;
242
+		} else {
243
+			return false;
244
+		}
245
+	}
246
+
247
+
248
+	/**
249
+	 * Wrapper for EE_Registry::instance()->load_model(), but takes the requested
250
+	 * version's models into account
251
+	 *
252
+	 * @param string $model_name
253
+	 * @return \EEM_Base
254
+	 * @throws \EE_Error
255
+	 */
256
+	public function loadModel($model_name)
257
+	{
258
+		if ($this->isModelNameInThisVersion($model_name)) {
259
+			return EE_Registry::instance()->load_model($model_name);
260
+		} else {
261
+			throw new \EE_Error(
262
+				sprintf(
263
+					esc_html__(
264
+						'Cannot load model "%1$s" because it does not exist in version %2$s of Event Espresso',
265
+						'event_espresso'
266
+					),
267
+					$model_name,
268
+					$this->requestedVersion()
269
+				)
270
+			);
271
+		}
272
+	}
273
+
274
+
275
+	/**
276
+	 * Gets all the fields that should exist on this model right now
277
+	 *
278
+	 * @param \EEM_Base $model
279
+	 * @return array|\EE_Model_Field_Base[]
280
+	 */
281
+	public function fieldsOnModelInThisVersion($model)
282
+	{
283
+		if (! isset($this->cached_fields_on_models[ $model->get_this_model_name() ])) {
284
+			// get all model changes between the requested version and current core version
285
+			$changes = $this->modelChangesBetweenRequestedVersionAndCurrent();
286
+			// fetch all fields currently on this model
287
+			$current_fields = $model->field_settings();
288
+			// remove all fields that have been added since
289
+			foreach ($changes as $version => $changes_in_version) {
290
+				if (
291
+					isset($changes_in_version[ $model->get_this_model_name() ])
292
+					&& $changes_in_version[ $model->get_this_model_name() ] !== ModelVersionInfo::MODEL_ADDED
293
+				) {
294
+					$current_fields = array_diff_key(
295
+						$current_fields,
296
+						array_flip($changes_in_version[ $model->get_this_model_name() ])
297
+					);
298
+				}
299
+			}
300
+			$this->cached_fields_on_models = $current_fields;
301
+		}
302
+		return $this->cached_fields_on_models;
303
+	}
304
+
305
+
306
+	/**
307
+	 * Determines if $object is of one of the classes of $classes. Similar to
308
+	 * in_array(), except this checks if $object is a subclass of the classnames provided
309
+	 * in $classnames
310
+	 *
311
+	 * @param object $object
312
+	 * @param array  $classnames
313
+	 * @return boolean
314
+	 */
315
+	public function isSubclassOfOne($object, $classnames)
316
+	{
317
+		foreach ($classnames as $classname) {
318
+			if (is_a($object, $classname)) {
319
+				return true;
320
+			}
321
+		}
322
+		return false;
323
+	}
324
+
325
+
326
+	/**
327
+	 * Returns the list of model field classes that that the API basically ignores
328
+	 *
329
+	 * @return array
330
+	 */
331
+	public function fieldsIgnored()
332
+	{
333
+		return apply_filters(
334
+			'FHEE__Controller_Model_Read_fields_ignored',
335
+			array()
336
+		);
337
+	}
338
+
339
+
340
+	/**
341
+	 * If this field one that should be ignored by the API?
342
+	 *
343
+	 * @param EE_Model_Field_Base
344
+	 * @return boolean
345
+	 */
346
+	public function fieldIsIgnored($field_obj)
347
+	{
348
+		return $this->isSubclassOfOne($field_obj, $this->fieldsIgnored());
349
+	}
350
+
351
+
352
+	/**
353
+	 * Returns the list of model field classes that have a "raw" and non-raw formats.
354
+	 * Normally the "raw" versions are only accessible to those who can edit them.
355
+	 *
356
+	 * @return array an array of EE_Model_Field_Base child classnames
357
+	 */
358
+	public function fieldsThatHaveRenderedFormat()
359
+	{
360
+		return apply_filters(
361
+			'FHEE__Controller_Model_Read__fields_raw',
362
+			array('EE_Post_Content_Field', 'EE_Full_HTML_Field')
363
+		);
364
+	}
365
+
366
+
367
+	/**
368
+	 * If this field one that has a raw format
369
+	 *
370
+	 * @param EE_Model_Field_Base
371
+	 * @return boolean
372
+	 */
373
+	public function fieldHasRenderedFormat($field_obj)
374
+	{
375
+		return $this->isSubclassOfOne($field_obj, $this->fieldsThatHaveRenderedFormat());
376
+	}
377
+
378
+
379
+	/**
380
+	 * Returns the list of model field classes that have a "_pretty" and non-pretty versions.
381
+	 * The pretty version of the field is NOT query-able or editable, but requires no extra permissions
382
+	 * to view
383
+	 *
384
+	 * @return array an array of EE_Model_Field_Base child classnames
385
+	 */
386
+	public function fieldsThatHavePrettyFormat()
387
+	{
388
+		return apply_filters(
389
+			'FHEE__Controller_Model_Read__fields_pretty',
390
+			array('EE_Enum_Integer_Field', 'EE_Enum_Text_Field', 'EE_Money_Field')
391
+		);
392
+	}
393
+
394
+
395
+	/**
396
+	 * If this field one that has a pretty equivalent
397
+	 *
398
+	 * @param EE_Model_Field_Base
399
+	 * @return boolean
400
+	 */
401
+	public function fieldHasPrettyFormat($field_obj)
402
+	{
403
+		return $this->isSubclassOfOne($field_obj, $this->fieldsThatHavePrettyFormat());
404
+	}
405
+
406
+
407
+	/**
408
+	 * Returns an array describing what extra API resource properties have been added through the versions
409
+	 *
410
+	 * @return array @see $this->_extra_resource_properties_for_models
411
+	 */
412
+	public function resourceChanges()
413
+	{
414
+		return $this->resource_changes;
415
+	}
416
+
417
+
418
+	/**
419
+	 * Returns an array where keys are extra resource properties in this version of the API,
420
+	 * and values are key-value pairs describing the new properties. @see Model_Version::_resource_changes
421
+	 *
422
+	 * @param \EEM_Base $model
423
+	 * @return array
424
+	 */
425
+	public function extraResourcePropertiesForModel($model)
426
+	{
427
+		$extra_properties = array();
428
+		foreach ($this->resourceChangesBetweenRequestedVersionAndCurrent() as $version => $model_classnames) {
429
+			foreach ($model_classnames as $model_classname => $properties_added_in_this_version) {
430
+				if (is_subclass_of($model, $model_classname)) {
431
+					$extra_properties = array_merge($extra_properties, $properties_added_in_this_version);
432
+				}
433
+			}
434
+		}
435
+		return $extra_properties;
436
+	}
437
+
438
+
439
+	/**
440
+	 * Gets all the related models for the specified model. It's good to use this
441
+	 * in case this model didn't exist for this version or something
442
+	 *
443
+	 * @param \EEM_Base $model
444
+	 * @return \EE_Model_Relation_Base[]
445
+	 */
446
+	public function relationSettings(\EEM_Base $model)
447
+	{
448
+		$relations = array();
449
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
450
+			if ($this->isModelNameInThisVersion($relation_name)) {
451
+				$relations[ $relation_name ] = $relation_obj;
452
+			}
453
+		}
454
+		// filter the results, but use the old filter name
455
+		return apply_filters(
456
+			'FHEE__Read__create_entity_from_wpdb_result__related_models_to_include',
457
+			$relations,
458
+			$model
459
+		);
460
+	}
461 461
 }
Please login to merge, or discard this patch.
core/libraries/messages/EE_Messages_Base.lib.php 2 patches
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -196,11 +196,11 @@  discard block
 block discarded – undo
196 196
             ! empty($messenger)
197 197
             && $Message_Resource_Manager->is_message_type_active_for_messenger($messenger, $this->name)
198 198
         ) {
199
-            $settings_to_use = $active_messengers[ $messenger ]['settings'][ $messenger . '-message_types' ];
199
+            $settings_to_use = $active_messengers[$messenger]['settings'][$messenger.'-message_types'];
200 200
         }
201 201
 
202
-        $this->_existing_admin_settings = isset($settings_to_use[ $this->name ]['settings'])
203
-            ? $settings_to_use[ $this->name ]['settings']
202
+        $this->_existing_admin_settings = isset($settings_to_use[$this->name]['settings'])
203
+            ? $settings_to_use[$this->name]['settings']
204 204
             : null;
205 205
     }
206 206
 
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
     public function get_valid_shortcodes()
241 241
     {
242 242
         $valid_shortcodes = apply_filters(
243
-            'FHEE__' . get_class($this) . '__get_valid_shortcodes',
243
+            'FHEE__'.get_class($this).'__get_valid_shortcodes',
244 244
             $this->_valid_shortcodes,
245 245
             $this
246 246
         );
@@ -283,19 +283,19 @@  discard block
 block discarded – undo
283 283
     protected function _get_admin_page_content($page, $action, $extra, $actives)
284 284
     {
285 285
         // we can also further refine the context by action (if present).
286
-        if (!empty($action)) {
287
-            $page = $page . '_' . $action;
286
+        if ( ! empty($action)) {
287
+            $page = $page.'_'.$action;
288 288
         }
289 289
 
290
-        if (!isset($this->admin_registered_pages[ $page ])) {
290
+        if ( ! isset($this->admin_registered_pages[$page])) {
291 291
             // todo: a place to throw an exception?
292 292
             // We need to indicate there is no registered page so this function is not being called correctly.
293 293
             return false;
294 294
         }
295 295
         // k made it here so let's call the method
296 296
         $content = call_user_func_array(
297
-            array( $this, '_get_admin_content_' . $page ),
298
-            array( $actives, $extra )
297
+            array($this, '_get_admin_content_'.$page),
298
+            array($actives, $extra)
299 299
         );
300 300
         if ($content === false) {
301 301
             // todo this needs to be an exception once we've got exceptions in place.
Please login to merge, or discard this patch.
Indentation   +265 added lines, -265 removed lines patch added patch discarded remove patch
@@ -14,44 +14,44 @@  discard block
 block discarded – undo
14 14
 abstract class EE_Messages_Base extends EE_Base
15 15
 {
16 16
 
17
-    /** DETAILS PROPERTIES **/
18
-    /**
19
-     * The following are used to hold details on the type for reference (i.e. on admin screens)
20
-     * and also used by the EE_message_type object to figure out where to get template data.
21
-     */
22
-    public $name;
23
-    public $description;
24
-    protected $_messages_item_type; // messenger OR message_type?
25
-
26
-
27
-    /**
28
-     * This is an array describing the ui facing labels
29
-     * that will be used whenever the messenger is referenced in the ui
30
-     *
31
-     * array(
32
-     *  'singular' => esc_html__('something'),
33
-     *  'plural' => esc_html__('somethings')
34
-     * )
35
-     *
36
-     * @var array
37
-     */
38
-    public $label;
39
-
40
-
41
-
42
-
43
-    /**
44
-     * This property when set will hold the slugs of all EE admin pages that we will need to retrieve fields for
45
-     * (and used to determine which callback method to call from the child class)
46
-     *
47
-     * structure should be
48
-     * array(
49
-     * 'page_action' => true
50
-     * )
51
-     *
17
+	/** DETAILS PROPERTIES **/
18
+	/**
19
+	 * The following are used to hold details on the type for reference (i.e. on admin screens)
20
+	 * and also used by the EE_message_type object to figure out where to get template data.
21
+	 */
22
+	public $name;
23
+	public $description;
24
+	protected $_messages_item_type; // messenger OR message_type?
25
+
26
+
27
+	/**
28
+	 * This is an array describing the ui facing labels
29
+	 * that will be used whenever the messenger is referenced in the ui
30
+	 *
31
+	 * array(
32
+	 *  'singular' => esc_html__('something'),
33
+	 *  'plural' => esc_html__('somethings')
34
+	 * )
35
+	 *
36
+	 * @var array
37
+	 */
38
+	public $label;
39
+
40
+
41
+
42
+
43
+	/**
44
+	 * This property when set will hold the slugs of all EE admin pages that we will need to retrieve fields for
45
+	 * (and used to determine which callback method to call from the child class)
46
+	 *
47
+	 * structure should be
48
+	 * array(
49
+	 * 'page_action' => true
50
+	 * )
51
+	 *
52 52
 *@var array
53
-     */
54
-    public $admin_registered_pages = array();
53
+	 */
54
+	public $admin_registered_pages = array();
55 55
 
56 56
 
57 57
 
@@ -60,265 +60,265 @@  discard block
 block discarded – undo
60 60
 
61 61
 
62 62
 
63
-    /**
64
-     * this property holds any specific fields for holding any settings related to a messenger (if any needed)
65
-     * @var array
66
-     */
67
-    protected $_admin_settings_fields = array();
63
+	/**
64
+	 * this property holds any specific fields for holding any settings related to a messenger (if any needed)
65
+	 * @var array
66
+	 */
67
+	protected $_admin_settings_fields = array();
68 68
 
69 69
 
70 70
 
71 71
 
72 72
 
73
-    /**
74
-     * this property will hold any existing settings that may have been set in the admin.
75
-     * @var array
76
-     */
77
-    protected $_existing_admin_settings = array();
73
+	/**
74
+	 * this property will hold any existing settings that may have been set in the admin.
75
+	 * @var array
76
+	 */
77
+	protected $_existing_admin_settings = array();
78 78
 
79 79
 
80 80
 
81 81
 
82 82
 
83
-    /**
84
-     * this property will hold an array of valid shortcodes for this message type and messengers.
85
-     * #For Message Types:
86
-     * This is an array of strings that correspond to defined EE_Shortcode libraries and per context.
87
-     * For example:
88
-     * array( 'admin' => array('transaction', 'event', 'attendee') )
89
-     * corresponds to 'EE_Transaction_Shortcodes.lib.php, EE_Event_Shortcodes.lib.php, EE_Attendee_Shortcodes.lib.php'
90
-     * for the admin context;
91
-     *
92
-     *
93
-     * #For Messengers:
94
-     * For example:
95
-     * array('subject' => array('transaction', 'event', 'attendee'))
96
-     * corresponds to 'EE_Transaction_Shortcodes.lib.php, EE_Event_Shortcodes.lib.php, EE_Attendee_Shortcodes.lib.php'
97
-     * for the 'subject' field;
98
-     * NOTE:  by default, with messengers, if the valid shortcodes for a field is left blank,
99
-     * that field will inherit whatever are set as valid shortcodes by message_type.
100
-     * This is so messenger can set specific valid codes for fields and leave other
101
-     * valid shortcodes up to the message type matched with the messenger.
102
-     *
103
-     * @access protected
104
-     * @var array
105
-     */
106
-    protected $_valid_shortcodes = array();
83
+	/**
84
+	 * this property will hold an array of valid shortcodes for this message type and messengers.
85
+	 * #For Message Types:
86
+	 * This is an array of strings that correspond to defined EE_Shortcode libraries and per context.
87
+	 * For example:
88
+	 * array( 'admin' => array('transaction', 'event', 'attendee') )
89
+	 * corresponds to 'EE_Transaction_Shortcodes.lib.php, EE_Event_Shortcodes.lib.php, EE_Attendee_Shortcodes.lib.php'
90
+	 * for the admin context;
91
+	 *
92
+	 *
93
+	 * #For Messengers:
94
+	 * For example:
95
+	 * array('subject' => array('transaction', 'event', 'attendee'))
96
+	 * corresponds to 'EE_Transaction_Shortcodes.lib.php, EE_Event_Shortcodes.lib.php, EE_Attendee_Shortcodes.lib.php'
97
+	 * for the 'subject' field;
98
+	 * NOTE:  by default, with messengers, if the valid shortcodes for a field is left blank,
99
+	 * that field will inherit whatever are set as valid shortcodes by message_type.
100
+	 * This is so messenger can set specific valid codes for fields and leave other
101
+	 * valid shortcodes up to the message type matched with the messenger.
102
+	 *
103
+	 * @access protected
104
+	 * @var array
105
+	 */
106
+	protected $_valid_shortcodes = array();
107 107
 
108 108
 
109 109
 
110 110
 
111 111
 
112
-    public function __construct()
113
-    {
114
-        $this->_set_admin_settings_fields();
115
-        $this->_set_valid_shortcodes();
116
-        $this->_set_admin_pages();
117
-    }
112
+	public function __construct()
113
+	{
114
+		$this->_set_admin_settings_fields();
115
+		$this->_set_valid_shortcodes();
116
+		$this->_set_admin_pages();
117
+	}
118 118
 
119 119
 
120 120
 
121 121
 
122 122
 
123
-    /**
124
-     * sets the _admin_settings_fields property which needs to be defined by child classes.
125
-     * You will want to set the _admin_settings_fields properties as a multi-dimensional array with the following format
126
-     * array(
127
-     *      {field_name - also used for setting index} => array(
128
-     *          'field_type' => {type of field: 'text', 'textarea', 'checkbox'},
129
-     *          'value_type' => {type of value: 'string', 'int', 'array', 'bool'},
130
-     *          'required' => {bool, required or not},
131
-     *          'validation' => {bool, true if we want validation, false if not},
132
-     *          'format' => {%d, or %s},
133
-     *          'label' => {label for the field, make sure it's localized},
134
-     *          'default' => {default value for the setting}
135
-     *      ),
136
-     * );
137
-     *
138
-     * @abstract
139
-     * @access protected
140
-     * @return void
141
-     */
142
-    abstract protected function _set_admin_settings_fields();
123
+	/**
124
+	 * sets the _admin_settings_fields property which needs to be defined by child classes.
125
+	 * You will want to set the _admin_settings_fields properties as a multi-dimensional array with the following format
126
+	 * array(
127
+	 *      {field_name - also used for setting index} => array(
128
+	 *          'field_type' => {type of field: 'text', 'textarea', 'checkbox'},
129
+	 *          'value_type' => {type of value: 'string', 'int', 'array', 'bool'},
130
+	 *          'required' => {bool, required or not},
131
+	 *          'validation' => {bool, true if we want validation, false if not},
132
+	 *          'format' => {%d, or %s},
133
+	 *          'label' => {label for the field, make sure it's localized},
134
+	 *          'default' => {default value for the setting}
135
+	 *      ),
136
+	 * );
137
+	 *
138
+	 * @abstract
139
+	 * @access protected
140
+	 * @return void
141
+	 */
142
+	abstract protected function _set_admin_settings_fields();
143 143
 
144 144
 
145 145
 
146 146
 
147 147
 
148
-    /**
149
-     * sets any properties on whether a message type or messenger interface shows up on a ee administration page.
150
-     * Child classes have to define this method but don't necessarily have to set the flags
151
-     * as they will be set to false by default.
152
-     *
153
-     * Child classes use this method to set the `_admin_registered_page` property.
154
-     * That property is to indicate what EE admin pages we have a corresponding callback for in the child class
155
-     * so Message Type/messenger fields/content is included on that admin page.
156
-     *
157
-     * @abstract
158
-     * @access protected
159
-     * @return void
160
-     */
161
-    abstract protected function _set_admin_pages();
148
+	/**
149
+	 * sets any properties on whether a message type or messenger interface shows up on a ee administration page.
150
+	 * Child classes have to define this method but don't necessarily have to set the flags
151
+	 * as they will be set to false by default.
152
+	 *
153
+	 * Child classes use this method to set the `_admin_registered_page` property.
154
+	 * That property is to indicate what EE admin pages we have a corresponding callback for in the child class
155
+	 * so Message Type/messenger fields/content is included on that admin page.
156
+	 *
157
+	 * @abstract
158
+	 * @access protected
159
+	 * @return void
160
+	 */
161
+	abstract protected function _set_admin_pages();
162 162
 
163 163
 
164 164
 
165 165
 
166 166
 
167
-    /**
168
-     * Child classes must declare the $_valid_shortcodes property using this method.
169
-     * See comments for $_valid_shortcodes property for details on what it is used for.
170
-     *
171
-     * @access protected
172
-     * @return void
173
-     */
174
-    abstract protected function _set_valid_shortcodes();
167
+	/**
168
+	 * Child classes must declare the $_valid_shortcodes property using this method.
169
+	 * See comments for $_valid_shortcodes property for details on what it is used for.
170
+	 *
171
+	 * @access protected
172
+	 * @return void
173
+	 */
174
+	abstract protected function _set_valid_shortcodes();
175 175
 
176 176
 
177 177
 
178
-    /**
179
-     * sets the _existing_admin_settings property can be overridden by child classes.
180
-     * We do this so we only do database calls if needed.
181
-     *
182
-     * @access protected
183
-     * @param string $messenger
184
-     */
185
-    protected function _set_existing_admin_settings($messenger = '')
186
-    {
187
-        /** @var EE_Message_Resource_Manager $Message_Resource_Manager */
188
-        $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
189
-        $active_messengers = $Message_Resource_Manager->get_active_messengers_option();
190
-        $settings_to_use = $active_messengers;
191
-
192
-        /**
193
-         * This determines what will be used for the getting the settings.
194
-         */
195
-        if (
196
-            ! empty($messenger)
197
-            && $Message_Resource_Manager->is_message_type_active_for_messenger($messenger, $this->name)
198
-        ) {
199
-            $settings_to_use = $active_messengers[ $messenger ]['settings'][ $messenger . '-message_types' ];
200
-        }
201
-
202
-        $this->_existing_admin_settings = isset($settings_to_use[ $this->name ]['settings'])
203
-            ? $settings_to_use[ $this->name ]['settings']
204
-            : null;
205
-    }
206
-
207
-
208
-
209
-
210
-
211
-
212
-    /**
213
-     * get_existing_admin_settings
214
-     * (if needed) sets and returns the _existing_admin_settings property.
215
-     *
216
-     * @access public
217
-     * @param string $messenger
218
-     * @return array          settings
219
-     */
220
-    public function get_existing_admin_settings($messenger = '')
221
-    {
222
-        // if admin_settings property empty lets try setting it.
223
-        if (method_exists($this, '_set_existing_admin_settings') && empty($this->_existing_admin_settings)) {
224
-            $this->_set_existing_admin_settings($messenger);
225
-        }
226
-        return property_exists($this, '_existing_admin_settings')
227
-            ? $this->_existing_admin_settings
228
-            : null;
229
-    }
230
-
231
-
232
-
233
-
234
-
235
-
236
-    /**
237
-     * This returns the array of valid shortcodes for a message type or messenger as set by the child in the $_valid_shortcode property.
238
-     * @return array   an array of valid shortcodes.
239
-     */
240
-    public function get_valid_shortcodes()
241
-    {
242
-        $valid_shortcodes = apply_filters(
243
-            'FHEE__' . get_class($this) . '__get_valid_shortcodes',
244
-            $this->_valid_shortcodes,
245
-            $this
246
-        );
247
-        // The below filter applies to ALL messengers and message types so use with care!
248
-        $valid_shortcodes = apply_filters('FHEE__EE_Messages_Base__get_valid_shortcodes', $valid_shortcodes, $this);
249
-        return $valid_shortcodes;
250
-    }
251
-
252
-
253
-
254
-
255
-    /**
256
-     * getter that returns the protected admin_settings_fields property
257
-     *
258
-     * @access public
259
-     * @return array admin settings fields
260
-     */
261
-    public function get_admin_settings_fields()
262
-    {
263
-        return $this->_admin_settings_fields;
264
-    }
265
-
266
-
267
-
268
-
269
-
270
-    /**
271
-     * this public method accepts a page slug (for an EE_admin page)
272
-     * and will return the response from the child class callback function
273
-     * if that page is registered via the `_admin_registered_page` property set by the child class.
274
-     *
275
-     * @param string $page the slug of the EE admin page
276
-     * @param array $actives an array of active message type (or messenger) objects.
277
-     * @param string $action the page action (to allow for more specific handling - i.e. edit vs. add pages)
278
-     * @param array $extra This is just an extra argument that can be used
279
-     *                     to pass additional data for setting up page content.
280
-     * @access protected
281
-     * @return string $content for page.
282
-     */
283
-    protected function _get_admin_page_content($page, $action, $extra, $actives)
284
-    {
285
-        // we can also further refine the context by action (if present).
286
-        if (!empty($action)) {
287
-            $page = $page . '_' . $action;
288
-        }
289
-
290
-        if (!isset($this->admin_registered_pages[ $page ])) {
291
-            // todo: a place to throw an exception?
292
-            // We need to indicate there is no registered page so this function is not being called correctly.
293
-            return false;
294
-        }
295
-        // k made it here so let's call the method
296
-        $content = call_user_func_array(
297
-            array( $this, '_get_admin_content_' . $page ),
298
-            array( $actives, $extra )
299
-        );
300
-        if ($content === false) {
301
-            // todo this needs to be an exception once we've got exceptions in place.
302
-            return false;
303
-        }
304
-        return $content;
305
-    }
306
-
307
-
308
-    /**
309
-     * Allows a message type to specifically exclude template fields for the provided messenger.
310
-     * Filtered so this can be programmatically altered as well.
311
-     * @param string $messenger_name name of messenger
312
-     * @return array
313
-     */
314
-    public function excludedFieldsForMessenger($messenger_name)
315
-    {
316
-        return apply_filters(
317
-            'FHEE__EE_Messages_Base__excludedFieldForMessenger',
318
-            array(),
319
-            $messenger_name,
320
-            $this->name,
321
-            $this
322
-        );
323
-    }
178
+	/**
179
+	 * sets the _existing_admin_settings property can be overridden by child classes.
180
+	 * We do this so we only do database calls if needed.
181
+	 *
182
+	 * @access protected
183
+	 * @param string $messenger
184
+	 */
185
+	protected function _set_existing_admin_settings($messenger = '')
186
+	{
187
+		/** @var EE_Message_Resource_Manager $Message_Resource_Manager */
188
+		$Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
189
+		$active_messengers = $Message_Resource_Manager->get_active_messengers_option();
190
+		$settings_to_use = $active_messengers;
191
+
192
+		/**
193
+		 * This determines what will be used for the getting the settings.
194
+		 */
195
+		if (
196
+			! empty($messenger)
197
+			&& $Message_Resource_Manager->is_message_type_active_for_messenger($messenger, $this->name)
198
+		) {
199
+			$settings_to_use = $active_messengers[ $messenger ]['settings'][ $messenger . '-message_types' ];
200
+		}
201
+
202
+		$this->_existing_admin_settings = isset($settings_to_use[ $this->name ]['settings'])
203
+			? $settings_to_use[ $this->name ]['settings']
204
+			: null;
205
+	}
206
+
207
+
208
+
209
+
210
+
211
+
212
+	/**
213
+	 * get_existing_admin_settings
214
+	 * (if needed) sets and returns the _existing_admin_settings property.
215
+	 *
216
+	 * @access public
217
+	 * @param string $messenger
218
+	 * @return array          settings
219
+	 */
220
+	public function get_existing_admin_settings($messenger = '')
221
+	{
222
+		// if admin_settings property empty lets try setting it.
223
+		if (method_exists($this, '_set_existing_admin_settings') && empty($this->_existing_admin_settings)) {
224
+			$this->_set_existing_admin_settings($messenger);
225
+		}
226
+		return property_exists($this, '_existing_admin_settings')
227
+			? $this->_existing_admin_settings
228
+			: null;
229
+	}
230
+
231
+
232
+
233
+
234
+
235
+
236
+	/**
237
+	 * This returns the array of valid shortcodes for a message type or messenger as set by the child in the $_valid_shortcode property.
238
+	 * @return array   an array of valid shortcodes.
239
+	 */
240
+	public function get_valid_shortcodes()
241
+	{
242
+		$valid_shortcodes = apply_filters(
243
+			'FHEE__' . get_class($this) . '__get_valid_shortcodes',
244
+			$this->_valid_shortcodes,
245
+			$this
246
+		);
247
+		// The below filter applies to ALL messengers and message types so use with care!
248
+		$valid_shortcodes = apply_filters('FHEE__EE_Messages_Base__get_valid_shortcodes', $valid_shortcodes, $this);
249
+		return $valid_shortcodes;
250
+	}
251
+
252
+
253
+
254
+
255
+	/**
256
+	 * getter that returns the protected admin_settings_fields property
257
+	 *
258
+	 * @access public
259
+	 * @return array admin settings fields
260
+	 */
261
+	public function get_admin_settings_fields()
262
+	{
263
+		return $this->_admin_settings_fields;
264
+	}
265
+
266
+
267
+
268
+
269
+
270
+	/**
271
+	 * this public method accepts a page slug (for an EE_admin page)
272
+	 * and will return the response from the child class callback function
273
+	 * if that page is registered via the `_admin_registered_page` property set by the child class.
274
+	 *
275
+	 * @param string $page the slug of the EE admin page
276
+	 * @param array $actives an array of active message type (or messenger) objects.
277
+	 * @param string $action the page action (to allow for more specific handling - i.e. edit vs. add pages)
278
+	 * @param array $extra This is just an extra argument that can be used
279
+	 *                     to pass additional data for setting up page content.
280
+	 * @access protected
281
+	 * @return string $content for page.
282
+	 */
283
+	protected function _get_admin_page_content($page, $action, $extra, $actives)
284
+	{
285
+		// we can also further refine the context by action (if present).
286
+		if (!empty($action)) {
287
+			$page = $page . '_' . $action;
288
+		}
289
+
290
+		if (!isset($this->admin_registered_pages[ $page ])) {
291
+			// todo: a place to throw an exception?
292
+			// We need to indicate there is no registered page so this function is not being called correctly.
293
+			return false;
294
+		}
295
+		// k made it here so let's call the method
296
+		$content = call_user_func_array(
297
+			array( $this, '_get_admin_content_' . $page ),
298
+			array( $actives, $extra )
299
+		);
300
+		if ($content === false) {
301
+			// todo this needs to be an exception once we've got exceptions in place.
302
+			return false;
303
+		}
304
+		return $content;
305
+	}
306
+
307
+
308
+	/**
309
+	 * Allows a message type to specifically exclude template fields for the provided messenger.
310
+	 * Filtered so this can be programmatically altered as well.
311
+	 * @param string $messenger_name name of messenger
312
+	 * @return array
313
+	 */
314
+	public function excludedFieldsForMessenger($messenger_name)
315
+	{
316
+		return apply_filters(
317
+			'FHEE__EE_Messages_Base__excludedFieldForMessenger',
318
+			array(),
319
+			$messenger_name,
320
+			$this->name,
321
+			$this
322
+		);
323
+	}
324 324
 }
Please login to merge, or discard this patch.
core/libraries/messages/EE_Messages_Scheduler.lib.php 2 patches
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -26,7 +26,7 @@  discard block
 block discarded – undo
26 26
     public function __construct()
27 27
     {
28 28
         // register tasks (and make sure only registered once).
29
-        if (! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
29
+        if ( ! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
30 30
             add_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'), 10);
31 31
         }
32 32
 
@@ -77,7 +77,7 @@  discard block
 block discarded – undo
77 77
         EE_Registry::instance()->load_helper('DTT_Helper');
78 78
         $tasks['AHEE__EE_Messages_Scheduler__generation'] = 'ee_message_cron';
79 79
         $tasks['AHEE__EE_Messages_Scheduler__sending']    = 'ee_message_cron';
80
-        $tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array( EEH_DTT_Helper::tomorrow(), 'daily');
80
+        $tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array(EEH_DTT_Helper::tomorrow(), 'daily');
81 81
         return $tasks;
82 82
     }
83 83
 
@@ -96,7 +96,7 @@  discard block
 block discarded – undo
96 96
                 true
97 97
             )
98 98
         ) {
99
-            $request_url  = add_query_arg(
99
+            $request_url = add_query_arg(
100 100
                 array_merge(
101 101
                     array('ee' => 'msg_cron_trigger'),
102 102
                     EE_Messages_Scheduler::get_request_params($task)
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
                 'sslverify'   => false,
110 110
                 'redirection' => 10,
111 111
             );
112
-            $response     = wp_remote_get($request_url, $request_args);
112
+            $response = wp_remote_get($request_url, $request_args);
113 113
             if (is_wp_error($response)) {
114 114
                 trigger_error($response->get_error_message());
115 115
             }
@@ -129,7 +129,7 @@  discard block
 block discarded – undo
129 129
     public static function get_request_params($task)
130 130
     {
131 131
         // transient is used for flood control on msg_cron_trigger requests
132
-        $transient_key = 'ee_trans_' . uniqid($task);
132
+        $transient_key = 'ee_trans_'.uniqid($task);
133 133
         set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
134 134
         return array(
135 135
             'type' => $task,
@@ -202,7 +202,7 @@  discard block
 block discarded – undo
202 202
             'AHEE__EE_Messages_Scheduler__sending'    => 'ee_message_cron',
203 203
         );
204 204
         foreach ($message_crons_to_check as $hook_name => $frequency) {
205
-            if (! wp_next_scheduled($hook_name)) {
205
+            if ( ! wp_next_scheduled($hook_name)) {
206 206
                 wp_schedule_event(time(), $frequency, $hook_name);
207 207
             }
208 208
         }
Please login to merge, or discard this patch.
Indentation   +221 added lines, -221 removed lines patch added patch discarded remove patch
@@ -14,225 +14,225 @@
 block discarded – undo
14 14
 class EE_Messages_Scheduler extends EE_Base
15 15
 {
16 16
 
17
-    /**
18
-     * Number of seconds between batch sends/generates on the cron job.
19
-     * Defaults to 5 minutes in seconds.  If you want to change this interval, you can use the native WordPress
20
-     * `cron_schedules` filter and modify the existing custom `ee_message_cron` schedule interval added.
21
-     *
22
-     * @type int
23
-     */
24
-    const message_cron_schedule = 300;
25
-
26
-    /**
27
-     * Constructor
28
-     */
29
-    public function __construct()
30
-    {
31
-        // register tasks (and make sure only registered once).
32
-        if (! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
33
-            add_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'), 10);
34
-        }
35
-
36
-        // register callbacks for scheduled events (but make sure they are set only once).
37
-        if (
38
-            ! has_action(
39
-                'AHEE__EE_Messages_Scheduler__generation',
40
-                array('EE_Messages_Scheduler', 'batch_generation')
41
-            )
42
-        ) {
43
-            add_action('AHEE__EE_Messages_Scheduler__generation', array('EE_Messages_Scheduler', 'batch_generation'));
44
-            add_action('AHEE__EE_Messages_Scheduler__sending', array('EE_Messages_Scheduler', 'batch_sending'));
45
-            add_action('AHEE__EE_Messages_Scheduler__cleanup', array('EE_Messages_Scheduler', 'cleanup'));
46
-        }
47
-
48
-        // add custom schedules
49
-        add_filter('cron_schedules', array($this, 'custom_schedules'));
50
-    }
51
-
52
-
53
-    /**
54
-     * Add custom schedules for wp_cron
55
-     *
56
-     * @param $schedules
57
-     */
58
-    public function custom_schedules($schedules)
59
-    {
60
-        $schedules['ee_message_cron'] = array(
61
-            'interval' => self::message_cron_schedule,
62
-            'display'  => esc_html__(
63
-                'This is the cron time interval for EE Message schedules (defaults to once every 5 minutes)',
64
-                'event_espresso'
65
-            ),
66
-        );
67
-        return $schedules;
68
-    }
69
-
70
-
71
-    /**
72
-     * Callback for FHEE__EEH_Activation__get_cron_tasks that is used to retrieve scheduled Cron events to add and
73
-     * remove.
74
-     *
75
-     * @param array $tasks already existing scheduled tasks
76
-     * @return array
77
-     * @throws EE_Error
78
-     * @throws ReflectionException
79
-     */
80
-    public function register_scheduled_tasks($tasks)
81
-    {
82
-        EE_Registry::instance()->load_helper('DTT_Helper');
83
-        $tasks['AHEE__EE_Messages_Scheduler__generation'] = 'ee_message_cron';
84
-        $tasks['AHEE__EE_Messages_Scheduler__sending']    = 'ee_message_cron';
85
-        $tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array( EEH_DTT_Helper::tomorrow(), 'daily');
86
-        return $tasks;
87
-    }
88
-
89
-
90
-    /**
91
-     * This initiates a non-blocking separate request to execute on a scheduled task.
92
-     * Note: The EED_Messages module has the handlers for these requests.
93
-     *
94
-     * @param string $task The task the request is being generated for.
95
-     */
96
-    public static function initiate_scheduled_non_blocking_request($task)
97
-    {
98
-        if (
99
-            apply_filters(
100
-                'EE_Messages_Scheduler__initiate_scheduled_non_blocking_request__do_separate_request',
101
-                true
102
-            )
103
-        ) {
104
-            $request_url  = add_query_arg(
105
-                array_merge(
106
-                    array('ee' => 'msg_cron_trigger'),
107
-                    EE_Messages_Scheduler::get_request_params($task)
108
-                ),
109
-                site_url()
110
-            );
111
-            $request_args = array(
112
-                'timeout'     => 300,
113
-                'blocking'    => (defined('DOING_CRON') && DOING_CRON)
114
-                                 || (defined('DOING_AJAX') && DOING_AJAX),
115
-                'sslverify'   => false,
116
-                'redirection' => 10,
117
-            );
118
-            $response     = wp_remote_get($request_url, $request_args);
119
-            if (is_wp_error($response)) {
120
-                trigger_error($response->get_error_message());
121
-            }
122
-        } else {
123
-            EE_Messages_Scheduler::initiate_immediate_request_on_cron($task);
124
-        }
125
-    }
126
-
127
-
128
-    /**
129
-     * This returns
130
-     * the request params used for a scheduled message task request.
131
-     *
132
-     * @param string $task The task the request is for.
133
-     * @return array
134
-     */
135
-    public static function get_request_params($task)
136
-    {
137
-        // transient is used for flood control on msg_cron_trigger requests
138
-        $transient_key = 'ee_trans_' . uniqid($task);
139
-        set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
140
-        return array(
141
-            'type' => $task,
142
-            'key'  => $transient_key,
143
-        );
144
-    }
145
-
146
-
147
-    /**
148
-     * This is used to execute an immediate call to the run_cron task performed by EED_Messages
149
-     *
150
-     * @param string $task The task the request is being generated for.
151
-     */
152
-    public static function initiate_immediate_request_on_cron($task)
153
-    {
154
-        /** @var RequestInterface $request */
155
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
156
-        $request_args = EE_Messages_Scheduler::get_request_params($task);
157
-        // set those request args in the request so it gets picked up
158
-        foreach ($request_args as $request_key => $request_value) {
159
-            $request->setRequestParam($request_key, $request_value);
160
-        }
161
-        EED_Messages::instance()->run_cron();
162
-    }
163
-
164
-
165
-    /**
166
-     * Callback for scheduled AHEE__EE_Messages_Scheduler__generation wp cron event
167
-     */
168
-    public static function batch_generation()
169
-    {
170
-        /**
171
-         * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
172
-         */
173
-        if (
174
-            ! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
175
-            || ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
176
-        ) {
177
-            EE_Messages_Scheduler::initiate_immediate_request_on_cron('generate');
178
-        }
179
-    }
180
-
181
-
182
-    /**
183
-     * Callback for scheduled AHEE__EE_Messages_Scheduler__sending
184
-     */
185
-    public static function batch_sending()
186
-    {
187
-        /**
188
-         * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
189
-         */
190
-        if (
191
-            ! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
192
-            || ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
193
-        ) {
194
-            EE_Messages_Scheduler::initiate_immediate_request_on_cron('send');
195
-        }
196
-    }
197
-
198
-
199
-    /**
200
-     * This is the callback for the `AHEE__EE_Messages_Scheduler__cleanup` scheduled event action.
201
-     * This runs once a day and if cleanup is active (set via messages settings), it will (by default) delete
202
-     * permanently from the database messages that have a MSG_modified date older than 30 days.
203
-     *
204
-     * @throws EE_Error
205
-     * @throws EE_Error
206
-     */
207
-    public static function cleanup()
208
-    {
209
-        // First, confirm that the generation and sending EE_Messages_Scheduler crons are
210
-        // set and reschedule them if they are not.
211
-        $message_crons_to_check = array(
212
-            'AHEE__EE_Messages_Scheduler__generation' => 'ee_message_cron',
213
-            'AHEE__EE_Messages_Scheduler__sending'    => 'ee_message_cron',
214
-        );
215
-        foreach ($message_crons_to_check as $hook_name => $frequency) {
216
-            if (! wp_next_scheduled($hook_name)) {
217
-                wp_schedule_event(time(), $frequency, $hook_name);
218
-            }
219
-        }
220
-
221
-        // check if user has cleanup turned on or if we're in maintenance mode.  If in maintenance mode we'll wait
222
-        // until the next scheduled event.
223
-        if (
224
-            ! EE_Registry::instance()->CFG->messages->delete_threshold
225
-            || ! EE_Maintenance_Mode::instance()->models_can_query()
226
-        ) {
227
-            return;
228
-        }
229
-
230
-        /**
231
-         * This filter switch allows other code (such as the EE_Worker_Queue add-on) to replace this with its own handling
232
-         * of deleting messages.
233
-         */
234
-        if (apply_filters('FHEE__EE_Messages_Scheduler__cleanup__handle_cleanup_on_cron', true)) {
235
-            EEM_Message::instance()->delete_old_messages(EE_Registry::instance()->CFG->messages->delete_threshold);
236
-        }
237
-    }
17
+	/**
18
+	 * Number of seconds between batch sends/generates on the cron job.
19
+	 * Defaults to 5 minutes in seconds.  If you want to change this interval, you can use the native WordPress
20
+	 * `cron_schedules` filter and modify the existing custom `ee_message_cron` schedule interval added.
21
+	 *
22
+	 * @type int
23
+	 */
24
+	const message_cron_schedule = 300;
25
+
26
+	/**
27
+	 * Constructor
28
+	 */
29
+	public function __construct()
30
+	{
31
+		// register tasks (and make sure only registered once).
32
+		if (! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
33
+			add_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'), 10);
34
+		}
35
+
36
+		// register callbacks for scheduled events (but make sure they are set only once).
37
+		if (
38
+			! has_action(
39
+				'AHEE__EE_Messages_Scheduler__generation',
40
+				array('EE_Messages_Scheduler', 'batch_generation')
41
+			)
42
+		) {
43
+			add_action('AHEE__EE_Messages_Scheduler__generation', array('EE_Messages_Scheduler', 'batch_generation'));
44
+			add_action('AHEE__EE_Messages_Scheduler__sending', array('EE_Messages_Scheduler', 'batch_sending'));
45
+			add_action('AHEE__EE_Messages_Scheduler__cleanup', array('EE_Messages_Scheduler', 'cleanup'));
46
+		}
47
+
48
+		// add custom schedules
49
+		add_filter('cron_schedules', array($this, 'custom_schedules'));
50
+	}
51
+
52
+
53
+	/**
54
+	 * Add custom schedules for wp_cron
55
+	 *
56
+	 * @param $schedules
57
+	 */
58
+	public function custom_schedules($schedules)
59
+	{
60
+		$schedules['ee_message_cron'] = array(
61
+			'interval' => self::message_cron_schedule,
62
+			'display'  => esc_html__(
63
+				'This is the cron time interval for EE Message schedules (defaults to once every 5 minutes)',
64
+				'event_espresso'
65
+			),
66
+		);
67
+		return $schedules;
68
+	}
69
+
70
+
71
+	/**
72
+	 * Callback for FHEE__EEH_Activation__get_cron_tasks that is used to retrieve scheduled Cron events to add and
73
+	 * remove.
74
+	 *
75
+	 * @param array $tasks already existing scheduled tasks
76
+	 * @return array
77
+	 * @throws EE_Error
78
+	 * @throws ReflectionException
79
+	 */
80
+	public function register_scheduled_tasks($tasks)
81
+	{
82
+		EE_Registry::instance()->load_helper('DTT_Helper');
83
+		$tasks['AHEE__EE_Messages_Scheduler__generation'] = 'ee_message_cron';
84
+		$tasks['AHEE__EE_Messages_Scheduler__sending']    = 'ee_message_cron';
85
+		$tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array( EEH_DTT_Helper::tomorrow(), 'daily');
86
+		return $tasks;
87
+	}
88
+
89
+
90
+	/**
91
+	 * This initiates a non-blocking separate request to execute on a scheduled task.
92
+	 * Note: The EED_Messages module has the handlers for these requests.
93
+	 *
94
+	 * @param string $task The task the request is being generated for.
95
+	 */
96
+	public static function initiate_scheduled_non_blocking_request($task)
97
+	{
98
+		if (
99
+			apply_filters(
100
+				'EE_Messages_Scheduler__initiate_scheduled_non_blocking_request__do_separate_request',
101
+				true
102
+			)
103
+		) {
104
+			$request_url  = add_query_arg(
105
+				array_merge(
106
+					array('ee' => 'msg_cron_trigger'),
107
+					EE_Messages_Scheduler::get_request_params($task)
108
+				),
109
+				site_url()
110
+			);
111
+			$request_args = array(
112
+				'timeout'     => 300,
113
+				'blocking'    => (defined('DOING_CRON') && DOING_CRON)
114
+								 || (defined('DOING_AJAX') && DOING_AJAX),
115
+				'sslverify'   => false,
116
+				'redirection' => 10,
117
+			);
118
+			$response     = wp_remote_get($request_url, $request_args);
119
+			if (is_wp_error($response)) {
120
+				trigger_error($response->get_error_message());
121
+			}
122
+		} else {
123
+			EE_Messages_Scheduler::initiate_immediate_request_on_cron($task);
124
+		}
125
+	}
126
+
127
+
128
+	/**
129
+	 * This returns
130
+	 * the request params used for a scheduled message task request.
131
+	 *
132
+	 * @param string $task The task the request is for.
133
+	 * @return array
134
+	 */
135
+	public static function get_request_params($task)
136
+	{
137
+		// transient is used for flood control on msg_cron_trigger requests
138
+		$transient_key = 'ee_trans_' . uniqid($task);
139
+		set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
140
+		return array(
141
+			'type' => $task,
142
+			'key'  => $transient_key,
143
+		);
144
+	}
145
+
146
+
147
+	/**
148
+	 * This is used to execute an immediate call to the run_cron task performed by EED_Messages
149
+	 *
150
+	 * @param string $task The task the request is being generated for.
151
+	 */
152
+	public static function initiate_immediate_request_on_cron($task)
153
+	{
154
+		/** @var RequestInterface $request */
155
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
156
+		$request_args = EE_Messages_Scheduler::get_request_params($task);
157
+		// set those request args in the request so it gets picked up
158
+		foreach ($request_args as $request_key => $request_value) {
159
+			$request->setRequestParam($request_key, $request_value);
160
+		}
161
+		EED_Messages::instance()->run_cron();
162
+	}
163
+
164
+
165
+	/**
166
+	 * Callback for scheduled AHEE__EE_Messages_Scheduler__generation wp cron event
167
+	 */
168
+	public static function batch_generation()
169
+	{
170
+		/**
171
+		 * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
172
+		 */
173
+		if (
174
+			! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
175
+			|| ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
176
+		) {
177
+			EE_Messages_Scheduler::initiate_immediate_request_on_cron('generate');
178
+		}
179
+	}
180
+
181
+
182
+	/**
183
+	 * Callback for scheduled AHEE__EE_Messages_Scheduler__sending
184
+	 */
185
+	public static function batch_sending()
186
+	{
187
+		/**
188
+		 * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
189
+		 */
190
+		if (
191
+			! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
192
+			|| ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
193
+		) {
194
+			EE_Messages_Scheduler::initiate_immediate_request_on_cron('send');
195
+		}
196
+	}
197
+
198
+
199
+	/**
200
+	 * This is the callback for the `AHEE__EE_Messages_Scheduler__cleanup` scheduled event action.
201
+	 * This runs once a day and if cleanup is active (set via messages settings), it will (by default) delete
202
+	 * permanently from the database messages that have a MSG_modified date older than 30 days.
203
+	 *
204
+	 * @throws EE_Error
205
+	 * @throws EE_Error
206
+	 */
207
+	public static function cleanup()
208
+	{
209
+		// First, confirm that the generation and sending EE_Messages_Scheduler crons are
210
+		// set and reschedule them if they are not.
211
+		$message_crons_to_check = array(
212
+			'AHEE__EE_Messages_Scheduler__generation' => 'ee_message_cron',
213
+			'AHEE__EE_Messages_Scheduler__sending'    => 'ee_message_cron',
214
+		);
215
+		foreach ($message_crons_to_check as $hook_name => $frequency) {
216
+			if (! wp_next_scheduled($hook_name)) {
217
+				wp_schedule_event(time(), $frequency, $hook_name);
218
+			}
219
+		}
220
+
221
+		// check if user has cleanup turned on or if we're in maintenance mode.  If in maintenance mode we'll wait
222
+		// until the next scheduled event.
223
+		if (
224
+			! EE_Registry::instance()->CFG->messages->delete_threshold
225
+			|| ! EE_Maintenance_Mode::instance()->models_can_query()
226
+		) {
227
+			return;
228
+		}
229
+
230
+		/**
231
+		 * This filter switch allows other code (such as the EE_Worker_Queue add-on) to replace this with its own handling
232
+		 * of deleting messages.
233
+		 */
234
+		if (apply_filters('FHEE__EE_Messages_Scheduler__cleanup__handle_cleanup_on_cron', true)) {
235
+			EEM_Message::instance()->delete_old_messages(EE_Registry::instance()->CFG->messages->delete_threshold);
236
+		}
237
+	}
238 238
 }
Please login to merge, or discard this patch.