| 1 |
<?php |
| 2 |
|
| 3 |
namespace wpforo\classes; |
| 4 |
|
| 5 |
// Exit if accessed directly |
| 6 |
if( ! defined( 'ABSPATH' ) ) exit; |
| 7 |
|
| 8 |
class Forms { |
| 9 |
public $default; |
| 10 |
public $field_dir; |
| 11 |
public $current; |
| 12 |
|
| 13 |
public function __construct() { |
| 14 |
$this->init_defaults(); |
| 15 |
} |
| 16 |
|
| 17 |
private function init_defaults() { |
| 18 |
$this->field_dir = '/wpforo/users/fields/'; |
| 19 |
$this->default = [ |
| 20 |
'label' => '', |
| 21 |
'title' => '', |
| 22 |
'name' => '', |
| 23 |
'value' => '', |
| 24 |
'values' => '', |
| 25 |
'type' => 'text', |
| 26 |
'placeholder' => '', |
| 27 |
'description' => '', |
| 28 |
'id' => '', |
| 29 |
'class' => '', |
| 30 |
'attributes' => '', |
| 31 |
'isDefault' => 0, |
| 32 |
'isWrapItem' => '', |
| 33 |
'isLabelFirst' => '', |
| 34 |
'isDisabled' => 0, |
| 35 |
'isEditable' => 1, |
| 36 |
'isRequired' => 0, |
| 37 |
'isMultiChoice' => 0, |
| 38 |
'isAllowedCustomValues' => 0, |
| 39 |
'UGroupIdsFrontAddNewDefaultValues' => [], |
| 40 |
'isOnlyForGuests' => 0, |
| 41 |
'isRemovable' => 1, |
| 42 |
'isSearchable' => 0, |
| 43 |
'allowedGroupIds' => [], |
| 44 |
'fileExtensions' => '', |
| 45 |
'fileSize' => 1, |
| 46 |
'minLength' => 0, |
| 47 |
'maxLength' => 0, |
| 48 |
'faIcon' => '', |
| 49 |
'html' => '', |
| 50 |
'varname' => '', |
| 51 |
'template' => '', |
| 52 |
'cantBeInactive' => [], |
| 53 |
'canEdit' => [ 1 ], |
| 54 |
'canView' => [ 1, 2, 3, 5 ], |
| 55 |
'can' => '', |
| 56 |
'isDisplayDefaultValues' => 0, |
| 57 |
]; |
| 58 |
} |
| 59 |
|
| 60 |
public function fix_field( $field ) { |
| 61 |
return wpforo_array_args_cast_and_merge( (array) $field, $this->default ); |
| 62 |
} |
| 63 |
|
| 64 |
/** |
| 65 |
* Form builder |
| 66 |
* for form layout and field building |
| 67 |
* |
| 68 |
* @param array $fields associative multi-level array |
| 69 |
* |
| 70 |
* @return string form HTML |
| 71 |
*/ |
| 72 |
public function build( $fields ) { |
| 73 |
if( empty( $fields ) ) return ''; |
| 74 |
$html = ''; |
| 75 |
foreach( $fields as $row_key => $row ) { |
| 76 |
$row_class = "row-$row_key " . apply_filters( 'wpforo_row_classes', '', $row_key ); |
| 77 |
$html .= '<div class="wpf-tr ' . esc_attr( $row_class ) . '">'; |
| 78 |
foreach( $row as $col_key => $col ) { |
| 79 |
$col_class_field = ''; |
| 80 |
foreach( $col as $field ) { |
| 81 |
$col_class_field .= ' wpf-row-' . wpfval( $field, 'name' ); |
| 82 |
} |
| 83 |
reset( $col ); |
| 84 |
$col_class = "row_$row_key-col_$col_key " . $col_class_field . ' ' . apply_filters( 'wpforo_col_classes', '', $row_key, $col_key ); |
| 85 |
$html .= '<div class="wpf-td wpfw-' . count( $row ) . ' ' . esc_attr( $col_class ) . '">'; |
| 86 |
foreach( $col as $field ) { |
| 87 |
if( ! empty( $field ) ) $html .= $this->build_field( $field ); |
| 88 |
} |
| 89 |
$html .= '</div>'; |
| 90 |
} |
| 91 |
$html .= '<div class="wpf-cl"></div></div>'; |
| 92 |
} |
| 93 |
|
| 94 |
return $html; |
| 95 |
} |
| 96 |
|
| 97 |
/** |
| 98 |
* Builds field with input HTML and wrapper divs |
| 99 |
* |
| 100 |
* @param array $args field arguments |
| 101 |
* |
| 102 |
* @return string field HTML |
| 103 |
*/ |
| 104 |
public function build_field( $args ) { |
| 105 |
if( is_string( $args ) ) $args = WPF()->member->get_field( $args ); |
| 106 |
|
| 107 |
$html = ''; |
| 108 |
if( ! is_array( $args ) || empty( $args ) ) return ''; |
| 109 |
$f = wpforo_parse_args( $args, $this->default ); |
| 110 |
$f = $this->prepare_args( $f ); |
| 111 |
|
| 112 |
//Get field input tag |
| 113 |
$field_html = $this->field( $f ); |
| 114 |
|
| 115 |
//Wrapping field input |
| 116 |
if( $f['template'] === 'register' ) { |
| 117 |
if( $this->can_add( $f ) ) { |
| 118 |
$html = $this->field_wrap_register( $field_html, $f ); |
| 119 |
} |
| 120 |
} elseif( $f['template'] === 'account' ) { |
| 121 |
if( $this->can_edit( $f ) ) { |
| 122 |
$html = $this->field_wrap_account( $field_html, $f ); |
| 123 |
} |
| 124 |
} elseif( $f['template'] === 'profile' ) { |
| 125 |
if( $this->can_view( $f ) && $this->can_show_value( $f ) ) { |
| 126 |
$f = $this->esc_field( $f ); |
| 127 |
$html = $this->field_wrap_profile( $field_html, $f ); |
| 128 |
} |
| 129 |
} elseif( $f['template'] === 'members' ) { |
| 130 |
if( $this->can_show_value( $f ) ) $html = $this->field_wrap_members( $field_html, $f ); |
| 131 |
} else { |
| 132 |
$html = $this->field_wrap_default( $field_html, $f ); |
| 133 |
} |
| 134 |
|
| 135 |
return $html; |
| 136 |
} |
| 137 |
|
| 138 |
/** |
| 139 |
* Field input HTML builder |
| 140 |
* |
| 141 |
* @param array $f field arguments |
| 142 |
* |
| 143 |
* @return string field input HTML |
| 144 |
*/ |
| 145 |
public function field( $f ) { |
| 146 |
$f = $this->prepare_field_args( $f ); |
| 147 |
|
| 148 |
$f = apply_filters( 'wpforo_form_field', $f ); |
| 149 |
|
| 150 |
switch( $f['type'] ) { |
| 151 |
case 'url': |
| 152 |
$field_html = $this->field_url( $f ); |
| 153 |
break; |
| 154 |
case 'file': |
| 155 |
$field_html = $this->field_file( $f ); |
| 156 |
break; |
| 157 |
case 'html': |
| 158 |
$field_html = $this->field_html( $f ); |
| 159 |
break; |
| 160 |
case 'radio': |
| 161 |
$field_html = $this->field_radio( $f ); |
| 162 |
break; |
| 163 |
case 'select': |
| 164 |
$field_html = $this->field_select( $f ); |
| 165 |
break; |
| 166 |
case 'avatar': |
| 167 |
$field_html = $this->field_avatar( $f ); |
| 168 |
break; |
| 169 |
case 'textarea': |
| 170 |
$field_html = $this->field_textarea( $f ); |
| 171 |
break; |
| 172 |
case 'tinymce': |
| 173 |
$field_html = $this->field_tinymce( $f ); |
| 174 |
break; |
| 175 |
case 'password': |
| 176 |
$field_html = $this->field_password( $f ); |
| 177 |
break; |
| 178 |
case 'checkbox': |
| 179 |
$field_html = $this->field_checkbox( $f ); |
| 180 |
break; |
| 181 |
case 'usergroup': |
| 182 |
$field_html = $this->field_usergroup( $f ); |
| 183 |
break; |
| 184 |
case 'secondary_groups': |
| 185 |
$field_html = $this->field_secondary_groups( $f ); |
| 186 |
break; |
| 187 |
case 'user_nicename': |
| 188 |
$field_html = $this->field_nicename( $f ); |
| 189 |
break; |
| 190 |
case 'tel': |
| 191 |
$field_html = $this->field_tel( $f ); |
| 192 |
break; |
| 193 |
case 'autocomplete': |
| 194 |
$field_html = $this->field_autocomplete( $f ); |
| 195 |
break; |
| 196 |
default: |
| 197 |
$field_html = $this->field_text( $f ); |
| 198 |
} |
| 199 |
|
| 200 |
return apply_filters( 'wpforo_form_field_html', $field_html, $f ); |
| 201 |
} |
| 202 |
|
| 203 |
/** |
| 204 |
* Wraps input HTML for Registration form |
| 205 |
* |
| 206 |
* @param string $field_html input HTML |
| 207 |
* @param array $f field arguments |
| 208 |
* |
| 209 |
* @return string wrapped field input HTML |
| 210 |
*/ |
| 211 |
public function field_wrap_register( $field_html, $f ) { |
| 212 |
$html = '<div class="wpf-field wpf-field-type-' . esc_attr( $f['type'] ) . ' wpf-field-name-' . esc_attr( $f['field_class'] ) . ' ' . esc_attr( $f['required_class'] ) . '" title="' . esc_attr( |
| 213 |
$f['title'] |
| 214 |
) . '">'; |
| 215 |
if( $f['type'] !== 'html' ) { |
| 216 |
if( $f['label'] || $f['description'] ) { |
| 217 |
$html .= '<div class="wpf-label-wrap">'; |
| 218 |
if( $f['label'] ) { |
| 219 |
$html .= '<p class="wpf-label wpfcl-1">' . $f['label'] . $f['required_indicator'] . '</p>'; |
| 220 |
} |
| 221 |
if( $f['description'] ) { |
| 222 |
$html .= '<div class="wpf-desc wpfcl-2">' . $f['description'] . '</div>'; |
| 223 |
} |
| 224 |
$html .= '</div>'; |
| 225 |
} |
| 226 |
$html .= '<div class="wpf-field-wrap">'; |
| 227 |
if( $f['faIcon'] ) { |
| 228 |
$html .= '<i class="' . esc_attr( $f['faIcon'] ) . ' wpf-field-icon"></i>'; |
| 229 |
} |
| 230 |
$html .= $field_html; |
| 231 |
$html .= '</div>'; |
| 232 |
} else { |
| 233 |
$html .= $field_html; |
| 234 |
} |
| 235 |
$html .= '<div class="wpf-field-cl"></div></div>'; |
| 236 |
|
| 237 |
return $html; |
| 238 |
} |
| 239 |
|
| 240 |
/** |
| 241 |
* Wraps input HTML for Account form |
| 242 |
* |
| 243 |
* @param string $field_html input HTML |
| 244 |
* @param array $f field arguments |
| 245 |
* |
| 246 |
* @return string wrapped field input HTML |
| 247 |
*/ |
| 248 |
public function field_wrap_account( $field_html, $f ) { |
| 249 |
$html = '<div class="wpf-field wpf-field-type-' . esc_attr( $f['type'] ) . ' wpf-field-name-' . esc_attr( $f['field_class'] ) . ' ' . esc_attr( $f['required_class'] ) . '" title="' . esc_attr( |
| 250 |
$f['title'] |
| 251 |
) . '">'; |
| 252 |
if( $f['type'] === 'html' ) { |
| 253 |
$html .= $field_html; |
| 254 |
} elseif( $f['name'] === 'user_login' ) { |
| 255 |
$html .= '<div class="wpf-label-wrap">'; |
| 256 |
$html .= '<p class="wpf-label wpfcl-1">' . stripslashes( (string) $f['label'] ) . '</p>'; |
| 257 |
$html .= '</div>'; |
| 258 |
$html .= '<div class="wpf-field-wrap">'; |
| 259 |
$html .= '<span class="wpf-username">' . $f['value'] . '</span>'; |
| 260 |
$html .= '</div>'; |
| 261 |
} elseif( $f['type'] !== 'password' && ! $f['isEditable'] && ! $this->can_moderate( $f ) && WPF()->current_user_groupid !== 1 ) { |
| 262 |
$f = $this->esc_field( $f ); |
| 263 |
$html .= '<div class="wpf-label-wrap">'; |
| 264 |
$html .= '<p class="wpf-label wpfcl-1">' . stripslashes( (string) $f['label'] ) . '</p>'; |
| 265 |
$html .= '</div>'; |
| 266 |
$html .= '<div class="wpf-field-wrap">'; |
| 267 |
$html .= '<span class="wpf-filed-value"><i class="' . esc_attr( $f['faIcon'] ) . '"></i> ' . $f['value'] . '</span>'; |
| 268 |
$html .= '</div>'; |
| 269 |
} else { |
| 270 |
if( $f['label'] || $f['description'] ) { |
| 271 |
$html .= '<div class="wpf-label-wrap">'; |
| 272 |
if( $f['label'] ) { |
| 273 |
$html .= '<p class="wpf-label wpfcl-1">' . stripslashes( (string) $f['label'] ) . $f['required_indicator'] . '</p>'; |
| 274 |
} |
| 275 |
if( $f['description'] ) { |
| 276 |
$html .= '<div class="wpf-desc wpfcl-2">' . $f['description'] . '</div>'; |
| 277 |
} |
| 278 |
$html .= '</div>'; |
| 279 |
} |
| 280 |
$html .= '<div class="wpf-field-wrap">'; |
| 281 |
if( $f['faIcon'] ) { |
| 282 |
$html .= '<i class="' . esc_attr( $f['faIcon'] ) . ' wpf-field-icon"></i>'; |
| 283 |
} |
| 284 |
$html .= $field_html; |
| 285 |
$html .= '</div>'; |
| 286 |
} |
| 287 |
$html .= '<div class="wpf-field-cl"></div></div>'; |
| 288 |
|
| 289 |
return $html; |
| 290 |
} |
| 291 |
|
| 292 |
/** |
| 293 |
* Wraps input HTML for Profile page |
| 294 |
* |
| 295 |
* @param string $field_html input HTML |
| 296 |
* @param array $f field arguments |
| 297 |
* |
| 298 |
* @return string wrapped field input HTML |
| 299 |
*/ |
| 300 |
public function field_wrap_profile( $field_html, $f ) { |
| 301 |
|
| 302 |
if( ! in_array( $f['type'], [ 'html', 'avatar' ] ) && ! ( $f['isRequired'] && $f['isDisplayDefaultValues'] ) && ( ! isset( $f['value'] ) || ( ! is_numeric( |
| 303 |
$f['value'] |
| 304 |
) && empty( $f['value'] ) ) ) ) { |
| 305 |
return false; |
| 306 |
} |
| 307 |
|
| 308 |
$html = '<div class="wpf-field wpf-field-type-' . esc_attr( $f['type'] ) . ' wpf-field-name-' . esc_attr( $f['field_class'] ) . ' ' . esc_attr( $f['required_class'] ) . '" title="' . esc_attr( |
| 309 |
$f['title'] |
| 310 |
) . '">'; |
| 311 |
if( $f['type'] !== 'html' ) { |
| 312 |
if( ! $f['faIcon'] ) { |
| 313 |
$f['faIcon'] = 'fas fa-address-card'; |
| 314 |
} |
| 315 |
if( $f['label'] ) { |
| 316 |
$html .= '<div class="wpf-label-wrap"><p class="wpf-label wpfcl-1"><i class="' . esc_attr( $f['faIcon'] ) . ' wpf-field-icon"></i> ' . $f['label'] . '</p></div>'; |
| 317 |
} |
| 318 |
if( $f['type'] === 'avatar' || ( isset( $f['value'] ) && ! empty( $f['value'] ) ) ) { |
| 319 |
if( is_array( $f['value'] ) ) { |
| 320 |
$html .= esc_html( implode( ', ', $f['value'] ) ); |
| 321 |
} else { |
| 322 |
$f = $this->prepare_values( $f, WPF()->current_object['userid'] ); |
| 323 |
$html .= '<div class="wpf-field-wrap">'; |
| 324 |
$html .= $f['value']; |
| 325 |
$html .= '</div>'; |
| 326 |
} |
| 327 |
} else { |
| 328 |
if( $default_values = wpforo_preg_grep_recursive( '#^\[.+?]$#isu', $f['values'] ) ) { |
| 329 |
$_html = ''; |
| 330 |
foreach( $default_values as $default_key => $default_value ) { |
| 331 |
if( ! is_array( $default_value ) ) { |
| 332 |
$item = $this->build_item_value_lable( $default_value ); |
| 333 |
$_html .= $item['label'] . ', '; |
| 334 |
} else { |
| 335 |
$csv = ''; |
| 336 |
foreach( $default_value as $_default_value ) { |
| 337 |
if( ! is_array( $_default_value ) ) { |
| 338 |
$item = $this->build_item_value_lable( $_default_value ); |
| 339 |
$csv .= $item['label'] . ', '; |
| 340 |
} |
| 341 |
} |
| 342 |
$_html .= trim( (string) $default_key ) . '( ' . trim( (string) $csv, ', ' ) . ' ), '; |
| 343 |
} |
| 344 |
} |
| 345 |
$html .= sprintf( '<div class="wpf-field-wrap">%1$s</div>', trim( (string) $_html, ', ' ) ); |
| 346 |
} else { |
| 347 |
return false; |
| 348 |
} |
| 349 |
} |
| 350 |
} else { |
| 351 |
$html .= $field_html; |
| 352 |
} |
| 353 |
$html .= '<div class="wpf-field-cl"></div></div>'; |
| 354 |
|
| 355 |
return $html; |
| 356 |
} |
| 357 |
|
| 358 |
/** |
| 359 |
* Wraps input HTML for Members Search form |
| 360 |
* |
| 361 |
* @param string $field_html input HTML |
| 362 |
* @param array $f field arguments |
| 363 |
* |
| 364 |
* @return string wrapped field input HTML |
| 365 |
*/ |
| 366 |
public function field_wrap_members( $field_html, $f ) { |
| 367 |
$html = '<div class="wpf-field wpf-field-type-' . esc_attr( $f['type'] ) . ' wpf-field-name-' . esc_attr( $f['field_class'] ) . ' ' . esc_attr( $f['required_class'] ) . '" title="' . esc_attr( |
| 368 |
$f['title'] |
| 369 |
) . '">'; |
| 370 |
if( $f['type'] === 'html' ) { |
| 371 |
$html .= $field_html; |
| 372 |
} else { |
| 373 |
if( $f['label'] || $f['description'] ) { |
| 374 |
$html .= '<div class="wpf-label-wrap">'; |
| 375 |
if( $f['label'] ) { |
| 376 |
$html .= '<p class="wpf-label wpfcl-1">' . stripslashes( (string) $f['label'] ) . $f['required_indicator'] . '</p>'; |
| 377 |
} |
| 378 |
if( $f['description'] ) { |
| 379 |
$html .= '<div class="wpf-desc wpfcl-2">' . $f['description'] . '</div>'; |
| 380 |
} |
| 381 |
$html .= '</div>'; |
| 382 |
} |
| 383 |
$html .= '<div class="wpf-field-wrap">'; |
| 384 |
if( $f['faIcon'] ) { |
| 385 |
$html .= '<i class="' . esc_attr( $f['faIcon'] ) . ' wpf-field-icon"></i>'; |
| 386 |
} |
| 387 |
$html .= $field_html; |
| 388 |
$html .= '</div>'; |
| 389 |
} |
| 390 |
$html .= '<div class="wpf-field-cl"></div></div>'; |
| 391 |
|
| 392 |
return $html; |
| 393 |
} |
| 394 |
|
| 395 |
/** |
| 396 |
* Default wrapper of input HTML |
| 397 |
* |
| 398 |
* @param string $field_html input HTML |
| 399 |
* @param array $f field arguments |
| 400 |
* |
| 401 |
* @return string wrapped field input HTML |
| 402 |
*/ |
| 403 |
public function field_wrap_default( $field_html, $f ) { |
| 404 |
$html = '<div class="wpf-field wpf-field-type-' . esc_attr( $f['type'] ) . ' wpf-field-name-' . esc_attr( $f['field_class'] ) . ' ' . esc_attr( $f['required_class'] ) . '">'; |
| 405 |
if( $f['type'] === 'html' ) { |
| 406 |
$html .= $field_html; |
| 407 |
} else { |
| 408 |
if( $f['label'] || $f['description'] ) { |
| 409 |
$html .= '<div class="wpf-label-wrap" style="float: none; width: 100%;">'; |
| 410 |
if( $f['faIcon'] ) $html .= '<i class="' . esc_attr( $f['faIcon'] ) . '"></i>'; |
| 411 |
if( $f['label'] ) { |
| 412 |
$html .= '<p class="wpf-label wpfcl-1" style="display: inline-block; margin-left: 5px;">' . stripslashes( (string) $f['label'] ) . $f['required_indicator'] . '</p>'; |
| 413 |
} |
| 414 |
|
| 415 |
if( wpfval( $f, 'type' ) === 'file' && ( $file_size = wpfval( $f, 'fileSize' ) ) ) { |
| 416 |
$html .= '<em style="opacity: 0.8;"> (' . wpforo_phrase( 'max allowed file size', false, 'lower' ) . ' ' . $file_size . 'MB)</em>'; |
| 417 |
} |
| 418 |
|
| 419 |
if( $f['description'] ) { |
| 420 |
$html .= '<div class="wpf-desc wpfcl-2" style="display: inline-block; margin-left: 5px;">' . $f['description'] . '</div>'; |
| 421 |
} |
| 422 |
$html .= '</div>'; |
| 423 |
} else { |
| 424 |
if( $f['faIcon'] ) $html .= '<i class="' . esc_attr( $f['faIcon'] ) . '"></i>'; |
| 425 |
} |
| 426 |
$html .= '<div class="wpf-field-wrap" style="width: 100%">'; |
| 427 |
$html .= $field_html; |
| 428 |
$html .= '</div>'; |
| 429 |
} |
| 430 |
$html .= '<div class="wpf-field-cl"></div></div>'; |
| 431 |
|
| 432 |
return $html; |
| 433 |
} |
| 434 |
|
| 435 |
/** |
| 436 |
* File - Field builder |
| 437 |
* |
| 438 |
* @param array $f field arguments |
| 439 |
* |
| 440 |
* @return string field HTML |
| 441 |
*/ |
| 442 |
public function field_file( $f ) { |
| 443 |
$field_html = ''; |
| 444 |
$extensions = ''; |
| 445 |
if( $f['fileExtensions'] ) { |
| 446 |
foreach( $f['fileExtensions'] as $key => $ext ) { |
| 447 |
if( strpos( (string) $ext, '.' ) === false ) { |
| 448 |
$f['fileExtensions'][ $key ] = '.' . $ext; |
| 449 |
} |
| 450 |
} |
| 451 |
$f['fileExtensions'] = implode( ', ', $f['fileExtensions'] ); |
| 452 |
if( $f['fileExtensions'] ) $extensions = ' accept="' . esc_attr( $f['fileExtensions'] ) . '" '; |
| 453 |
} |
| 454 |
if( $f['value'] ) { |
| 455 |
$f['isRequired'] = ''; |
| 456 |
if( is_array( $f['value'] ) ) { |
| 457 |
$file_name = (string) wpfval( $f['value'], 'filename' ); |
| 458 |
$f['value'] = (string) wpfval( $f['value'], 'fileurl' ); |
| 459 |
} else { |
| 460 |
$file_name = basename( (string) $f['value'] ); |
| 461 |
} |
| 462 |
$extension = pathinfo( $f['value'], PATHINFO_EXTENSION ); |
| 463 |
$f['value'] = wpforo_fix_upload_url( $f['value'] ); |
| 464 |
|
| 465 |
if( wpfval( WPF()->current_object['user'], 'userid' ) ) { |
| 466 |
$delete = '?wpfaction=ucf_file_delete&foro_f=' . $f['name'] . '&foro_u=' . WPF()->current_object['user']['userid']; |
| 467 |
$delete_url = wp_nonce_url( $delete, 'wpforo_delete_profile_field', 'foro_n' ); |
| 468 |
$delete_html = ' | <a href="' . $delete_url . '" title="' . wpforo_phrase( 'Delete this file', false ) . '" onclick="return confirm(\'' . wpforo_phrase( |
| 469 |
'Are you sure you want to delete this file?', |
| 470 |
false |
| 471 |
) . '\')"><i class="fas fa-times" style="color:#e86666; font-size:14px; line-height:14px;"></i></a>'; |
| 472 |
} else { |
| 473 |
$delete_html = ' | <span data-fieldkey="' . $f['fieldKey'] . '" style="cursor: pointer;" class="wpforo-delete-custom-file" title="' . wpforo_phrase( |
| 474 |
'Delete this file', |
| 475 |
false |
| 476 |
) . '"><i class="fas fa-times" style="color:#e86666; font-size:14px; line-height:14px;"></i></span>'; |
| 477 |
} |
| 478 |
|
| 479 |
if( $extension && wpforo_is_image( $extension ) ) { |
| 480 |
$field_html .= '<div class="wpf-field-file-wrap" style="margin-bottom: 10px;"> |
| 481 |
<img src="' . esc_url_raw( $f['value'] ) . '" alt="' . esc_attr( $file_name ) . '" title="' . esc_attr( $file_name ) . '" style="max-width:100px; max-height:100px"/> |
| 482 |
<div class="wpf-field-file-name"> |
| 483 |
<i class="fas fa-paperclip"></i> |
| 484 |
<a href="' . esc_url_raw( $f['value'] ) . '" title="' . esc_attr( $file_name ) . '" target="_blank">' . esc_attr( $file_name ) . '</a>' . $delete_html . ' |
| 485 |
</div> |
| 486 |
</div>'; |
| 487 |
} else { |
| 488 |
$field_html .= '<div class="wpf-field-file-wrap" style="margin-bottom: 10px;"> |
| 489 |
<div class="wpf-field-file-name"> |
| 490 |
<i class="fas fa-paperclip"></i> |
| 491 |
<a href="' . esc_url_raw( $f['value'] ) . '" title="' . esc_attr( $file_name ) . '" target="_blank">' . esc_attr( $file_name ) . '</a>' . $delete_html . ' |
| 492 |
</div> |
| 493 |
</div>'; |
| 494 |
} |
| 495 |
} |
| 496 |
$field_html .= '<input type="file" name="' . esc_attr( $f['fieldName'] ) . '" value="" |
| 497 |
id="' . esc_attr( $f['fieldId'] ) . '" class="' . esc_attr( $f['fieldId'] ) . '" |
| 498 |
' . $f['isRequired'] . ' ' . $f['isDisabled'] . ' ' . $f['attributes'] . ' ' . $extensions . ' />'; |
| 499 |
|
| 500 |
return $field_html; |
| 501 |
} |
| 502 |
|
| 503 |
private function form_extra( $f ) { |
| 504 |
$form_type = wpfval( $f, 'form_type' ); |
| 505 |
switch( $form_type ) { |
| 506 |
case 'topic': |
| 507 |
if( $forum = wpfval( $f, 'meta', 'forum' ) ) { |
| 508 |
wpforo_topic_form_extra( (int) wpfval( $forum, 'forumid' ), (array) wpfval( $f, 'meta', 'values' ) ); |
| 509 |
} |
| 510 |
break; |
| 511 |
case 'post': |
| 512 |
if( $topic = wpfval( $f, 'meta', 'topic' ) ) { |
| 513 |
wpforo_reply_form_extra( $topic, (array) wpfval( $f, 'meta', 'values' ) ); |
| 514 |
} |
| 515 |
break; |
| 516 |
} |
| 517 |
} |
| 518 |
|
| 519 |
/** |
| 520 |
* Textarea - Field builder |
| 521 |
* |
| 522 |
* @param array $f field arguments |
| 523 |
* |
| 524 |
* @return string field HTML |
| 525 |
*/ |
| 526 |
public function field_textarea( $f ) { |
| 527 |
$field_html = '<textarea name="' . esc_attr( $f['fieldName'] ) . '" |
| 528 |
id="' . esc_attr( $f['fieldId'] ) . '" |
| 529 |
class="' . esc_attr( $f['fieldId'] ) . '" |
| 530 |
placeholder="' . esc_attr( $f['placeholder'] ) . '" |
| 531 |
' . $f['isRequired'] . ' ' . $f['isDisabled'] . ' ' . $f['attributes'] . ' |
| 532 |
' . $f['minmax'] . ' data-isbody="' . intval( $f['fieldKey'] === 'body' ) . '">' . esc_textarea( (string) $f['value'] ) . '</textarea>'; |
| 533 |
if( $f['fieldKey'] === 'body' ) { |
| 534 |
ob_start(); |
| 535 |
$this->form_extra( $f ); |
| 536 |
$field_html .= ob_get_clean(); |
| 537 |
} |
| 538 |
|
| 539 |
return $field_html; |
| 540 |
} |
| 541 |
|
| 542 |
/** |
| 543 |
* Textarea - Field builder |
| 544 |
* |
| 545 |
* @param array $f field arguments |
| 546 |
* |
| 547 |
* @return string field HTML |
| 548 |
*/ |
| 549 |
public function field_tinymce( $f ) { |
| 550 |
WPF()->current_object['load_tinymce'] = true; |
| 551 |
$f['isRequired'] = ''; |
| 552 |
$f['attributes'] .= ' data-wpforoeditor="tinymce" '; |
| 553 |
if( empty( $f['wp_editor_settings'] ) ) $f['wp_editor_settings'] = WPF()->tpl->editor_buttons(); |
| 554 |
$f['wp_editor_settings'] = apply_filters( 'wpforo_form_field_tinymce_editor_settings', $f['wp_editor_settings'], $f ); |
| 555 |
wp_localize_script( 'wpforo-frontend-js', 'wpforo_editor_settings_' . esc_attr( $f['fieldId'] ), $f['wp_editor_settings'] ); |
| 556 |
|
| 557 |
return $this->field_textarea( $f ); |
| 558 |
} |
| 559 |
|
| 560 |
/** |
| 561 |
* Password - Field builder |
| 562 |
* |
| 563 |
* @param array $f field arguments |
| 564 |
* |
| 565 |
* @return string field HTML |
| 566 |
*/ |
| 567 |
public function field_password( $f ) { |
| 568 |
$field_html = ''; |
| 569 |
if( $f['template'] === 'account' ) { |
| 570 |
$f['isRequired'] = 0; |
| 571 |
$f['label'] = wpforo_phrase( 'Old password', false ); |
| 572 |
$f['description'] = ''; |
| 573 |
$field_html .= '<input type="password" |
| 574 |
name="' . esc_attr( $f['varname'] ) . '[old_pass]" |
| 575 |
value="" id="' . esc_attr( $f['fieldId'] ) . '-old" |
| 576 |
class="' . esc_attr( $f['fieldId'] ) . '" |
| 577 |
placeholder="' . esc_attr( wpforo_phrase( 'Old password', false ) ) . '" |
| 578 |
' . $f['isDisabled'] . ' ' . $f['attributes'] . '/> |
| 579 |
<i class="fas fa-eye-slash wpf-show-password"></i>'; |
| 580 |
} |
| 581 |
$p1 = '1'; |
| 582 |
$p2 = '2'; |
| 583 |
if( ! empty( $f['varname'] ) ) { |
| 584 |
$f['fieldName'] = $f['varname'] . '[' . $f['name'] . $p1 . ']'; |
| 585 |
} else { |
| 586 |
$f['fieldName'] = $f['name'] . $p1; |
| 587 |
} |
| 588 |
if( $f['template'] === 'account' ) { |
| 589 |
$f['label'] = wpforo_phrase( 'New', false ) . ' ' . wpforo_phrase( $f['label'], false, 'lower' ); |
| 590 |
$f['placeholder'] = wpforo_phrase( 'New', false ) . ' ' . wpforo_phrase( $f['placeholder'], false, 'lower' ); |
| 591 |
} |
| 592 |
if( in_array( $f['template'], [ 'account', 'register' ], true ) ) { |
| 593 |
if( $f['template'] === 'account' ) $field_html .= '<div style="position:relative"><i class="' . esc_attr( $f['faIcon'] ) . ' wpf-field-icon"></i>'; |
| 594 |
$field_html .= '<input type="password" |
| 595 |
name="' . esc_attr( $f['fieldName'] ) . '" |
| 596 |
value="" id="' . esc_attr( $f['fieldId'] ) . '-new1" |
| 597 |
class="' . esc_attr( $f['fieldId'] ) . '" |
| 598 |
placeholder="' . esc_attr( $f['placeholder'] ) . '" |
| 599 |
' . $f['isDisabled'] . ' ' . $f['attributes'] . ' ' . $f['minmax'] . '/>'; |
| 600 |
if( $f['template'] === 'register' ) { |
| 601 |
$field_html .= '<i class="fas fa-eye-slash wpf-show-password"></i>'; |
| 602 |
} |
| 603 |
if( $f['template'] === 'account' ) { |
| 604 |
$field_html .= '</div>'; |
| 605 |
} |
| 606 |
$f['label'] = wpforo_phrase( 'Confirm Password', false ); |
| 607 |
$f['placeholder'] = wpforo_phrase( 'Confirm Password', false ); |
| 608 |
$f['description'] = ''; |
| 609 |
$f['fieldName'] = ( ! empty( $f['varname'] ) ? $f['varname'] . '[' . $f['name'] . $p2 . ']' : $f['name'] . $p2 ); |
| 610 |
$field_html .= '<div style="position:relative"><i class="' . esc_attr( $f['faIcon'] ) . ' wpf-field-icon"></i>'; |
| 611 |
$field_html .= '<input type="password" |
| 612 |
name="' . esc_attr( $f['fieldName'] ) . '" |
| 613 |
value="" id="' . esc_attr( $f['fieldId'] ) . '-new2" |
| 614 |
class="' . esc_attr( $f['fieldId'] ) . '" |
| 615 |
placeholder="' . esc_attr( $f['placeholder'] ) . '" |
| 616 |
' . $f['isDisabled'] . ' ' . $f['attributes'] . ' ' . $f['minmax'] . '/>'; |
| 617 |
$field_html .= '</div>'; |
| 618 |
} |
| 619 |
|
| 620 |
return $field_html; |
| 621 |
} |
| 622 |
|
| 623 |
/** |
| 624 |
* Checkbox - Field builder |
| 625 |
* |
| 626 |
* @param array $f field arguments |
| 627 |
* |
| 628 |
* @return string field HTML |
| 629 |
*/ |
| 630 |
public function field_checkbox( $f ) { |
| 631 |
$i = 0; |
| 632 |
$field_html = ''; |
| 633 |
$f['value'] = $this->build_array_value( $f['value'], "\n" ); |
| 634 |
$f['values'] = $this->build_array_using_string_rows( $f['values'] ); |
| 635 |
if( ! empty( $f['values'] ) ) { |
| 636 |
$item_field_name = $f['fieldName'] . '[]'; |
| 637 |
$use_default_selected = ( trim( (string) $f['isRequired'] ) && ! $f['value'] ); |
| 638 |
$f['isRequired'] = ( count( $f['values'] ) == 1 ) ? $f['isRequired'] : ''; |
| 639 |
$field_html .= '<input type="hidden" name="' . esc_attr( $f['fieldName'] ) . '" value="">'; |
| 640 |
foreach( $f['values'] as $row ) { |
| 641 |
$item = $this->build_item_value_lable( $row ); |
| 642 |
$id = $f['fieldId'] . '_' . ++ $i; |
| 643 |
$field_html .= '<div class="wpf-field-item">'; |
| 644 |
$item_html = '<input type="checkbox" ' . ( $use_default_selected ? ( $item['default_selected'] ? ' checked ' : '' ) : $this->check( $item['value'], $f['value'] ) ) . ' |
| 645 |
name="' . esc_attr( $item_field_name ) . '" |
| 646 |
value="' . esc_attr( $item['value'] ) . '" |
| 647 |
id="' . esc_attr( $id ) . '" |
| 648 |
class="wpf-input-checkbox ' . esc_attr( $f['class'] ) . '" |
| 649 |
' . $f['isDisabled'] . ' ' . $f['isRequired'] . ' ' . $f['attributes'] . '>'; |
| 650 |
$field_html .= $this->build_label( $item['label'], $item_html, $f, $id ); |
| 651 |
$field_html .= '</div>'; |
| 652 |
} |
| 653 |
} |
| 654 |
|
| 655 |
return $field_html; |
| 656 |
} |
| 657 |
|
| 658 |
/** |
| 659 |
* Radio - Field builder |
| 660 |
* |
| 661 |
* @param array $f field arguments |
| 662 |
* |
| 663 |
* @return string field HTML |
| 664 |
*/ |
| 665 |
public function field_radio( $f ) { |
| 666 |
$i = 0; |
| 667 |
$field_html = ''; |
| 668 |
$f['value'] = $this->build_array_value( $f['value'], "\n" ); |
| 669 |
$f['values'] = $this->build_array_using_string_rows( $f['values'] ); |
| 670 |
$use_default_selected = ( trim( (string) $f['isRequired'] ) && ! $f['value'] ); |
| 671 |
if( ! empty( $f['values'] ) ) { |
| 672 |
foreach( $f['values'] as $row ) { |
| 673 |
$item = $this->build_item_value_lable( $row ); |
| 674 |
$id = $f['fieldId'] . '_' . ++ $i; |
| 675 |
$field_html .= '<div class="wpf-field-item">'; |
| 676 |
$item_html = '<input type="radio" ' . ( $use_default_selected ? ( $item['default_selected'] ? ' checked ' : '' ) : $this->check( $item['value'], $f['value'] ) ) . ' |
| 677 |
name="' . esc_attr( $f['fieldName'] ) . '" |
| 678 |
value="' . esc_attr( $item['value'] ) . '" |
| 679 |
id="' . esc_attr( $id ) . '" |
| 680 |
class="wpf-input-radio ' . esc_attr( $f['class'] ) . '" |
| 681 |
' . $f['isDisabled'] . ' ' . $f['isRequired'] . ' ' . $f['attributes'] . ' />'; |
| 682 |
$field_html .= $this->build_label( $item['label'], $item_html, $f, $id ); |
| 683 |
$field_html .= '</div>'; |
| 684 |
} |
| 685 |
} |
| 686 |
|
| 687 |
return $field_html; |
| 688 |
} |
| 689 |
|
| 690 |
/** |
| 691 |
* Radio - Field builder |
| 692 |
* |
| 693 |
* @param array $f field arguments |
| 694 |
* |
| 695 |
* @return string field HTML |
| 696 |
*/ |
| 697 |
public function field_select( $f ) { |
| 698 |
$field_html = ''; |
| 699 |
$f['value'] = $this->build_array_value( $f['value'], "\n" ); |
| 700 |
$f['values'] = $this->build_array_using_string_rows( $f['values'] ); |
| 701 |
$use_default_selected = ( trim( (string) $f['isRequired'] ) && ! $f['value'] ); |
| 702 |
if( ! empty( $f['values'] ) ) { |
| 703 |
$field_html .= '<select name="' . esc_attr( $f['fieldName'] ) . '" |
| 704 |
id="' . esc_attr( $f['fieldId'] ) . '" |
| 705 |
class="' . esc_attr( $f['class'] ) . '" |
| 706 |
' . $f['isMultiChoice'] . ' ' . $f['isDisabled'] . ' |
| 707 |
' . $f['isRequired'] . ' ' . $f['attributes'] . '>'; |
| 708 |
if( ! $f['isRequired'] ) { |
| 709 |
$field_html .= apply_filters( 'wpforo_form_field_select_first_option', '<option value="">' . wpforo_phrase( '--- Choose ---', false ) . '</option>', $f ); |
| 710 |
} |
| 711 |
foreach( $f['values'] as $optgroup => $row ) { |
| 712 |
if( is_array( $row ) && ! empty( $row ) ) { |
| 713 |
$field_html .= '<optgroup label="' . esc_attr( $optgroup ) . '">'; |
| 714 |
foreach( $row as $sub_row ) { |
| 715 |
$item = $this->build_item_value_lable( $sub_row ); |
| 716 |
$item['value'] = ( $f['name'] === 'timezone' ) ? str_replace( ' ', '_', $item['value'] ) : $item['value']; |
| 717 |
$field_html .= '<option value="' . esc_attr( $item['value'] ) . '" ' . ( $use_default_selected ? ( $item['default_selected'] ? ' selected ' : '' ) : $this->select( |
| 718 |
$item['value'], |
| 719 |
$f['value'] |
| 720 |
) ) . '>' . esc_html( $item['label'] ) . '</option>'; |
| 721 |
} |
| 722 |
$field_html .= '</optgroup>'; |
| 723 |
} else { |
| 724 |
$item = $this->build_item_value_lable( $row ); |
| 725 |
$item['value'] = ( $f['name'] === 'timezone' ) ? str_replace( ' ', '_', $item['value'] ) : $item['value']; |
| 726 |
$field_html .= '<option value="' . esc_attr( $item['value'] ) . '" ' . ( $use_default_selected ? ( $item['default_selected'] ? ' selected ' : '' ) : $this->select( |
| 727 |
$item['value'], |
| 728 |
$f['value'] |
| 729 |
) ) . '>' . esc_html( $item['label'] ) . '</option>'; |
| 730 |
} |
| 731 |
} |
| 732 |
$field_html .= '</select>'; |
| 733 |
} |
| 734 |
|
| 735 |
return $field_html; |
| 736 |
} |
| 737 |
|
| 738 |
public function generate_multi_item( $val, $dvalues = [], $save_button = false ) { |
| 739 |
return sprintf( |
| 740 |
'<div class="wpf-multi-item wpf-multi-item-known-%1$d"><span class="wpf-multi-item-value">%2$s</span>%3$s<span class="wpf-multi-item-action wpf-del" title="%4$s"><i class="fa-solid fa-xmark" title="%4$s"></i></span></div>', |
| 741 |
(int) in_array( $val, $dvalues, true ), |
| 742 |
$val, |
| 743 |
( $save_button ? sprintf( |
| 744 |
'<span class="wpf-multi-item-action wpf-save-variant" title="%1$s"><i class="fa-regular fa-floppy-disk" title="%1$s"></i></span>', |
| 745 |
wpforo_phrase( 'Add to pre-defined values', false ) |
| 746 |
) : '' ), |
| 747 |
wpforo_phrase( 'remove', false ) |
| 748 |
); |
| 749 |
} |
| 750 |
|
| 751 |
/** |
| 752 |
* Radio - Field builder |
| 753 |
* |
| 754 |
* @param array $f field arguments |
| 755 |
* |
| 756 |
* @return string field HTML |
| 757 |
*/ |
| 758 |
public function field_autocomplete( $f ) { |
| 759 |
$f['value'] = $this->build_array_value( $f['value'], "\n" ); |
| 760 |
$f['values'] = $this->build_array_using_string_rows( $f['values'] ); |
| 761 |
$save_button = (int) wpfval( $f, 'formid' ) > 0 && array_intersect( WPF()->current_user_groupids, (array) wpfval( $f, 'UGroupIdsFrontAddNewDefaultValues' ) ); |
| 762 |
|
| 763 |
return sprintf( |
| 764 |
'<%1$s data-dbvariants="%16$s" data-formid="%2$d" data-fieldkey="%3$s">%4$s<input type="text" name="%5$s" list="%6$s" class="%7$s" value="%8$s" autocomplete="off" %9$s %10$s %11$s %12$s><span class="wpf-invalid-msg wpf-required">%13$s</span><span class="wpf-invalid-msg wpf-not-allowed-value">%14$s</span>%15$s</%1$s>', |
| 765 |
( $f['isMultiChoice'] ? 'wpf-multi-input' : 'wpf-autocomplete-input' ), |
| 766 |
(int) wpfval( $f, 'formid' ), |
| 767 |
$f['fieldKey'], |
| 768 |
( $f['isMultiChoice'] ? sprintf( '<template id="wpf-multi-item-template">%1$s</template>', $this->generate_multi_item( '', [], $save_button ) ) . implode( |
| 769 |
'', |
| 770 |
array_map( function( $val ) use ( $f, $save_button ) { return $this->generate_multi_item( $val, $f['values'], $save_button ); }, array_filter( $f['value'] ) ) |
| 771 |
) : '' ), |
| 772 |
esc_attr( $f['fieldName'] ), |
| 773 |
esc_attr( $f['fieldId'] ), |
| 774 |
esc_attr( $f['class'] ), |
| 775 |
( ! $f['isMultiChoice'] ? current( $f['value'] ) : '' ), |
| 776 |
$f['isDisabled'], |
| 777 |
$f['isRequired'], |
| 778 |
$f['attributes'], |
| 779 |
( (int) $f['isAllowedCustomValues'] || $save_button ? 'allow-custom-values' : '' ), |
| 780 |
wpforo_phrase( 'This Field is Required', false ), |
| 781 |
wpforo_phrase( 'Wrong Value (This Field Allows Only Predefined Values)', false ), |
| 782 |
( ( $values = (array) wpfval( $f, 'values' ) ) ? sprintf( |
| 783 |
'<datalist id="%1$s">%2$s</datalist>', |
| 784 |
esc_attr( $f['fieldId'] ), |
| 785 |
implode( |
| 786 |
'', |
| 787 |
array_map( |
| 788 |
function( $value ) { |
| 789 |
return sprintf( '<option value="%1$s"></option>', esc_attr( $value ) ); |
| 790 |
}, |
| 791 |
array_diff( $values, $f['value'] ) |
| 792 |
) |
| 793 |
) |
| 794 |
) : '' ), |
| 795 |
esc_attr( json_encode( $f['values'] ) ) |
| 796 |
); |
| 797 |
} |
| 798 |
|
| 799 |
/** |
| 800 |
* Usergroup - Field builder |
| 801 |
* |
| 802 |
* @param array $f field arguments |
| 803 |
* |
| 804 |
* @return string field HTML |
| 805 |
*/ |
| 806 |
public function field_usergroup( $f ) { |
| 807 |
$field_html = ''; |
| 808 |
if( ! empty( $f['allowedGroupIds'] ) ) { |
| 809 |
$field_html .= '<select name="' . esc_attr( $f['fieldName'] ) . '" |
| 810 |
id="' . esc_attr( $f['fieldId'] ) . '" |
| 811 |
class="' . esc_attr( $f['class'] ) . '" |
| 812 |
' . $f['isDisabled'] . ' ' . $f['isRequired'] . ' ' . $f['attributes'] . '>'; |
| 813 |
|
| 814 |
$field_html .= '<option value="">' . wpforo_phrase( '--- Choose ---', false ) . '</option>'; |
| 815 |
foreach( $f['allowedGroupIds'] as $groupid ) { |
| 816 |
if( $f['value'] != 4 && $groupid == 4 ) continue; |
| 817 |
if( $group = WPF()->usergroup->get_usergroup( $groupid ) ) { |
| 818 |
$field_html .= '<option value="' . esc_attr( $groupid ) . '" ' . $this->select( $groupid, $f['value'] ) . '>' . $group['name'] . '</option>'; |
| 819 |
} |
| 820 |
} |
| 821 |
$field_html .= '</select>'; |
| 822 |
} |
| 823 |
|
| 824 |
return $field_html; |
| 825 |
} |
| 826 |
|
| 827 |
public function field_secondary_groups( $f ) { |
| 828 |
$field_html = ''; |
| 829 |
if( $groups = WPF()->usergroup->get_secondary_groups() ) { |
| 830 |
$allowed_groupids = (array) wpfval( $f, 'allowedGroupIds' ); |
| 831 |
$i = 0; |
| 832 |
$field_html .= '<input type="hidden" name="' . esc_attr( $f['fieldName'] ) . '" value="">'; |
| 833 |
foreach( $groups as $group ) { |
| 834 |
if( in_array( $group['groupid'], [ 1, 2, 4 ] ) || ( $allowed_groupids && ! in_array( $group['groupid'], $allowed_groupids ) ) ) continue; |
| 835 |
$id = $f['fieldId'] . '_' . ++ $i; |
| 836 |
$field_html .= '<div class="wpf-field-item">'; |
| 837 |
$item_html = '<input type="checkbox" ' . $this->check( $group['groupid'], $f['value'] ) . ' |
| 838 |
name="' . esc_attr( $f['fieldName'] . '[]' ) . '" |
| 839 |
value="' . esc_attr( $group['groupid'] ) . '" |
| 840 |
id="' . esc_attr( $id ) . '" |
| 841 |
class="wpf-input-checkbox ' . esc_attr( $f['class'] ) . '" |
| 842 |
' . $f['isDisabled'] . ' ' . $f['attributes'] . '>'; |
| 843 |
$field_html .= $this->build_label( $group['name'], $item_html, $f, $id ); |
| 844 |
$field_html .= '</div>'; |
| 845 |
} |
| 846 |
} |
| 847 |
|
| 848 |
return $field_html; |
| 849 |
} |
| 850 |
|
| 851 |
/** |
| 852 |
* Avatar - Field builder |
| 853 |
* |
| 854 |
* @param array $f field arguments |
| 855 |
* |
| 856 |
* @return string field HTML |
| 857 |
*/ |
| 858 |
public function field_avatar( $f ) { |
| 859 |
$protocol = is_ssl() ? 'https://' : 'http://'; |
| 860 |
$remote_url = ( $f['value'] && strpos( (string) $f['value'], 'wpforo/avatars' ) === false ) ? $f['value'] : ''; |
| 861 |
$field_html = '<ul> |
| 862 |
<li> |
| 863 |
<input ' . $f['isRequired'] . ' name="' . esc_attr( |
| 864 |
$f['varname'] |
| 865 |
) . '[avatar_type]" id="wpfat_gravatar" value="gravatar" ' . ( $f['value'] == '' || $f['value'] == null ? 'checked="checked"' : '' ) . ' type="radio" /> |
| 866 |
<label for="wpfat_gravatar">' . wpforo_phrase( 'Default avatar', false ) . '</label> |
| 867 |
</li> |
| 868 |
<li> |
| 869 |
<input name="' . esc_attr( $f['varname'] ) . '[avatar_type]" id="wpfat_remote" value="remote" ' . ( $f['value'] && strpos( |
| 870 |
(string) $f['value'], |
| 871 |
'wpforo/avatars' |
| 872 |
) === false ? 'checked="checked"' : '' ) . ' type="radio" /> |
| 873 |
<label for="wpfat_remote">' . wpforo_phrase( 'Specify avatar by URL:', false ) . '</label> |
| 874 |
<input autocomplete="off" name="' . esc_attr( $f['varname'] ) . '[avatar_url]" value="' . esc_url( preg_replace( '|^//|is', $protocol, (string) $remote_url ) ) . '" maxlength="990" data-wpfucf-minmaxlength="1,990" type="url" /> |
| 875 |
</li>'; |
| 876 |
if( ( wpfval( WPF()->current_object, 'template' ) && WPF()->current_object['template'] === 'register' ) || WPF()->usergroup->can( 'upa' ) ) { |
| 877 |
if( strpos( (string) $f['value'], 'gravatar.com' ) === false && strpos( $f['value'], 'facebook.com' ) === false ) { |
| 878 |
$url = $f['value'] . '?lm=' . time(); |
| 879 |
} else { |
| 880 |
$url = ''; |
| 881 |
} |
| 882 |
$field_html .= '<li> |
| 883 |
<input name="' . esc_attr( $f['varname'] ) . '[avatar_type]" id="wpfat_custom" value="custom" type="radio" ' . ( ( strpos( $url, 'wpforo/avatars' ) !== false ) ? 'checked' : '' ) . ' /> |
| 884 |
<label for="wpfat_custom"> ' . wpforo_phrase( 'Upload an avatar', false ) . '</label>' . ( strpos( $url, 'wpforo/avatars' ) !== false ? '<br /> |
| 885 |
<img src="' . esc_url( (string) $url ) . '" class="wpf-custom-avatar-img" alt="avatar">' : '' ) . ' |
| 886 |
<input class="wpf-custom-avatar" name="avatar" type="file" /> </li>'; |
| 887 |
} |
| 888 |
$field_html .= '</ul> <script type="text/javascript">jQuery(document).ready(function($){$( "input[name=\'' . esc_attr( |
| 889 |
$f['varname'] |
| 890 |
) . '\[avatar_url\]\']" ).on("click", function(){$( "#wpfat_remote" ).prop(\'checked\', true);}); $( "input[name=\'avatar\']" ).on("click", function(){$( "#wpfat_custom" ).prop(\'checked\', true);});});</script>'; |
| 891 |
|
| 892 |
return $field_html; |
| 893 |
} |
| 894 |
|
| 895 |
/** |
| 896 |
* HTML - Field builder |
| 897 |
* |
| 898 |
* @param array $f field arguments |
| 899 |
* |
| 900 |
* @return string field HTML |
| 901 |
*/ |
| 902 |
public function field_html( $f ) { |
| 903 |
return stripslashes( do_shortcode( wpforo_apply_ucf_shortcode( (string) $f['html'] ) ) ); |
| 904 |
} |
| 905 |
|
| 906 |
/** |
| 907 |
* URL - Field builder |
| 908 |
* |
| 909 |
* @param array $f field arguments |
| 910 |
* |
| 911 |
* @return string field HTML |
| 912 |
*/ |
| 913 |
public function field_url( $f ) { |
| 914 |
return '<input type="url" value="' . esc_url_raw( $f['value'] ) . '" |
| 915 |
name="' . esc_attr( $f['fieldName'] ) . '" |
| 916 |
id="' . esc_attr( $f['fieldId'] ) . '" |
| 917 |
class="' . esc_attr( $f['class'] ) . '" |
| 918 |
placeholder="' . esc_attr( $f['placeholder'] ) . '" |
| 919 |
' . $f['isRequired'] . ' ' . $f['isDisabled'] . ' ' . $f['attributes'] . ' ' . $f['minmax'] . '/>'; |
| 920 |
} |
| 921 |
|
| 922 |
/** |
| 923 |
* Nickname - Field builder |
| 924 |
* |
| 925 |
* @param array $f field arguments |
| 926 |
* |
| 927 |
* @return string field HTML |
| 928 |
*/ |
| 929 |
public function field_nicename( $f ) { |
| 930 |
return '<input type="text" value="' . esc_attr( urldecode( (string) $f['value'] ) ) . '" |
| 931 |
name="' . esc_attr( $f['fieldName'] ) . '" |
| 932 |
id="' . esc_attr( $f['fieldId'] ) . '" |
| 933 |
class="' . esc_attr( $f['class'] ) . '" |
| 934 |
placeholder="' . esc_attr( $f['placeholder'] ) . '" |
| 935 |
' . $f['isRequired'] . ' ' . $f['isDisabled'] . ' ' . $f['attributes'] . ' ' . $f['minmax'] . '/>'; |
| 936 |
} |
| 937 |
|
| 938 |
/** |
| 939 |
* Text - Field builder |
| 940 |
* |
| 941 |
* @param array $f field arguments |
| 942 |
* |
| 943 |
* @return string field HTML |
| 944 |
*/ |
| 945 |
public function field_text( $f ) { |
| 946 |
return '<input type="' . esc_attr( $f['type'] ) . '" |
| 947 |
value="' . esc_attr( $f['value'] ) . '" |
| 948 |
name="' . esc_attr( $f['fieldName'] ) . '" |
| 949 |
id="' . esc_attr( $f['fieldId'] ) . '" |
| 950 |
class="' . esc_attr( $f['class'] ) . '" |
| 951 |
placeholder="' . esc_attr( $f['placeholder'] ) . '" |
| 952 |
' . $f['isRequired'] . ' ' . $f['isDisabled'] . ' ' . $f['attributes'] . ' ' . $f['minmax'] . '/>'; |
| 953 |
} |
| 954 |
|
| 955 |
public function field_tel( $f ) { |
| 956 |
return '<input type="' . esc_attr( $f['type'] ) . '" |
| 957 |
value="' . esc_attr( $f['value'] ) . '" |
| 958 |
name="' . esc_attr( $f['fieldName'] ) . '" |
| 959 |
id="' . esc_attr( $f['fieldId'] ) . '" |
| 960 |
class="' . esc_attr( $f['class'] ) . '" |
| 961 |
placeholder="' . esc_attr( $f['placeholder'] ) . '" |
| 962 |
' . $f['isRequired'] . ' ' . $f['isDisabled'] . ' ' . $f['attributes'] . ' ' . $f['minmax'] . ' |
| 963 |
pattern="' . ( ! empty( $f['pattern'] ) ? $f['pattern'] : '[0-9]*' ) . '">'; |
| 964 |
} |
| 965 |
|
| 966 |
/** |
| 967 |
* Prepares displayed values for Profile fields |
| 968 |
* |
| 969 |
* @param array $f field arguments |
| 970 |
* @param int $userid |
| 971 |
* |
| 972 |
* @return array prepared values |
| 973 |
*/ |
| 974 |
public function prepare_values( $f, $userid = 0 ) { |
| 975 |
switch( $f['type'] ) { |
| 976 |
case 'textarea': |
| 977 |
$f['value'] = wpforo_kses( wpforo_decode( $f['value'] ) ); |
| 978 |
break; |
| 979 |
case 'date': |
| 980 |
// $f['value'] = wpforo_date($f['value'], 'date', false); |
| 981 |
break; |
| 982 |
case 'datetime': |
| 983 |
$f['value'] = wpforo_date( $f['value'], 'datetime', false ); |
| 984 |
break; |
| 985 |
case 'url': |
| 986 |
$f['value'] = sprintf( '<a href="%1$s" target="_blank" rel="nofollow">%2$s</a>', $f['value'], $f['value'] ); |
| 987 |
break; |
| 988 |
case 'email': |
| 989 |
$f['value'] = sprintf( '<a href="mailto:%1$s" rel="nofollow">%2$s</a>', $f['value'], $f['value'] ); |
| 990 |
break; |
| 991 |
case 'tel': |
| 992 |
$f['value'] = sprintf( '<a href="tel:%1$s" rel="nofollow">%2$s</a>', $f['value'], $f['value'] ); |
| 993 |
break; |
| 994 |
case 'file': |
| 995 |
if( ! empty( $f['value'] ) ) { |
| 996 |
if( is_array( $f['value'] ) ) { |
| 997 |
$file_name = (string) wpfval( $f['value'], 'filename' ); |
| 998 |
$f['value'] = (string) wpfval( $f['value'], 'fileurl' ); |
| 999 |
} else { |
| 1000 |
$file_name = basename( (string) $f['value'] ); |
| 1001 |
} |
| 1002 |
$f['value'] = wpforo_fix_upload_url( $f['value'] ); |
| 1003 |
$file_url = esc_url_raw( $f['value'] ); |
| 1004 |
$file_name = esc_attr( $file_name ); |
| 1005 |
$extension = pathinfo( $f['value'], PATHINFO_EXTENSION ); |
| 1006 |
if( wpforo_is_image( $extension ) ) { |
| 1007 |
$f['value'] = sprintf( |
| 1008 |
'<a href="%1$s" target="_blank" title="%2$s"><img src="%1$s" alt="%2$s" class="wpf-field-file-img" style="max-width:120px; max-height:120px"></a>', |
| 1009 |
$file_url, |
| 1010 |
$file_name |
| 1011 |
); |
| 1012 |
} elseif( wpforo_is_audio( $extension ) ) { |
| 1013 |
$f['value'] = sprintf( '<audio src="%1$s" controls title="%2$s"></audio>', $file_url, $file_name ); |
| 1014 |
} elseif( wpforo_is_video( $extension ) ) { |
| 1015 |
$f['value'] = sprintf( '<video src="%1$s" controls title="%2$s"></video>', $file_url, $file_name ); |
| 1016 |
} else { |
| 1017 |
$f['value'] = sprintf( '<a href="%s" target="_blank">%s</a>', $file_url, $file_name ); |
| 1018 |
} |
| 1019 |
} |
| 1020 |
break; |
| 1021 |
case 'avatar': |
| 1022 |
$f['value'] = ( WPF()->usergroup->can( 'va' ) && wpforo_setting( 'profiles', 'avatars' ) ) ? WPF()->member->get_avatar_html( $f['value'], $userid ) : ''; |
| 1023 |
break; |
| 1024 |
case 'color': |
| 1025 |
if( $f['value'] ) { |
| 1026 |
$f['value'] = '<input type="color" value="' . $f['value'] . '" disabled title="' . $f['value'] . '" style="min-width: 100px; min-height: 25px;">'; |
| 1027 |
} |
| 1028 |
break; |
| 1029 |
} |
| 1030 |
switch( $f['name'] ) { |
| 1031 |
case 'skype': |
| 1032 |
$f['value'] = sprintf( '<a href="skype:%s?userinfo" rel="nofollow">%s</a>', $f['value'], $f['value'] ); |
| 1033 |
break; |
| 1034 |
case 'location': |
| 1035 |
$f['value'] = sprintf( '<a href="//maps.google.com/?q=%s" target="_blank" rel="nofollow">%s</a>', $f['value'], $f['value'] ); |
| 1036 |
break; |
| 1037 |
case 'signature': |
| 1038 |
$f['value'] = wpforo_signature( $f['value'], [ 'echo' => 0 ] ); |
| 1039 |
break; |
| 1040 |
case 'about': |
| 1041 |
$f['value'] = wpforo_nofollow_tag( $f['value'] ); |
| 1042 |
break; |
| 1043 |
} |
| 1044 |
|
| 1045 |
return apply_filters( 'wpforo_form_prepare_values', $f ); |
| 1046 |
} |
| 1047 |
|
| 1048 |
/** |
| 1049 |
* Prepares arguments |
| 1050 |
* |
| 1051 |
* @param array $f field arguments |
| 1052 |
* |
| 1053 |
* @return array prepared values |
| 1054 |
*/ |
| 1055 |
public function prepare_args( $f ) { |
| 1056 |
|
| 1057 |
$is_owner = $this->owner(); |
| 1058 |
|
| 1059 |
//field_class |
| 1060 |
$f['field_class'] = sanitize_text_field( $f['name'] ); |
| 1061 |
|
| 1062 |
//varname |
| 1063 |
$f['varname'] = $f['isDefault'] ? (string) wpfval( $this->current, 'varname' ) : 'data'; |
| 1064 |
|
| 1065 |
//template |
| 1066 |
$f['template'] = ( isset( $this->current['template'] ) ) ? $this->current['template'] : WPF()->current_object['template']; |
| 1067 |
|
| 1068 |
//value |
| 1069 |
$f['value'] = ( isset( $this->current['value'][ $f['name'] ] ) ) ? $this->current['value'][ $f['name'] ] : $f['value']; |
| 1070 |
if( ! $f['isDefault'] && $f['varname'] ) { |
| 1071 |
$f['value'] = ( isset( $this->current['value'][ $f['varname'] ][ $f['name'] ] ) ) ? $this->current['value'][ $f['varname'] ][ $f['name'] ] : $f['value']; |
| 1072 |
} |
| 1073 |
$f['value'] = wpforo_unslashe( $f['value'] ); |
| 1074 |
$f['value'] = wpforo_decode( $f['value'] ); |
| 1075 |
|
| 1076 |
if( $f['name'] === 'user_nicename' ) { |
| 1077 |
$f['value'] = urldecode( (string) $f['value'] ); |
| 1078 |
} |
| 1079 |
|
| 1080 |
//allowedGroupIds |
| 1081 |
$groups = []; |
| 1082 |
if( ! empty( $f['allowedGroupIds'] ) ) $groups = $this->build_array_value( $f['allowedGroupIds'] ); |
| 1083 |
if( $f['type'] === 'usergroup' ) { |
| 1084 |
if( ! $is_owner && wpforo_current_user_is( 'admin' ) ) { |
| 1085 |
$groups = WPF()->usergroup->get_usergroups( 'groupid' ); |
| 1086 |
} elseif( $is_owner && ! in_array( WPF()->current_user_groupid, $f['allowedGroupIds'] ) ) { |
| 1087 |
$groups = []; |
| 1088 |
} |
| 1089 |
} |
| 1090 |
$f['allowedGroupIds'] = array_filter( $groups ); |
| 1091 |
|
| 1092 |
//isRequired |
| 1093 |
if( $f['isRequired'] ) { |
| 1094 |
$f['required_class'] = ' wpf-field-required '; |
| 1095 |
$f['required_indicator'] = ' <span class="wpf-field-required-icon" title="' . esc_attr( wpforo_phrase( 'Required field', false ) ) . '">*</span>'; |
| 1096 |
} else { |
| 1097 |
$f['required_class'] = ''; |
| 1098 |
$f['required_indicator'] = ''; |
| 1099 |
} |
| 1100 |
|
| 1101 |
return $f; |
| 1102 |
} |
| 1103 |
|
| 1104 |
/** |
| 1105 |
* @param array $f field arguments |
| 1106 |
* |
| 1107 |
* @return array prepared values |
| 1108 |
*/ |
| 1109 |
public function prepare_field_args( $f ) { |
| 1110 |
//faIcon |
| 1111 |
$f['faIcon'] = trim( (string) $f['faIcon'] ); |
| 1112 |
if( strpos( $f['faIcon'], ' ' ) === false ) $f['faIcon'] = 'fas ' . $f['faIcon']; |
| 1113 |
|
| 1114 |
//isRequired |
| 1115 |
$f['isRequired'] = ( $f['isRequired'] ) ? ' required="required" ' : ''; |
| 1116 |
|
| 1117 |
//isDisabled |
| 1118 |
$f['isDisabled'] = ( $f['isDisabled'] ) ? ' disabled="disabled" ' : ''; |
| 1119 |
|
| 1120 |
//fieldName | new key in args |
| 1121 |
$f['fieldName'] = ( ! empty( $f['varname'] ) ? $f['varname'] . '[' . $f['name'] . ']' : $f['name'] ); |
| 1122 |
|
| 1123 |
//isMultiChoice |
| 1124 |
if( $f['isMultiChoice'] ) { |
| 1125 |
$f['fieldName'] .= '[]'; |
| 1126 |
$f['isMultiChoice'] = ' multiple="multiple" '; |
| 1127 |
} else { |
| 1128 |
$f['isMultiChoice'] = ''; |
| 1129 |
} |
| 1130 |
|
| 1131 |
//fieldId | new key in args |
| 1132 |
$f['fieldId'] = ( $f['varname'] ? $f['varname'] . '_' : '' ) . ( $f['id'] ?: $f['name'] ); |
| 1133 |
$f['fieldId'] = uniqid( $f['fieldId'] . '_' ); |
| 1134 |
|
| 1135 |
//minLength & maxLength |
| 1136 |
$f['minLength'] = ( $f['minLength'] ) ? intval( $f['minLength'] ) : ''; |
| 1137 |
$f['maxLength'] = ( $f['maxLength'] ) ? intval( $f['maxLength'] ) : ''; |
| 1138 |
if( $f['minLength'] ) { |
| 1139 |
$minLength_attr = ( $f['type'] === 'date' || $f['type'] === 'number' || $f['type'] === 'range' ) ? ' min="' . $f['minLength'] . '" ' : ' minlength="' . $f['minLength'] . '" '; |
| 1140 |
} |
| 1141 |
if( $f['maxLength'] ) { |
| 1142 |
$maxLength_attr = ( $f['type'] === 'date' || $f['type'] === 'number' || $f['type'] === 'range' ) ? ' max="' . $f['maxLength'] . '" ' : ' maxlength="' . $f['maxLength'] . '" '; |
| 1143 |
} |
| 1144 |
$f['minmax'] = isset( $minLength_attr ) ? $minLength_attr : ''; |
| 1145 |
$f['minmax'] .= isset( $maxLength_attr ) ? ' ' . $maxLength_attr : ''; |
| 1146 |
|
| 1147 |
//attributes |
| 1148 |
$f['attributes'] .= ' autocomplete="off"'; |
| 1149 |
|
| 1150 |
if( wpfkey( $f, 'fileExtensions' ) ) { |
| 1151 |
if( is_scalar( $f['fileExtensions'] ) ) $f['fileExtensions'] = explode( ',', $f['fileExtensions'] ); |
| 1152 |
$f['fileExtensions'] = array_filter( $f['fileExtensions'] ); |
| 1153 |
} |
| 1154 |
|
| 1155 |
return $f; |
| 1156 |
} |
| 1157 |
|
| 1158 |
/** |
| 1159 |
* @param array $file_data |
| 1160 |
* @param int $userid |
| 1161 |
* |
| 1162 |
* @return array |
| 1163 |
*/ |
| 1164 |
public function prepare_file_args( $file_data, $userid = 1 ) { |
| 1165 |
$file = [ 'files' => [], 'fields' => [] ]; |
| 1166 |
$userid = $userid ?: WPF()->current_userid; |
| 1167 |
|
| 1168 |
if( ! empty( $file_data ) ) { |
| 1169 |
foreach( $file_data as $file_field_name => $file_name ) { |
| 1170 |
$field_name_folder = substr( (string) $file_field_name, 6 ); |
| 1171 |
$file_upload_dir = wpforo_fix_dir_sep( |
| 1172 |
WPF()->folders['wp_upload']['dir'] . $this->field_dir . $userid . DIRECTORY_SEPARATOR . $field_name_folder |
| 1173 |
) . DIRECTORY_SEPARATOR; |
| 1174 |
$file_path = $file_upload_dir . $file_name; |
| 1175 |
$file['files'][ $file_field_name ] = $file_path; |
| 1176 |
$file['fields'][ $file_field_name ] = $this->field_dir . $userid . '/' . $field_name_folder . '/' . $file_name; |
| 1177 |
wp_mkdir_p( $file_upload_dir ); |
| 1178 |
} |
| 1179 |
} |
| 1180 |
|
| 1181 |
return $file; |
| 1182 |
} |
| 1183 |
|
| 1184 |
public function check( $needle, $haystack ) { |
| 1185 |
if( is_scalar( $haystack ) ) $haystack = explode( ',', $haystack ); |
| 1186 |
|
| 1187 |
return in_array( $needle, (array) $haystack ) ? 'checked' : ''; |
| 1188 |
} |
| 1189 |
|
| 1190 |
public function select( $needle, $haystack ) { |
| 1191 |
return in_array( $needle, (array) $haystack ) ? 'selected' : ''; |
| 1192 |
} |
| 1193 |
|
| 1194 |
public function build_label( $item_label, $item_html, $f, $for = '' ) { |
| 1195 |
$label = '<label for="' . $for . '" class="wpf-' . $f['type'] . '-label">' . stripslashes( (string) $item_label ) . '</label>'; |
| 1196 |
$field_html = $f['isLabelFirst'] ? $label . ' ' . $item_html : $item_html . ' ' . $label; |
| 1197 |
if( $f['isWrapItem'] ) $field_html = '<label for="' . $for . '">' . $field_html . '</label>'; |
| 1198 |
|
| 1199 |
return $field_html; |
| 1200 |
} |
| 1201 |
|
| 1202 |
public function build_item_value_lable( $string, $sep = '=>' ) { |
| 1203 |
$string = trim( (string) $string ); |
| 1204 |
$count = 0; |
| 1205 |
$string = preg_replace( '#^\[(.+?)]$#isu', '$1', (string) $string, 1, $count ); |
| 1206 |
$default_selected = (bool) $count; |
| 1207 |
$data = explode( $sep, $string ); |
| 1208 |
$value = wpfkey( $data, 0 ) ? trim( (string) $data[0] ) : 'no_value'; |
| 1209 |
$label = wpfkey( $data, 1 ) ? trim( (string) $data[1] ) : $value; |
| 1210 |
|
| 1211 |
return compact( 'value', 'label', 'default_selected' ); |
| 1212 |
} |
| 1213 |
|
| 1214 |
public function build_array_value( $var, $sep = ',' ) { |
| 1215 |
if( is_scalar( $var ) ) { |
| 1216 |
$var = trim( (string) $var ); |
| 1217 |
if( ! strlen( (string) $var ) ) return []; |
| 1218 |
} |
| 1219 |
if( is_serialized( $var ) ) { |
| 1220 |
$var = unserialize( $var ); |
| 1221 |
} elseif( is_scalar( $var ) && strpos( (string) $var, $sep ) !== false ) { |
| 1222 |
$var = explode( $sep, $var ); |
| 1223 |
} |
| 1224 |
|
| 1225 |
return array_map( 'trim', (array) $var ); |
| 1226 |
} |
| 1227 |
|
| 1228 |
public function build_array_using_string_rows( $string, $regexp = '' ) { |
| 1229 |
if( is_scalar( $string ) ) { |
| 1230 |
if( ! $regexp ) $regexp = '#' . preg_quote( PHP_EOL ) . '#isu'; |
| 1231 |
|
| 1232 |
return array_filter( preg_split( $regexp, $string ) ); |
| 1233 |
} |
| 1234 |
|
| 1235 |
return $string; |
| 1236 |
} |
| 1237 |
|
| 1238 |
public function sanitize( $data, $fields ) { |
| 1239 |
$types = $this->field_types( $fields ); |
| 1240 |
if( ! empty( $data ) && ! empty( $types ) ) { |
| 1241 |
foreach( $data as $name => $value ) { |
| 1242 |
if( wpfval( $types, $name ) ) { |
| 1243 |
$data[ $name ] = $this->sanitize_field( $value, $types[ $name ], $name ); |
| 1244 |
} |
| 1245 |
} |
| 1246 |
} |
| 1247 |
|
| 1248 |
return $data; |
| 1249 |
} |
| 1250 |
|
| 1251 |
public function sanitize_field( $value, $type = 'text', $name = '' ) { |
| 1252 |
if( ! is_null( $value ) ) { |
| 1253 |
if( $type === 'text' ) { |
| 1254 |
$value = sanitize_text_field( $value ); |
| 1255 |
if( $name === 'user_nicename' ) { |
| 1256 |
$value = sanitize_title( sanitize_user( $value, true ) ); |
| 1257 |
} |
| 1258 |
} elseif( $type === 'url' ) { |
| 1259 |
$value = esc_url_raw( $value ); |
| 1260 |
} elseif( $type === 'date' ) { |
| 1261 |
$value = sanitize_text_field( $value ); |
| 1262 |
} elseif( $type === 'textarea' ) { |
| 1263 |
$value = stripslashes( wpforo_kses( trim( (string) $value ), 'user_description' ) ); |
| 1264 |
} elseif( $type === 'email' ) { |
| 1265 |
$value = sanitize_email( $value ); |
| 1266 |
} elseif( $type === 'password' ) { |
| 1267 |
$value = trim( (string) $value ); |
| 1268 |
} elseif( $type === 'usergroup' ) { |
| 1269 |
$value = intval( $value ); |
| 1270 |
} elseif( $type === 'radio' ) { |
| 1271 |
$value = sanitize_text_field( $value ); |
| 1272 |
} elseif( $type === 'checkbox' ) { |
| 1273 |
if( $name === 'secondary_groupids' ) { |
| 1274 |
$value = wpforo_sanitize_int( $value ); |
| 1275 |
} else { |
| 1276 |
$value = wpforo_sanitize_text( $value ); |
| 1277 |
} |
| 1278 |
} elseif( $type === 'select' ) { |
| 1279 |
$value = sanitize_text_field( $value ); |
| 1280 |
} elseif( $type === 'color' ) { |
| 1281 |
$value = sanitize_text_field( $value ); |
| 1282 |
} elseif( $type === 'number' ) { |
| 1283 |
$value = intval( $value ); |
| 1284 |
} elseif( $type === 'tel' ) { |
| 1285 |
$value = sanitize_text_field( $value ); |
| 1286 |
} elseif( $type === 'html' ) { |
| 1287 |
$value = preg_replace( '#<script(.*?)>(.*?)</script>#is', '', (string) $value ); |
| 1288 |
} |
| 1289 |
|
| 1290 |
if( is_string( $value ) ) { |
| 1291 |
$value = stripslashes( (string) $value ); |
| 1292 |
} |
| 1293 |
} |
| 1294 |
|
| 1295 |
return $value; |
| 1296 |
} |
| 1297 |
|
| 1298 |
public function esc_field( $f ) { |
| 1299 |
if( wpfkey( $f, 'value' ) ) { |
| 1300 |
$f['value'] = wpforo_trim( $f['value'] ); |
| 1301 |
if( in_array( wpfval( $f, 'type' ), [ 'textarea', 'tinymce' ], true ) ) { |
| 1302 |
$f['value'] = wpautop( wpforo_kses( stripslashes( (string) $f['value'] ) ) ); |
| 1303 |
} elseif( wpfval( $f, 'type' ) === 'file' ) { |
| 1304 |
$f['value'] = wpfval( $f['value'], 'fileurl' ) ?: $f['value']; |
| 1305 |
} elseif( $f['name'] === 'timezone' ) { |
| 1306 |
$f['value'] = str_replace( '_', ' ', $f['value'] ); |
| 1307 |
} elseif( $f['fieldKey'] === 'secondary_groupids' ) { |
| 1308 |
$f['value'] = WPF()->usergroup->get_secondary_group_names( $f['value'] ); |
| 1309 |
$f['value'] = implode( ', ', $f['value'] ); |
| 1310 |
} elseif( $f['type'] === 'usergroup' && $f['fieldKey'] === 'groupid' && ( $f['value'] = intval( $f['value'] ) ) ) { |
| 1311 |
if( $group = WPF()->usergroup->get_usergroup( $f['value'] ) ) $f['value'] = wpfval( $group, 'name' ); |
| 1312 |
} elseif( is_array( $f['value'] ) ) { |
| 1313 |
$f['value'] = array_filter( $f['value'] ); |
| 1314 |
$f['value'] = implode( ', ', $f['value'] ); |
| 1315 |
} |
| 1316 |
} |
| 1317 |
$f['value'] = apply_filters( 'wpforo_display_field_value', $f['value'], $f ); |
| 1318 |
|
| 1319 |
return $f; |
| 1320 |
} |
| 1321 |
|
| 1322 |
public function validate( &$data, &$fields ) { |
| 1323 |
$type = ''; |
| 1324 |
$label = ''; |
| 1325 |
$userid = ''; |
| 1326 |
$error = []; |
| 1327 |
$return = []; |
| 1328 |
$is_owner = $this->owner(); |
| 1329 |
$template = ( isset( $this->current['template'] ) ) ? $this->current['template'] : WPF()->current_object['template']; |
| 1330 |
if( empty( $data ) ) $error[] = 'No data submitted'; |
| 1331 |
if( empty( $fields ) ) $error[] = 'User profile fields not found'; |
| 1332 |
if( empty( $error ) ) { |
| 1333 |
foreach( $fields as $r_key => $rows ) { |
| 1334 |
foreach( $rows as $c_key => $cols ) { |
| 1335 |
foreach( $cols as $key => $field ) { |
| 1336 |
if( wpfval( $field, 'name' ) ) { |
| 1337 |
$name = $field['name']; |
| 1338 |
if( ! $template && wpfval( $field, 'template' ) ) $template = $field['template']; |
| 1339 |
if( wpfval( $field, 'label' ) ) $label = esc_html( $field['label'] ); |
| 1340 |
if( wpfval( $field, 'type' ) ) $type = $field['type']; |
| 1341 |
if( wpfval( $data, 'userid' ) ) $userid = $data['userid']; |
| 1342 |
if( $template && $template !== 'register' ) { |
| 1343 |
if( $template === 'account' && $field['type'] === 'password' ) $field['isRequired'] = 0; |
| 1344 |
if( ! $this->can_edit( $field ) ) { |
| 1345 |
unset( $cols[ $key ] ); |
| 1346 |
unset( $data[ $name ] ); |
| 1347 |
unset( $fields[ $r_key ][ $c_key ][ $key ] ); |
| 1348 |
} |
| 1349 |
} |
| 1350 |
if( wpfkey( $cols, $key ) && wpfkey( $data, $name ) ) { |
| 1351 |
$value = $data[ $name ]; |
| 1352 |
if( is_string( $value ) ) { |
| 1353 |
$value = trim( $value ); |
| 1354 |
$value = htmlspecialchars_decode( $value ); |
| 1355 |
} |
| 1356 |
if( wpfval( $field, 'isRequired' ) && ! $value ) { |
| 1357 |
$error[] = $label . ' ' . wpforo_phrase( 'field is required', false, false ); |
| 1358 |
} |
| 1359 |
if( $value ) { |
| 1360 |
if( $type === 'number' ) { |
| 1361 |
if( wpfval( $field, 'minLength' ) ) { |
| 1362 |
if( (int) $value < $field['minLength'] ) { |
| 1363 |
$error[] = $label . ' ' . sprintf( wpforo_phrase( 'field value must be at least %d', false, false ), intval( $field['minLength'] ) ); |
| 1364 |
} |
| 1365 |
} |
| 1366 |
if( wpfval( $field, 'maxLength' ) ) { |
| 1367 |
if( (int) $value > $field['maxLength'] ) { |
| 1368 |
$error[] = $label . ' ' . sprintf( wpforo_phrase( 'field value cannot be greater than %d', false, false ), intval( $field['maxLength'] ) ); |
| 1369 |
} |
| 1370 |
} |
| 1371 |
} else { |
| 1372 |
if( wpfval( $field, 'minLength' ) ) { |
| 1373 |
if( wpforo_strlen( $value ) < $field['minLength'] ) { |
| 1374 |
$error[] = $label . ' ' . sprintf( wpforo_phrase( 'field length must be at least %d characters', false, false ), intval( $field['minLength'] ) ); |
| 1375 |
} |
| 1376 |
} |
| 1377 |
if( wpfval( $field, 'maxLength' ) ) { |
| 1378 |
if( wpforo_strlen( $value ) > $field['maxLength'] ) { |
| 1379 |
$error[] = $label . ' ' . sprintf( wpforo_phrase( 'field length cannot be greater than %d characters', false, false ), intval( $field['maxLength'] ) ); |
| 1380 |
} |
| 1381 |
} |
| 1382 |
} |
| 1383 |
if( $type === 'url' && filter_var( $value, FILTER_VALIDATE_URL ) === false ) { |
| 1384 |
$error[] = $label . ' ' . wpforo_phrase( 'field value is not a valid URL', false, false ); |
| 1385 |
} |
| 1386 |
if( $type === 'email' ) { |
| 1387 |
if( ! is_email( $value ) ) { |
| 1388 |
$error[] = $label . ' ' . wpforo_phrase( 'Invalid Email address', false, false ); |
| 1389 |
} |
| 1390 |
if( $name === 'user_email' ) { |
| 1391 |
$email_owner = email_exists( $value ); |
| 1392 |
if( $email_owner && $email_owner != $userid ) { |
| 1393 |
$error[] = $label . ' ' . wpforo_phrase( 'This email address is already registered. Please insert another', false, false ); |
| 1394 |
} |
| 1395 |
} |
| 1396 |
} |
| 1397 |
if( $type === 'file' ) { |
| 1398 |
$extension = pathinfo( $value, PATHINFO_EXTENSION ); |
| 1399 |
$extension = ( function_exists( 'mb_strtolower' ) ) ? mb_strtolower( (string) $extension ) : strtolower( (string) $extension ); |
| 1400 |
if( wpfval( $field, 'fileExtensions' ) ) { |
| 1401 |
if( $extension ) { |
| 1402 |
if( ! in_array( $extension, $field['fileExtensions'] ) ) { |
| 1403 |
$error[] = $label . ' ' . wpforo_phrase( 'file type is not allowed', false, false ); |
| 1404 |
$error[] = sprintf( 'Allowed file types: %s', implode( ', ', $field['fileExtensions'] ) ); |
| 1405 |
} |
| 1406 |
} else { |
| 1407 |
$error[] = $label . ' ' . wpforo_phrase( 'file type is not detected', false, false ); |
| 1408 |
} |
| 1409 |
} else { |
| 1410 |
$mime_types = get_allowed_mime_types(); |
| 1411 |
$mime_types = array_flip( $mime_types ); |
| 1412 |
if( ! empty( $mime_types ) ) { |
| 1413 |
$implode_types = implode( '|', $mime_types ); |
| 1414 |
$explode_types = explode( '|', $implode_types ); |
| 1415 |
if( ! in_array( $extension, $explode_types ) ) { |
| 1416 |
$error[] = $label . ' ' . sprintf( wpforo_phrase( 'file type %s is not allowed', false, false ), $extension ); |
| 1417 |
} |
| 1418 |
if( ! WPF()->perm->can_attach_file_type( $extension ) ) { |
| 1419 |
$error[] = 'You are not allowed to attach this file type'; |
| 1420 |
} |
| 1421 |
} |
| 1422 |
} |
| 1423 |
if( wpfval( $field, 'fileSize' ) ) { |
| 1424 |
if( wpfval( $_FILES, 'data', 'size', $name ) && $_FILES['data']['size'][ $name ] > ( $field['fileSize'] * 1024 * 1024 ) ) { |
| 1425 |
$error[] = $label . ' ' . wpforo_phrase( 'file is too large', false, false ); |
| 1426 |
$error[] = sprintf( 'Maximum allowed file size is %s MB', $field['fileSize'] ); |
| 1427 |
} |
| 1428 |
} |
| 1429 |
} |
| 1430 |
if( $name === 'user_nicename' ) { |
| 1431 |
$value = sanitize_text_field( $value ); |
| 1432 |
$user_nicename = sanitize_title( sanitize_user( $value, true ) ); |
| 1433 |
if( ! $user_nicename ) { |
| 1434 |
$error[] = 'Nickname validation failed'; |
| 1435 |
} |
| 1436 |
$sql = "SELECT `ID` FROM `" . WPF()->db->users . "` WHERE `ID` != " . intval( $userid ) . " AND `user_nicename` LIKE '" . esc_sql( $user_nicename ) . "'"; |
| 1437 |
if( WPF()->db->get_var( $sql ) ) { |
| 1438 |
$error[] = 'This nickname is already in use. Please insert another.'; |
| 1439 |
} |
| 1440 |
} |
| 1441 |
if( $name === 'groupid' ) { |
| 1442 |
if( $template !== 'register' ) { |
| 1443 |
if( $is_owner || ! wpforo_current_user_is( 'admin' ) ) { |
| 1444 |
$error[] = 'You have no permission to edit Usergroup field'; |
| 1445 |
} |
| 1446 |
} else { |
| 1447 |
if( in_array( $value, [ 1, 2, 4 ] ) ) { |
| 1448 |
$error[] = 'Admin and Moderator Usergroups are not permitted'; |
| 1449 |
} else { |
| 1450 |
if( wpfval( $field, 'allowedGroupIds' ) ) { |
| 1451 |
$allowedGroupIds = wpforo_parse_args( $field['allowedGroupIds'] ); |
| 1452 |
if( ! in_array( $value, $allowedGroupIds ) ) { |
| 1453 |
$error[] = 'The selected Usergroup cannot be set'; |
| 1454 |
} |
| 1455 |
} else { |
| 1456 |
$error[] = 'The selected Usergroup is not found in allowed list'; |
| 1457 |
} |
| 1458 |
} |
| 1459 |
} |
| 1460 |
} |
| 1461 |
if( $name === 'secondary_groupids' ) { |
| 1462 |
if( $template === 'register' || ( $is_owner && $field['isEditable'] ) || ( ! $is_owner && in_array( |
| 1463 |
WPF()->current_user_groupid, |
| 1464 |
(array) $field['canEdit'] |
| 1465 |
) ) || wpforo_current_user_is( 'admin' ) ) { |
| 1466 |
if( ! empty( $value ) && is_array( $value ) ) { |
| 1467 |
$secondary_groupids = WPF()->usergroup->get_secondary_groupids(); |
| 1468 |
foreach( $value as $secondary_groupid ) { |
| 1469 |
if( in_array( $secondary_groupid, [ 1, 2, 4 ] ) ) { |
| 1470 |
$error[] = 'Admin and Moderator Usergroups are not permitted'; |
| 1471 |
} |
| 1472 |
if( $secondary_groupid && ! in_array( $secondary_groupid, $secondary_groupids ) ) { |
| 1473 |
$error[] = 'One of the selected Usergroups cannot be set as Secondary'; |
| 1474 |
} |
| 1475 |
} |
| 1476 |
} |
| 1477 |
} else { |
| 1478 |
$error[] = 'You have no permission to edit Usergroup field'; |
| 1479 |
} |
| 1480 |
} |
| 1481 |
} |
| 1482 |
} |
| 1483 |
} |
| 1484 |
} |
| 1485 |
} |
| 1486 |
} |
| 1487 |
} |
| 1488 |
if( ! empty( $error ) ) { |
| 1489 |
$return['error'] = $error; |
| 1490 |
|
| 1491 |
return $return; |
| 1492 |
} else { |
| 1493 |
return true; |
| 1494 |
} |
| 1495 |
} |
| 1496 |
|
| 1497 |
public function validate_password( $data ) { |
| 1498 |
$error = []; |
| 1499 |
$return = [ 'error' => false ]; |
| 1500 |
if( wpfval( $data, 'old_pass' ) && wpfval( $data, 'user_pass1' ) && wpfval( $data, 'user_pass2' ) ) { |
| 1501 |
if( $data['user_pass1'] !== $data['user_pass2'] ) { |
| 1502 |
$error[] = 'New Passwords do not match'; |
| 1503 |
} else { |
| 1504 |
return true; |
| 1505 |
} |
| 1506 |
} |
| 1507 |
if( ! empty( $error ) ) { |
| 1508 |
$return['error'] = $error; |
| 1509 |
|
| 1510 |
return $return; |
| 1511 |
} |
| 1512 |
|
| 1513 |
return false; |
| 1514 |
} |
| 1515 |
|
| 1516 |
public function field_types( $fields ) { |
| 1517 |
$name_type_fields = []; |
| 1518 |
if( ! empty( $fields ) ) { |
| 1519 |
foreach( $fields as $rows ) { |
| 1520 |
foreach( $rows as $cols ) { |
| 1521 |
foreach( $cols as $field ) { |
| 1522 |
if( wpfval( $field, 'name' ) && wpfval( $field, 'type' ) ) { |
| 1523 |
$name_type_fields[ $field['name'] ] = $field['type']; |
| 1524 |
} |
| 1525 |
} |
| 1526 |
} |
| 1527 |
} |
| 1528 |
} |
| 1529 |
|
| 1530 |
return $name_type_fields; |
| 1531 |
} |
| 1532 |
|
| 1533 |
public function owner( $object_userid = false ): bool { |
| 1534 |
if( ! $object_userid ) { |
| 1535 |
if( wpfval( WPF()->current_object, 'user', 'userid' ) ) { |
| 1536 |
return wpforo_is_owner( WPF()->current_object['user']['userid'] ); |
| 1537 |
} else { |
| 1538 |
return false; |
| 1539 |
} |
| 1540 |
} else { |
| 1541 |
return wpforo_is_owner( $object_userid ); |
| 1542 |
} |
| 1543 |
} |
| 1544 |
|
| 1545 |
/** |
| 1546 |
* @param array $f |
| 1547 |
* |
| 1548 |
* @return bool |
| 1549 |
*/ |
| 1550 |
public function can_add( $f ) { |
| 1551 |
if( wpfval( $f, 'name' ) ) { |
| 1552 |
if( $f['name'] === 'signature' && ! wpforo_setting( 'profiles', 'signature' ) ) { |
| 1553 |
return false; |
| 1554 |
} |
| 1555 |
if( $f['name'] === 'avatar' && ( ! wpforo_setting( 'profiles', 'custom_avatars' ) || ! wpforo_setting( 'profiles', 'avatars' ) ) ) { |
| 1556 |
return false; |
| 1557 |
} |
| 1558 |
} |
| 1559 |
|
| 1560 |
return true; |
| 1561 |
} |
| 1562 |
|
| 1563 |
/** |
| 1564 |
* @param array $f |
| 1565 |
* |
| 1566 |
* @return bool |
| 1567 |
*/ |
| 1568 |
public function can_view( $f ) { |
| 1569 |
return wpforo_current_user_is( 'admin' ) || ! ( ! $this->owner() && ! in_array( WPF()->current_user_groupid, (array) $f['canView'] ) ); |
| 1570 |
} |
| 1571 |
|
| 1572 |
/** |
| 1573 |
* @param array $f |
| 1574 |
* |
| 1575 |
* @return bool |
| 1576 |
*/ |
| 1577 |
public function can_edit( $f ) { |
| 1578 |
if( wpfval( WPF()->current_object, 'user', 'userid' ) ) { |
| 1579 |
$is_owner = $this->owner(); |
| 1580 |
$value = wpfkey( $f, 'value' ) ? $f['value'] : false; |
| 1581 |
$can_edit = wpfkey( $f, 'isEditable' ) ? $f['isEditable'] : false; |
| 1582 |
$can_moderate = $this->can_moderate( $f ); |
| 1583 |
if( ! $is_owner && ! $can_moderate && WPF()->current_user_groupid !== 1 ) { |
| 1584 |
return false; |
| 1585 |
} |
| 1586 |
if( ! $can_edit && ! $can_moderate && WPF()->current_user_groupid !== 1 && ! $value ) { |
| 1587 |
return false; |
| 1588 |
} |
| 1589 |
if( wpfkey( $f, 'name' ) ) { |
| 1590 |
if( $f['name'] === 'signature' && ( ! WPF()->usergroup->can( 'ups' ) || ! wpforo_setting( 'profiles', 'signature' ) ) ) { |
| 1591 |
return false; |
| 1592 |
} |
| 1593 |
if( $f['name'] === 'avatar' && ( ! wpforo_setting( 'profiles', 'custom_avatars' ) || ! wpforo_setting( 'profiles', 'avatars' ) ) ) { |
| 1594 |
return false; |
| 1595 |
} |
| 1596 |
if( $f['name'] === 'groupid' && ( WPF()->current_user_groupid != 1 || $is_owner || ! current_user_can( 'administrator' ) ) ) { |
| 1597 |
return false; |
| 1598 |
} |
| 1599 |
} |
| 1600 |
|
| 1601 |
return true; |
| 1602 |
} else { |
| 1603 |
return false; |
| 1604 |
} |
| 1605 |
} |
| 1606 |
|
| 1607 |
/** |
| 1608 |
* @param array $f |
| 1609 |
* |
| 1610 |
* @return bool |
| 1611 |
*/ |
| 1612 |
public function can_moderate( $f ) { |
| 1613 |
if( empty( $f ) ) return false; |
| 1614 |
$usergroups_who_can_edit = ! empty( $f['canEdit'] ) ? (array) $f['canEdit'] : [ 1 ]; |
| 1615 |
|
| 1616 |
return in_array( WPF()->current_user_groupid, $usergroups_who_can_edit ); |
| 1617 |
} |
| 1618 |
|
| 1619 |
public function can_show_value( $f ) { |
| 1620 |
$return = true; |
| 1621 |
if( is_string( $f ) ) $f = WPF()->member->get_field( $f ); |
| 1622 |
$f = wpforo_parse_args( $f, $this->default ); |
| 1623 |
if( $f['type'] === 'password' ) $return = false; |
| 1624 |
|
| 1625 |
return apply_filters( 'wpforo_form_can_show_value', $return, $f ); |
| 1626 |
} |
| 1627 |
} |
| 1628 |
|