PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.10.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.10.0
2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 1.1.0 All 77 releases
← All changes | app/Services/SmartCodeParser.php +11 -71 trunk2.10.0 View file →
@@ -143,75 +143,39 @@
143 143
144 144 if ($transformer && is_string($transformer) && $value) {
145 145 switch ($transformer) {
146 146 case 'trim':
147 - $value = trim($value);
148 - break;
147 + return trim($value);
149 148 case 'ucfirst':
150 - $value = ucfirst($value);
151 - break;
149 + return ucfirst($value);
152 150 case 'strtolower':
153 - $value = strtolower($value);
154 - break;
151 + return strtolower($value);
155 152 case 'strtoupper':
156 - $value = strtoupper($value);
157 - break;
153 + return strtoupper($value);
158 154 case 'ucwords':
159 - $value = ucwords($value);
160 - break;
155 + return ucwords($value);
161 156 case 'concat_first': // usage: {{contact.first_name||concat_first|Hi
162 157 if (isset($valueKeys[3])) {
163 158 $value = trim($valueKeys[3] . ' ' . $value);
164 159 }
165 - break;
160 + return $value;
166 161 case 'concat_last': // usage: {{contact.first_name||concat_last|, => FIRST_NAME,
167 162 if (isset($valueKeys[3])) {
168 163 $value = trim($value . '' . $valueKeys[3]);
169 164 }
170 - break;
165 + return $value;
171 166 case 'show_if': // usage {{contact.first_name||show_if|First name exist
172 167 if (isset($valueKeys[3])) {
173 168 $value = $valueKeys[3];
174 169 }
175 - break;
170 + return $value;
171 + default:
172 + return $value;
176 173 }
177 174 }
178 175
179 - return $this->escapeValueForContext($value, $dataKey, $valueKey);
180 - }
176 + return $value;
181 177
182 - /**
183 - * Smartcode values are substituted into lockscreen/lesson/email HTML *after*
184 - * that content has passed through wp_kses / do_blocks, so a resolved scalar
185 - * carrying markup would otherwise bypass sanitisation. Escape ordinary
186 - * values for the HTML context. The few branches that intentionally build a
187 - * trusted fragment (photo_html, name_with_url, section url) already escape
188 - * their own interpolated parts, so they are left untouched, and values from
189 - * third-party group callbacks are the extension's responsibility.
190 - */
191 - protected function escapeValueForContext($value, $dataKey, $valueKey)
192 - {
193 - if (!static::$isHtml || !is_string($value) || $value === '') {
194 - return $value;
195 - }
196 -
197 - $knownGroups = ['site', 'user', 'community', 'section', 'course'];
198 - if (!in_array($dataKey, $knownGroups, true)) {
199 - return $value;
200 - }
201 -
202 - $trustedHtml = [
203 - 'user' => ['photo_html'],
204 - 'community' => ['name_with_url'],
205 - 'section' => ['url'],
206 - ];
207 -
208 - $baseKey = strtok($valueKey, '.'); // "photo_html.50px" -> "photo_html"
209 - if (in_array($baseKey, Arr::get($trustedHtml, $dataKey, []), true)) {
210 - return $value;
211 - }
212 -
213 - return esc_html($value);
214 178 }
215 179
216 180 protected function getWpValue($valueKey, $defaultValue)
217 181 {
@@ -262,22 +226,8 @@
262 226
263 227 $wpUser = $userModel->getWpUser();
264 228 $valueKeys = explode('.', $valueKey);
265 229 if (count($valueKeys) == 1) {
266 - // Smartcodes are resolved against the *viewer* and can be authored by
267 - // space/course/page admins, so only a fixed set of non-sensitive
268 - // profile fields may be read. Never expose user_pass,
269 - // user_activation_key, session tokens or capability meta.
270 - $allowedFields = apply_filters('fluent_community/smartcode/user_fields', [
271 - 'ID', 'first_name', 'last_name', 'nickname', 'display_name',
272 - 'user_email', 'user_login', 'user_nicename', 'user_url',
273 - 'description', 'user_registered'
274 - ]);
275 -
276 - if (!in_array($valueKey, $allowedFields, true)) {
277 - return $defaultValue;
278 - }
279 -
280 230 $value = $wpUser->get($valueKey);
281 231 if (!$value) {
282 232 return $defaultValue;
283 233 }
@@ -301,18 +251,8 @@
301 251 return '<img ' . $style . ' src="' . esc_url($userModel->photo) . '" alt="' . esc_attr($userModel->display_name) . '" class="fcom_user_dynamic_photo" />';
302 252 }
303 253
304 254 if ($customKey == 'meta') {
305 - // No first-party template reads user meta through smartcodes, and the
306 - // viewer's own meta (session_tokens, capability keys, reset keys,
307 - // any _-prefixed value) must never leak into author-controlled
308 - // content. Resolve only meta keys a site has explicitly allowed.
309 - $allowedMetaKeys = apply_filters('fluent_community/smartcode/user_meta_keys', []);
310 -
311 - if (strpos($customProperty, '_') === 0 || !in_array($customProperty, $allowedMetaKeys, true)) {
312 - return $defaultValue;
313 - }
314 -
315 255 $metaValue = get_user_meta($wpUser->ID, $customProperty, true);
316 256 if (!$metaValue) {
317 257 return $defaultValue;
318 258 }