| @@ -3,27 +3,43 @@ | ||
| 3 | 3 | die( 'You are not allowed to call this page directly.' ); |
| 4 | 4 | } |
| 5 | 5 | |
| 6 | 6 | class FrmAppHelper { |
| 7 | - public static $db_version = 98; // Version of the database we are moving to. | |
| 8 | - public static $pro_db_version = 37; //deprecated | |
| 9 | - public static $font_version = 7; | |
| 10 | 7 | |
| 11 | 8 | /** |
| 12 | - * @var bool $added_gmt_offset_filter | |
| 9 | + * Version of the database we are moving to. | |
| 10 | + * | |
| 11 | + * @var int | |
| 13 | 12 | */ |
| 13 | + public static $db_version = 103; | |
| 14 | + | |
| 15 | + /** | |
| 16 | + * Used by the API add-on. | |
| 17 | + * | |
| 18 | + * @var float | |
| 19 | + */ | |
| 20 | + public static $font_version = 7; | |
| 21 | + | |
| 22 | + /** | |
| 23 | + * @var bool | |
| 24 | + */ | |
| 14 | 25 | private static $added_gmt_offset_filter = false; |
| 15 | 26 | |
| 16 | 27 | /** |
| 17 | 28 | * @since 2.0 |
| 29 | + * | |
| 30 | + * @var string | |
| 18 | 31 | */ |
| 19 | - public static $plug_version = '6.5'; | |
| 32 | + public static $plug_version = '6.21'; | |
| 20 | 33 | |
| 21 | 34 | /** |
| 35 | + * @var bool | |
| 36 | + */ | |
| 37 | + private static $included_svg = false; | |
| 38 | + | |
| 39 | + /** | |
| 22 | 40 | * @since 1.07.02 |
| 23 | 41 | * |
| 24 | - * @param none | |
| 25 | - * | |
| 26 | 42 | * @return string The version of this plugin |
| 27 | 43 | */ |
| 28 | 44 | public static function plugin_version() { |
| 29 | 45 | return self::$plug_version; |
| @@ -28,21 +44,33 @@ | ||
| 28 | 44 | public static function plugin_version() { |
| 29 | 45 | return self::$plug_version; |
| 30 | 46 | } |
| 31 | 47 | |
| 48 | + /** | |
| 49 | + * @return string | |
| 50 | + */ | |
| 32 | 51 | public static function plugin_folder() { |
| 33 | 52 | return basename( self::plugin_path() ); |
| 34 | 53 | } |
| 35 | 54 | |
| 55 | + /** | |
| 56 | + * @return string | |
| 57 | + */ | |
| 36 | 58 | public static function plugin_path() { |
| 37 | - return dirname( dirname( dirname( __FILE__ ) ) ); | |
| 59 | + return dirname( dirname( __DIR__ ) ); | |
| 38 | 60 | } |
| 39 | 61 | |
| 62 | + /** | |
| 63 | + * @return string | |
| 64 | + */ | |
| 40 | 65 | public static function plugin_url() { |
| 41 | - // Prevously FRM_URL constant. | |
| 66 | + // Previously FRM_URL constant. | |
| 42 | 67 | return plugins_url( '', self::plugin_path() . '/formidable.php' ); |
| 43 | 68 | } |
| 44 | 69 | |
| 70 | + /** | |
| 71 | + * @return string | |
| 72 | + */ | |
| 45 | 73 | public static function relative_plugin_url() { |
| 46 | 74 | return str_replace( array( 'https:', 'http:' ), '', self::plugin_url() ); |
| 47 | 75 | } |
| 48 | 76 | |
| @@ -63,8 +91,12 @@ | ||
| 63 | 91 | public static function site_name() { |
| 64 | 92 | return get_option( 'blogname' ); |
| 65 | 93 | } |
| 66 | 94 | |
| 95 | + /** | |
| 96 | + * @param string $url | |
| 97 | + * @return string | |
| 98 | + */ | |
| 67 | 99 | public static function make_affiliate_url( $url ) { |
| 68 | 100 | $affiliate_id = self::get_affiliate(); |
| 69 | 101 | if ( ! empty( $affiliate_id ) ) { |
| 70 | 102 | $url = str_replace( array( 'http://', 'https://' ), '', $url ); |
| @@ -73,8 +105,11 @@ | ||
| 73 | 105 | |
| 74 | 106 | return $url; |
| 75 | 107 | } |
| 76 | 108 | |
| 109 | + /** | |
| 110 | + * @return int | |
| 111 | + */ | |
| 77 | 112 | public static function get_affiliate() { |
| 78 | 113 | return absint( apply_filters( 'frm_affiliate_id', 0 ) ); |
| 79 | 114 | } |
| 80 | 115 | |
| @@ -92,9 +127,9 @@ | ||
| 92 | 127 | } |
| 93 | 128 | |
| 94 | 129 | $anchor = ''; |
| 95 | 130 | if ( is_array( $args ) ) { |
| 96 | - $medium = $args['medium']; | |
| 131 | + $medium = isset( $args['medium'] ) ? $args['medium'] : ''; | |
| 97 | 132 | if ( isset( $args['content'] ) ) { |
| 98 | 133 | $content = $args['content']; |
| 99 | 134 | } |
| 100 | 135 | if ( isset( $args['anchor'] ) ) { |
| @@ -126,14 +161,42 @@ | ||
| 126 | 161 | return self::make_affiliate_url( $link ); |
| 127 | 162 | } |
| 128 | 163 | |
| 129 | 164 | /** |
| 165 | + * @since 6.21 | |
| 166 | + * | |
| 167 | + * @param string $cta_link | |
| 168 | + * @param array $utm | |
| 169 | + */ | |
| 170 | + public static function maybe_add_missing_utm( $cta_link, $utm ) { | |
| 171 | + $query_args = array(); | |
| 172 | + | |
| 173 | + if ( false === strpos( $cta_link, 'utm_source' ) ) { | |
| 174 | + $query_args['utm_source'] = 'WordPress'; | |
| 175 | + } | |
| 176 | + | |
| 177 | + if ( false === strpos( $cta_link, 'utm_campaign' ) ) { | |
| 178 | + $query_args['utm_campaign'] = 'liteplugin'; | |
| 179 | + } | |
| 180 | + | |
| 181 | + if ( false === strpos( $cta_link, 'utm_medium' ) && isset( $utm['medium'] ) ) { | |
| 182 | + $query_args['utm_medium'] = $utm['medium']; | |
| 183 | + } | |
| 184 | + | |
| 185 | + if ( false === strpos( $cta_link, 'utm_content' ) && isset( $utm['content'] ) ) { | |
| 186 | + $query_args['utm_content'] = $utm['content']; | |
| 187 | + } | |
| 188 | + | |
| 189 | + return $query_args ? add_query_arg( $query_args, $cta_link ) : $cta_link; | |
| 190 | + } | |
| 191 | + | |
| 192 | + /** | |
| 130 | 193 | * Get the Formidable settings |
| 131 | 194 | * |
| 132 | 195 | * @since 2.0 |
| 133 | 196 | * |
| 134 | 197 | * @param array $args - May include the form id when values need translation. |
| 135 | - * @return FrmSettings $frm_setings | |
| 198 | + * @return FrmSettings $frm_settings | |
| 136 | 199 | */ |
| 137 | 200 | public static function get_settings( $args = array() ) { |
| 138 | 201 | global $frm_settings; |
| 139 | 202 | if ( empty( $frm_settings ) ) { |
| @@ -145,32 +208,39 @@ | ||
| 145 | 208 | |
| 146 | 209 | return $frm_settings; |
| 147 | 210 | } |
| 148 | 211 | |
| 212 | + /** | |
| 213 | + * @return string | |
| 214 | + */ | |
| 149 | 215 | public static function get_menu_name() { |
| 150 | 216 | $frm_settings = self::get_settings(); |
| 151 | 217 | |
| 152 | - return $frm_settings->menu; | |
| 218 | + return FrmAddonsController::is_license_expired() ? 'Formidable' : $frm_settings->menu; | |
| 153 | 219 | } |
| 154 | 220 | |
| 155 | 221 | /** |
| 156 | 222 | * Determine if the current branding is set to 'formidable'. |
| 223 | + * Checks the menu icon, and verifies if it matches the formidable branding. | |
| 157 | 224 | * |
| 158 | - * Checks the menu title, retrieved through get_menu_name, | |
| 159 | - * and verifies if it matches the 'formidable' branding. | |
| 160 | - * | |
| 161 | 225 | * @since 6.4.2 |
| 162 | 226 | * |
| 163 | - * @return bool True if the menu title is 'formidable', false otherwise. | |
| 227 | + * @return bool True if the menu icon is the logo, false otherwise. | |
| 164 | 228 | */ |
| 165 | 229 | public static function is_formidable_branding() { |
| 166 | - $menu_title = self::get_menu_name(); | |
| 230 | + if ( ! self::pro_is_installed() ) { | |
| 231 | + return true; | |
| 232 | + } | |
| 167 | 233 | |
| 168 | - return 'formidable' === strtolower( trim( $menu_title ) ); | |
| 234 | + $menu_icon = self::get_menu_icon_class(); | |
| 235 | + return strpos( $menu_icon, 'frm_logo_icon' ) !== false; | |
| 169 | 236 | } |
| 170 | 237 | |
| 171 | 238 | /** |
| 172 | 239 | * @since 3.05 |
| 240 | + * | |
| 241 | + * @param array $atts | |
| 242 | + * @return string | |
| 173 | 243 | */ |
| 174 | 244 | public static function svg_logo( $atts = array() ) { |
| 175 | 245 | $defaults = array( |
| 176 | 246 | 'height' => 18, |
| @@ -187,8 +257,11 @@ | ||
| 187 | 257 | } |
| 188 | 258 | |
| 189 | 259 | /** |
| 190 | 260 | * @since 4.0 |
| 261 | + * | |
| 262 | + * @param array $atts | |
| 263 | + * @return void | |
| 191 | 264 | */ |
| 192 | 265 | public static function show_logo( $atts = array() ) { |
| 193 | 266 | echo self::kses( self::svg_logo( $atts ), 'all' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 194 | 267 | } |
| @@ -194,8 +267,10 @@ | ||
| 194 | 267 | } |
| 195 | 268 | |
| 196 | 269 | /** |
| 197 | 270 | * @since 4.03.02 |
| 271 | + * | |
| 272 | + * @return void | |
| 198 | 273 | */ |
| 199 | 274 | public static function show_header_logo() { |
| 200 | 275 | $icon = self::svg_logo( |
| 201 | 276 | array( |
| @@ -217,21 +292,38 @@ | ||
| 217 | 292 | } |
| 218 | 293 | |
| 219 | 294 | /** |
| 220 | 295 | * @since 2.02.04 |
| 296 | + * | |
| 297 | + * @return bool | |
| 221 | 298 | */ |
| 222 | 299 | public static function ips_saved() { |
| 223 | 300 | $frm_settings = self::get_settings(); |
| 224 | - | |
| 225 | 301 | return ! $frm_settings->no_ips; |
| 226 | 302 | } |
| 227 | 303 | |
| 304 | + /** | |
| 305 | + * @return bool | |
| 306 | + */ | |
| 228 | 307 | public static function pro_is_installed() { |
| 229 | - return apply_filters( 'frm_pro_installed', false ); | |
| 308 | + return (bool) apply_filters( 'frm_pro_installed', false ); | |
| 230 | 309 | } |
| 231 | 310 | |
| 232 | 311 | /** |
| 312 | + * Check if the Pro plugin is installed, whether authorized or not. | |
| 313 | + * | |
| 314 | + * @since 6.8.3 | |
| 315 | + * | |
| 316 | + * @return bool | |
| 317 | + */ | |
| 318 | + public static function pro_is_included() { | |
| 319 | + return function_exists( 'load_formidable_pro' ); | |
| 320 | + } | |
| 321 | + | |
| 322 | + /** | |
| 233 | 323 | * @since 4.06.02 |
| 324 | + * | |
| 325 | + * @return bool | |
| 234 | 326 | */ |
| 235 | 327 | public static function pro_is_connected() { |
| 236 | 328 | global $frm_vars; |
| 237 | 329 | return self::pro_is_installed() && $frm_vars['pro_is_authorized']; |
| @@ -238,14 +330,26 @@ | ||
| 238 | 330 | } |
| 239 | 331 | |
| 240 | 332 | /** |
| 241 | 333 | * @since 4.06 |
| 334 | + * @since 6.16.2 Added $check_for_settings parameter | |
| 335 | + * | |
| 336 | + * @param bool $check_for_settings | |
| 337 | + * | |
| 338 | + * @return bool | |
| 242 | 339 | */ |
| 243 | - public static function is_form_builder_page() { | |
| 244 | - $action = self::simple_get( 'frm_action', 'sanitize_title' ); | |
| 245 | - return self::is_admin_page( 'formidable' ) && ( $action === 'edit' || $action === 'settings' || $action === 'duplicate' ); | |
| 340 | + public static function is_form_builder_page( $check_for_settings = true ) { | |
| 341 | + $action = self::simple_get( 'frm_action', 'sanitize_title' ); | |
| 342 | + $check_actions = array( 'edit', 'duplicate' ); | |
| 343 | + if ( $check_for_settings ) { | |
| 344 | + $check_actions[] = 'settings'; | |
| 345 | + } | |
| 346 | + return self::is_admin_page( 'formidable' ) && in_array( $action, $check_actions, true ); | |
| 246 | 347 | } |
| 247 | 348 | |
| 349 | + /** | |
| 350 | + * @return bool | |
| 351 | + */ | |
| 248 | 352 | public static function is_formidable_admin() { |
| 249 | 353 | $page = self::simple_get( 'page', 'sanitize_title' ); |
| 250 | 354 | $is_formidable = strpos( $page, 'formidable' ) !== false; |
| 251 | 355 | if ( empty( $page ) ) { |
| @@ -255,15 +359,52 @@ | ||
| 255 | 359 | return $is_formidable; |
| 256 | 360 | } |
| 257 | 361 | |
| 258 | 362 | /** |
| 363 | + * Checks if is a list page. | |
| 364 | + * | |
| 365 | + * @since 6.19 | |
| 366 | + * | |
| 367 | + * @param string $page The name of the page to check. | |
| 368 | + * @return bool | |
| 369 | + */ | |
| 370 | + public static function is_admin_list_page( $page = 'formidable' ) { | |
| 371 | + if ( 'formidable' === $page ) { | |
| 372 | + return self::on_form_listing_page(); | |
| 373 | + } | |
| 374 | + | |
| 375 | + if ( ! self::is_admin_page( $page ) ) { | |
| 376 | + return false; | |
| 377 | + } | |
| 378 | + | |
| 379 | + if ( 'formidable-entries' === $page ) { | |
| 380 | + $action = self::simple_get( 'frm_action' ); | |
| 381 | + if ( ! $action || in_array( $action, self::get_entries_listing_page_form_actions(), true ) ) { | |
| 382 | + return true; | |
| 383 | + } | |
| 384 | + } | |
| 385 | + | |
| 386 | + // Check edit or settings page. | |
| 387 | + return ! self::simple_get( 'frm_action' ); | |
| 388 | + } | |
| 389 | + | |
| 390 | + /** | |
| 391 | + * @since 6.20 | |
| 392 | + * | |
| 393 | + * @return array<string> | |
| 394 | + */ | |
| 395 | + private static function get_entries_listing_page_form_actions() { | |
| 396 | + return array( 'list', 'destroy' ); | |
| 397 | + } | |
| 398 | + | |
| 399 | + /** | |
| 259 | 400 | * Check for certain page in Formidable settings |
| 260 | 401 | * |
| 261 | 402 | * @since 2.0 |
| 262 | 403 | * |
| 263 | - * @param string $page The name of the page to check | |
| 404 | + * @param string $page The name of the page to check. | |
| 264 | 405 | * |
| 265 | - * @return boolean | |
| 406 | + * @return bool | |
| 266 | 407 | */ |
| 267 | 408 | public static function is_admin_page( $page = 'formidable' ) { |
| 268 | 409 | global $pagenow; |
| 269 | 410 | $get_page = self::simple_get( 'page', 'sanitize_title' ); |
| @@ -282,8 +423,10 @@ | ||
| 282 | 423 | * If the current page is for editing or creating a view. |
| 283 | 424 | * Returns false for the views listing page. |
| 284 | 425 | * |
| 285 | 426 | * @since 4.0 |
| 427 | + * | |
| 428 | + * @return bool | |
| 286 | 429 | */ |
| 287 | 430 | public static function is_view_builder_page() { |
| 288 | 431 | global $pagenow; |
| 289 | 432 | |
| @@ -293,10 +436,10 @@ | ||
| 293 | 436 | |
| 294 | 437 | $post_type = self::simple_get( 'post_type', 'sanitize_title' ); |
| 295 | 438 | |
| 296 | 439 | if ( empty( $post_type ) ) { |
| 297 | - $post_id = self::simple_get( 'post', 'absint' ); | |
| 298 | - $post = get_post( $post_id ); | |
| 440 | + $post_id = self::simple_get( 'post', 'absint' ); | |
| 441 | + $post = get_post( $post_id ); | |
| 299 | 442 | $post_type = $post ? $post->post_type : ''; |
| 300 | 443 | } |
| 301 | 444 | |
| 302 | 445 | return $post_type === 'frm_display'; |
| @@ -306,17 +449,15 @@ | ||
| 306 | 449 | * Check for the form preview page |
| 307 | 450 | * |
| 308 | 451 | * @since 2.0 |
| 309 | 452 | * |
| 310 | - * @param None | |
| 311 | - * | |
| 312 | - * @return boolean | |
| 453 | + * @return bool | |
| 313 | 454 | */ |
| 314 | 455 | public static function is_preview_page() { |
| 315 | 456 | global $pagenow; |
| 316 | 457 | $action = self::simple_get( 'action', 'sanitize_title' ); |
| 317 | 458 | |
| 318 | - return $pagenow && $pagenow == 'admin-ajax.php' && $action == 'frm_forms_preview'; | |
| 459 | + return $pagenow && $pagenow === 'admin-ajax.php' && $action === 'frm_forms_preview'; | |
| 319 | 460 | } |
| 320 | 461 | |
| 321 | 462 | /** |
| 322 | 463 | * Check for ajax except the form preview page |
| @@ -322,16 +463,17 @@ | ||
| 322 | 463 | * Check for ajax except the form preview page |
| 323 | 464 | * |
| 324 | 465 | * @since 2.0 |
| 325 | 466 | * |
| 326 | - * @param None | |
| 327 | - * | |
| 328 | - * @return boolean | |
| 467 | + * @return bool | |
| 329 | 468 | */ |
| 330 | 469 | public static function doing_ajax() { |
| 331 | 470 | return wp_doing_ajax() && ! self::is_preview_page(); |
| 332 | 471 | } |
| 333 | 472 | |
| 473 | + /** | |
| 474 | + * @return string | |
| 475 | + */ | |
| 334 | 476 | public static function js_suffix() { |
| 335 | 477 | return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; |
| 336 | 478 | } |
| 337 | 479 | |
| @@ -336,13 +478,13 @@ | ||
| 336 | 478 | } |
| 337 | 479 | |
| 338 | 480 | /** |
| 339 | 481 | * @since 2.0.8 |
| 482 | + * @return bool | |
| 340 | 483 | */ |
| 341 | 484 | public static function prevent_caching() { |
| 342 | 485 | global $frm_vars; |
| 343 | - | |
| 344 | - return isset( $frm_vars['prevent_caching'] ) && $frm_vars['prevent_caching']; | |
| 486 | + return ! empty( $frm_vars['prevent_caching'] ); | |
| 345 | 487 | } |
| 346 | 488 | |
| 347 | 489 | /** |
| 348 | 490 | * Check if on an admin page |
| @@ -348,9 +490,9 @@ | ||
| 348 | 490 | * Check if on an admin page |
| 349 | 491 | * |
| 350 | 492 | * @since 2.0 |
| 351 | 493 | * |
| 352 | - * @return boolean | |
| 494 | + * @return bool | |
| 353 | 495 | */ |
| 354 | 496 | public static function is_admin() { |
| 355 | 497 | $is_admin = is_admin() && ! wp_doing_ajax(); |
| 356 | 498 | |
| @@ -365,17 +507,22 @@ | ||
| 365 | 507 | * Check if value contains blank value or empty array |
| 366 | 508 | * |
| 367 | 509 | * @since 2.0 |
| 368 | 510 | * |
| 369 | - * @param mixed $value - value to check | |
| 370 | - * @param string | |
| 511 | + * @param mixed $value Value to check. | |
| 512 | + * @param string $empty | |
| 371 | 513 | * |
| 372 | - * @return boolean | |
| 514 | + * @return bool | |
| 373 | 515 | */ |
| 374 | 516 | public static function is_empty_value( $value, $empty = '' ) { |
| 375 | 517 | return ( is_array( $value ) && empty( $value ) ) || $value === $empty; |
| 376 | 518 | } |
| 377 | 519 | |
| 520 | + /** | |
| 521 | + * @param mixed $value | |
| 522 | + * @param string $empty | |
| 523 | + * @return bool | |
| 524 | + */ | |
| 378 | 525 | public static function is_not_empty_value( $value, $empty = '' ) { |
| 379 | 526 | return ! self::is_empty_value( $value, $empty ); |
| 380 | 527 | } |
| 381 | 528 | |
| @@ -394,14 +541,13 @@ | ||
| 394 | 541 | |
| 395 | 542 | /** |
| 396 | 543 | * Get the server OS |
| 397 | 544 | * |
| 398 | - * @since 6.4.x | |
| 545 | + * @since 6.4.2 | |
| 399 | 546 | * |
| 400 | 547 | * @return string |
| 401 | 548 | */ |
| 402 | 549 | public static function get_server_os() { |
| 403 | - | |
| 404 | 550 | if ( function_exists( 'php_uname' ) ) { |
| 405 | 551 | return php_uname( 's' ); |
| 406 | 552 | } |
| 407 | 553 | |
| @@ -429,9 +575,10 @@ | ||
| 429 | 575 | } |
| 430 | 576 | |
| 431 | 577 | $key = self::get_server_value( $key ); |
| 432 | 578 | foreach ( explode( ',', $key ) as $ip ) { |
| 433 | - $ip = trim( $ip ); // Just to be safe. | |
| 579 | + // Just to be safe. | |
| 580 | + $ip = trim( $ip ); | |
| 434 | 581 | |
| 435 | 582 | if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) !== false ) { |
| 436 | 583 | return sanitize_text_field( $ip ); |
| 437 | 584 | } |
| @@ -522,15 +669,24 @@ | ||
| 522 | 669 | |
| 523 | 670 | return $value; |
| 524 | 671 | } |
| 525 | 672 | |
| 673 | + /** | |
| 674 | + * Get a value from $_POST data. | |
| 675 | + * | |
| 676 | + * @param string $param The key we are trying to access data from in $_POST. | |
| 677 | + * @param mixed $default The default if nothing is being sent. | |
| 678 | + * @param callable|string $sanitize Make sure to pass a sanitize method here. This function will NOT sanitize by default. | |
| 679 | + * @param bool $serialized | |
| 680 | + * @return mixed | |
| 681 | + */ | |
| 526 | 682 | public static function get_post_param( $param, $default = '', $sanitize = '', $serialized = false ) { |
| 527 | 683 | return self::get_simple_request( |
| 528 | 684 | array( |
| 529 | - 'type' => 'post', | |
| 530 | - 'param' => $param, | |
| 531 | - 'default' => $default, | |
| 532 | - 'sanitize' => $sanitize, | |
| 685 | + 'type' => 'post', | |
| 686 | + 'param' => $param, | |
| 687 | + 'default' => $default, | |
| 688 | + 'sanitize' => $sanitize, | |
| 533 | 689 | 'serialized' => $serialized, |
| 534 | 690 | ) |
| 535 | 691 | ); |
| 536 | 692 | } |
| @@ -541,9 +697,9 @@ | ||
| 541 | 697 | * @param string $param |
| 542 | 698 | * @param string $sanitize |
| 543 | 699 | * @param string $default |
| 544 | 700 | * |
| 545 | - * @return string|array | |
| 701 | + * @return array|string | |
| 546 | 702 | */ |
| 547 | 703 | public static function simple_get( $param, $sanitize = 'sanitize_text_field', $default = '' ) { |
| 548 | 704 | return self::get_simple_request( |
| 549 | 705 | array( |
| @@ -561,16 +717,16 @@ | ||
| 561 | 717 | * @since 2.0.6 |
| 562 | 718 | * |
| 563 | 719 | * @param array $args |
| 564 | 720 | * |
| 565 | - * @return string|array | |
| 721 | + * @return array|string | |
| 566 | 722 | */ |
| 567 | 723 | public static function get_simple_request( $args ) { |
| 568 | 724 | $defaults = array( |
| 569 | - 'param' => '', | |
| 570 | - 'default' => '', | |
| 571 | - 'type' => 'get', | |
| 572 | - 'sanitize' => 'sanitize_text_field', | |
| 725 | + 'param' => '', | |
| 726 | + 'default' => '', | |
| 727 | + 'type' => 'get', | |
| 728 | + 'sanitize' => 'sanitize_text_field', | |
| 573 | 729 | 'serialized' => false, |
| 574 | 730 | ); |
| 575 | 731 | $args = wp_parse_args( $args, $defaults ); |
| 576 | 732 | |
| @@ -587,13 +743,12 @@ | ||
| 587 | 743 | if ( $args['serialized'] === true && is_serialized_string( $value ) && is_serialized( $value ) ) { |
| 588 | 744 | self::unserialize_or_decode( $value ); |
| 589 | 745 | } |
| 590 | 746 | } |
| 591 | - } else { | |
| 592 | - if ( isset( $_REQUEST[ $args['param'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 747 | + } elseif ( isset( $_REQUEST[ $args['param'] ] ) ) { | |
| 748 | + // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 593 | 749 | // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| 594 | 750 | $value = wp_unslash( $_REQUEST[ $args['param'] ] ); |
| 595 | - } | |
| 596 | 751 | } |
| 597 | 752 | |
| 598 | 753 | self::sanitize_value( $args['sanitize'], $value ); |
| 599 | 754 | |
| @@ -617,19 +772,35 @@ | ||
| 617 | 772 | |
| 618 | 773 | return $value; |
| 619 | 774 | } |
| 620 | 775 | |
| 776 | + /** | |
| 777 | + * Sanitize a value in-place. | |
| 778 | + * If $value is an array, the sanitize function will get called for each item. | |
| 779 | + * | |
| 780 | + * @param callable $sanitize | |
| 781 | + * @param mixed $value | |
| 782 | + * @return void | |
| 783 | + */ | |
| 621 | 784 | public static function sanitize_value( $sanitize, &$value ) { |
| 622 | - if ( ! empty( $sanitize ) ) { | |
| 623 | - if ( is_array( $value ) ) { | |
| 624 | - $temp_values = $value; | |
| 625 | - foreach ( $temp_values as $k => $v ) { | |
| 626 | - self::sanitize_value( $sanitize, $value[ $k ] ); | |
| 627 | - } | |
| 628 | - } else { | |
| 629 | - $value = call_user_func( $sanitize, $value ); | |
| 785 | + if ( ! $sanitize ) { | |
| 786 | + return; | |
| 787 | + } | |
| 788 | + | |
| 789 | + if ( is_object( $value ) ) { | |
| 790 | + $value = ''; | |
| 791 | + return; | |
| 792 | + } | |
| 793 | + | |
| 794 | + if ( is_array( $value ) ) { | |
| 795 | + $temp_values = $value; | |
| 796 | + foreach ( $temp_values as $k => $v ) { | |
| 797 | + self::sanitize_value( $sanitize, $value[ $k ] ); | |
| 630 | 798 | } |
| 799 | + return; | |
| 631 | 800 | } |
| 801 | + | |
| 802 | + $value = call_user_func( $sanitize, $value ); | |
| 632 | 803 | } |
| 633 | 804 | |
| 634 | 805 | public static function sanitize_request( $sanitize_method, &$values ) { |
| 635 | 806 | $temp_values = $values; |
| @@ -641,15 +812,52 @@ | ||
| 641 | 812 | } |
| 642 | 813 | |
| 643 | 814 | /** |
| 644 | 815 | * @since 4.0.04 |
| 816 | + * | |
| 817 | + * @param mixed $value | |
| 818 | + * @return void | |
| 645 | 819 | */ |
| 646 | 820 | public static function sanitize_with_html( &$value ) { |
| 647 | - self::sanitize_value( 'wp_kses_post', $value ); | |
| 821 | + if ( current_user_can( 'frm_edit_entries' ) || current_user_can( 'administrator' ) ) { | |
| 822 | + // Only strip unsafe HTML like scripts for a privileged user submitting a form. | |
| 823 | + self::sanitize_value( 'wp_kses_post', $value ); | |
| 824 | + } else { | |
| 825 | + self::sanitize_value( self::class . '::strip_most_html', $value ); | |
| 826 | + } | |
| 648 | 827 | self::decode_specialchars( $value ); |
| 649 | 828 | } |
| 650 | 829 | |
| 651 | 830 | /** |
| 831 | + * Allow only a small set of very basic HTML for unprivileged users. | |
| 832 | + * | |
| 833 | + * @since 6.7.1 | |
| 834 | + * | |
| 835 | + * @param string $value | |
| 836 | + */ | |
| 837 | + public static function strip_most_html( $value ) { | |
| 838 | + $allowed_html = array( | |
| 839 | + 'b' => array(), | |
| 840 | + 'br' => array(), | |
| 841 | + 'strong' => array(), | |
| 842 | + 'p' => array(), | |
| 843 | + 'i' => array(), | |
| 844 | + 'ul' => array(), | |
| 845 | + 'ol' => array(), | |
| 846 | + 'li' => array(), | |
| 847 | + ); | |
| 848 | + | |
| 849 | + /** | |
| 850 | + * @since 6.7.1 | |
| 851 | + * | |
| 852 | + * @param array $allowed_html | |
| 853 | + */ | |
| 854 | + $allowed_html = apply_filters( 'frm_allowed_form_input_html', $allowed_html ); | |
| 855 | + | |
| 856 | + return wp_kses( $value, $allowed_html ); | |
| 857 | + } | |
| 858 | + | |
| 859 | + /** | |
| 652 | 860 | * Do wp_specialchars_decode to get back '&' that wp_kses_post might have turned to '&' |
| 653 | 861 | * this MUST be done, else we'll be back to the '& entity' problem. |
| 654 | 862 | * |
| 655 | 863 | * @since 4.0.04 |
| @@ -683,10 +891,12 @@ | ||
| 683 | 891 | $translation = array( |
| 684 | 892 | '"' => '"', |
| 685 | 893 | '"' => '"', |
| 686 | 894 | '"' => '"', |
| 687 | - '< ' => '< ', // The space preserves the HTML. | |
| 688 | - '< ' => '< ', // The space preserves the HTML. | |
| 895 | + // The space preserves the HTML. | |
| 896 | + '< ' => '< ', | |
| 897 | + // The space preserves the HTML. | |
| 898 | + '< ' => '< ', | |
| 689 | 899 | '>' => '>', |
| 690 | 900 | '>' => '>', |
| 691 | 901 | '&' => '&', |
| 692 | 902 | '&' => '&', |
| @@ -713,10 +923,10 @@ | ||
| 713 | 923 | * Sanitize the value, and allow some HTML |
| 714 | 924 | * |
| 715 | 925 | * @since 2.0 |
| 716 | 926 | * |
| 717 | - * @param string $value | |
| 718 | - * @param array|string $allowed 'all' for everything included as defaults | |
| 927 | + * @param string $value | |
| 928 | + * @param array|string $allowed 'all' for everything included as defaults. | |
| 719 | 929 | * |
| 720 | 930 | * @return string |
| 721 | 931 | */ |
| 722 | 932 | public static function kses( $value, $allowed = array() ) { |
| @@ -725,8 +935,21 @@ | ||
| 725 | 935 | return wp_kses( $value, $allowed_html ); |
| 726 | 936 | } |
| 727 | 937 | |
| 728 | 938 | /** |
| 939 | + * Sanitizes and echoes a given value. | |
| 940 | + * | |
| 941 | + * @since 6.18 | |
| 942 | + * | |
| 943 | + * @param string $value The value to sanitize and output. | |
| 944 | + * @param array|string $allowed Allowed HTML tags and attributes. | |
| 945 | + * @return void | |
| 946 | + */ | |
| 947 | + public static function kses_echo( $value, $allowed = array() ) { | |
| 948 | + echo self::kses( $value, $allowed ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 949 | + } | |
| 950 | + | |
| 951 | + /** | |
| 729 | 952 | * The regular kses function strips [button_action] from submit button HTML. |
| 730 | 953 | * |
| 731 | 954 | * @since 5.0.13 |
| 732 | 955 | * |
| @@ -817,9 +1040,9 @@ | ||
| 817 | 1040 | 'id' => true, |
| 818 | 1041 | ); |
| 819 | 1042 | |
| 820 | 1043 | return array( |
| 821 | - 'a' => array( | |
| 1044 | + 'a' => array( | |
| 822 | 1045 | 'class' => true, |
| 823 | 1046 | 'href' => true, |
| 824 | 1047 | 'id' => true, |
| 825 | 1048 | 'rel' => true, |
| @@ -888,16 +1111,16 @@ | ||
| 888 | 1111 | 'cite' => true, |
| 889 | 1112 | 'title' => true, |
| 890 | 1113 | ), |
| 891 | 1114 | 'rect' => array( |
| 892 | - 'class' => true, | |
| 893 | - 'fill' => true, | |
| 894 | - 'height' => true, | |
| 895 | - 'width' => true, | |
| 896 | - 'x' => true, | |
| 897 | - 'y' => true, | |
| 898 | - 'rx' => true, | |
| 899 | - 'stroke' => true, | |
| 1115 | + 'class' => true, | |
| 1116 | + 'fill' => true, | |
| 1117 | + 'height' => true, | |
| 1118 | + 'width' => true, | |
| 1119 | + 'x' => true, | |
| 1120 | + 'y' => true, | |
| 1121 | + 'rx' => true, | |
| 1122 | + 'stroke' => true, | |
| 900 | 1123 | 'stroke-opacity' => true, |
| 901 | 1124 | 'stroke-width' => true, |
| 902 | 1125 | ), |
| 903 | 1126 | 'section' => $allow_class, |
| @@ -932,9 +1155,9 @@ | ||
| 932 | 1155 | 'xlink:href' => true, |
| 933 | 1156 | ), |
| 934 | 1157 | 'ul' => $allow_class, |
| 935 | 1158 | 'label' => array( |
| 936 | - 'for' => true, | |
| 1159 | + 'for' => true, | |
| 937 | 1160 | 'class' => true, |
| 938 | 1161 | 'id' => true, |
| 939 | 1162 | ), |
| 940 | 1163 | 'button' => array( |
| @@ -943,8 +1166,13 @@ | ||
| 943 | 1166 | ), |
| 944 | 1167 | 'legend' => array( |
| 945 | 1168 | 'class' => true, |
| 946 | 1169 | ), |
| 1170 | + 'option' => array( | |
| 1171 | + 'class' => true, | |
| 1172 | + 'value' => true, | |
| 1173 | + 'selected' => true, | |
| 1174 | + ), | |
| 947 | 1175 | ); |
| 948 | 1176 | } |
| 949 | 1177 | |
| 950 | 1178 | /** |
| @@ -952,9 +1180,9 @@ | ||
| 952 | 1180 | * |
| 953 | 1181 | * @since 2.0 |
| 954 | 1182 | */ |
| 955 | 1183 | public static function remove_get_action() { |
| 956 | - if ( ! isset( $_GET ) ) { | |
| 1184 | + if ( empty( $_GET ) ) { | |
| 957 | 1185 | return; |
| 958 | 1186 | } |
| 959 | 1187 | |
| 960 | 1188 | $action_name = isset( $_GET['action'] ) ? 'action' : ( isset( $_GET['action2'] ) ? 'action2' : '' ); |
| @@ -971,9 +1199,9 @@ | ||
| 971 | 1199 | /** |
| 972 | 1200 | * Check the WP query for a parameter |
| 973 | 1201 | * |
| 974 | 1202 | * @since 2.0 |
| 975 | - * @return string|array | |
| 1203 | + * @return array|string | |
| 976 | 1204 | */ |
| 977 | 1205 | public static function get_query_var( $value, $param ) { |
| 978 | 1206 | if ( $value != '' ) { |
| 979 | 1207 | return $value; |
| @@ -990,10 +1218,12 @@ | ||
| 990 | 1218 | /** |
| 991 | 1219 | * Try to show the SVG if possible. Otherwise, use the font icon. |
| 992 | 1220 | * |
| 993 | 1221 | * @since 4.0.02 |
| 1222 | + * | |
| 994 | 1223 | * @param string $class |
| 995 | 1224 | * @param array $atts |
| 1225 | + * @return string|null | |
| 996 | 1226 | */ |
| 997 | 1227 | public static function icon_by_class( $class, $atts = array() ) { |
| 998 | 1228 | $echo = ! isset( $atts['echo'] ) || $atts['echo']; |
| 999 | 1229 | if ( isset( $atts['echo'] ) ) { |
| @@ -1003,14 +1233,16 @@ | ||
| 1003 | 1233 | $html_atts = self::array_to_html_params( $atts ); |
| 1004 | 1234 | |
| 1005 | 1235 | $icon = trim( str_replace( array( 'frm_icon_font', 'frmfont ' ), '', $class ) ); |
| 1006 | 1236 | |
| 1007 | - // Replace icons that have been removed. | |
| 1237 | + // Replace icons that have been removed or renamed. | |
| 1008 | 1238 | $deprecated = array( |
| 1009 | - 'frm_clone_solid_icon' => 'frm_clone_icon', | |
| 1239 | + 'frm_clone_solid_icon' => 'frm_clone_icon', | |
| 1240 | + 'frm_keyalt_icon' => 'frm_key_icon', | |
| 1241 | + 'frm_keyalt_solid_icon' => 'frm_key_solid_icon', | |
| 1010 | 1242 | ); |
| 1011 | 1243 | if ( isset( $deprecated[ $icon ] ) ) { |
| 1012 | - $icon = $deprecated[ $icon ]; | |
| 1244 | + $icon = $deprecated[ $icon ]; | |
| 1013 | 1245 | $class = str_replace( $icon, $deprecated[ $icon ], $class ); |
| 1014 | 1246 | } |
| 1015 | 1247 | |
| 1016 | 1248 | if ( $icon === $class ) { |
| @@ -1020,11 +1252,9 @@ | ||
| 1020 | 1252 | if ( strpos( $icon, ' ' ) ) { |
| 1021 | 1253 | $icon = explode( ' ', $icon ); |
| 1022 | 1254 | $icon = reset( $icon ); |
| 1023 | 1255 | } |
| 1024 | - $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '> | |
| 1025 | - <use xlink:href="#' . esc_attr( $icon ) . '" /> | |
| 1026 | - </svg>'; | |
| 1256 | + $icon = '<svg class="frmsvg' . esc_attr( $class ) . '"' . $html_atts . '><use xlink:href="#' . esc_attr( $icon ) . '" /></svg>'; | |
| 1027 | 1257 | } |
| 1028 | 1258 | |
| 1029 | 1259 | if ( $echo ) { |
| 1030 | 1260 | echo self::kses_icon( $icon ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| @@ -1110,11 +1340,18 @@ | ||
| 1110 | 1340 | /** |
| 1111 | 1341 | * Include svg images. |
| 1112 | 1342 | * |
| 1113 | 1343 | * @since 4.0.02 |
| 1344 | + * @return void | |
| 1114 | 1345 | */ |
| 1115 | 1346 | public static function include_svg() { |
| 1116 | - include_once self::plugin_path() . '/images/icons.svg'; | |
| 1347 | + if ( self::$included_svg ) { | |
| 1348 | + return; | |
| 1349 | + } | |
| 1350 | + | |
| 1351 | + // Use readfile instead of include_once because of a default security rule in Snuffleupagus. | |
| 1352 | + readfile( self::plugin_path() . '/images/icons.svg' ); | |
| 1353 | + self::$included_svg = true; | |
| 1117 | 1354 | } |
| 1118 | 1355 | |
| 1119 | 1356 | /** |
| 1120 | 1357 | * Convert an associative array to HTML values. |
| @@ -1126,9 +1363,9 @@ | ||
| 1126 | 1363 | * @param bool $echo |
| 1127 | 1364 | * @return string|void |
| 1128 | 1365 | */ |
| 1129 | 1366 | public static function array_to_html_params( $atts, $echo = false ) { |
| 1130 | - $callback = function() use ( $atts ) { | |
| 1367 | + $callback = function () use ( $atts ) { | |
| 1131 | 1368 | if ( $atts ) { |
| 1132 | 1369 | foreach ( $atts as $key => $value ) { |
| 1133 | 1370 | echo ' ' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"'; |
| 1134 | 1371 | } |
| @@ -1143,9 +1380,9 @@ | ||
| 1143 | 1380 | * @since 5.0.13 |
| 1144 | 1381 | * |
| 1145 | 1382 | * @param Closure $echo_function |
| 1146 | 1383 | * @param bool $echo |
| 1147 | - * @return string|void | |
| 1384 | + * @return string|null | |
| 1148 | 1385 | */ |
| 1149 | 1386 | public static function clip( $echo_function, $echo = false ) { |
| 1150 | 1387 | if ( ! $echo ) { |
| 1151 | 1388 | ob_start(); |
| @@ -1163,12 +1400,15 @@ | ||
| 1163 | 1400 | } |
| 1164 | 1401 | |
| 1165 | 1402 | /** |
| 1166 | 1403 | * @since 3.0 |
| 1404 | + * | |
| 1405 | + * @param array $atts | |
| 1406 | + * @return void | |
| 1167 | 1407 | */ |
| 1168 | 1408 | public static function get_admin_header( $atts ) { |
| 1169 | - $has_nav = ( isset( $atts['form'] ) && ! empty( $atts['form'] ) && ( ! isset( $atts['is_template'] ) || ! $atts['is_template'] ) ); | |
| 1170 | - if ( ! isset( $atts['close'] ) || empty( $atts['close'] ) ) { | |
| 1409 | + $has_nav = ! empty( $atts['form'] ) && empty( $atts['is_template'] ); | |
| 1410 | + if ( empty( $atts['close'] ) ) { | |
| 1171 | 1411 | $atts['close'] = admin_url( 'admin.php?page=formidable' ); |
| 1172 | 1412 | } |
| 1173 | 1413 | if ( ! isset( $atts['import_link'] ) ) { |
| 1174 | 1414 | $atts['import_link'] = false; |
| @@ -1173,9 +1413,9 @@ | ||
| 1173 | 1413 | if ( ! isset( $atts['import_link'] ) ) { |
| 1174 | 1414 | $atts['import_link'] = false; |
| 1175 | 1415 | } |
| 1176 | 1416 | |
| 1177 | - include( self::plugin_path() . '/classes/views/shared/admin-header.php' ); | |
| 1417 | + include self::plugin_path() . '/classes/views/shared/admin-header.php'; | |
| 1178 | 1418 | } |
| 1179 | 1419 | |
| 1180 | 1420 | /** |
| 1181 | 1421 | * @since 6.0 |
| @@ -1204,9 +1444,9 @@ | ||
| 1204 | 1444 | FrmInbox::maybe_show_banner(); |
| 1205 | 1445 | return; |
| 1206 | 1446 | } |
| 1207 | 1447 | |
| 1208 | - if ( self::maybe_show_license_warning() || FrmInbox::maybe_show_banner() || ! $should_show_lite_upgrade || self::pro_is_installed() ) { | |
| 1448 | + if ( FrmSalesApi::maybe_show_banner() || self::maybe_show_license_warning() || FrmInbox::maybe_show_banner() || ! $should_show_lite_upgrade || self::pro_is_installed() ) { | |
| 1209 | 1449 | // Print license warning or inbox banner and exit if either prints. |
| 1210 | 1450 | // And exit before printing the upgrade bar if it shouldn't be shown. |
| 1211 | 1451 | return; |
| 1212 | 1452 | } |
| @@ -1211,10 +1451,36 @@ | ||
| 1211 | 1451 | return; |
| 1212 | 1452 | } |
| 1213 | 1453 | ?> |
| 1214 | 1454 | <div class="frm-upgrade-bar"> |
| 1215 | - <span>You're using Formidable Forms Lite. To unlock more features consider</span> | |
| 1216 | - <a href="<?php echo esc_url( self::admin_upgrade_link( 'top-bar' ) ); ?>" target="_blank" rel="noopener">upgrading to Pro</a>. | |
| 1455 | + <div class="frm-upgrade-bar-inner"> | |
| 1456 | + <?php | |
| 1457 | + $cta_text = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_text' ); | |
| 1458 | + if ( ! $cta_text ) { | |
| 1459 | + $cta_text = __( 'upgrading to PRO', 'formidable' ); | |
| 1460 | + } | |
| 1461 | + | |
| 1462 | + $upgrade_link = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_link' ); | |
| 1463 | + $utm = array( | |
| 1464 | + 'medium' => 'settings-license', | |
| 1465 | + 'content' => 'lite-banner', | |
| 1466 | + ); | |
| 1467 | + | |
| 1468 | + if ( $upgrade_link ) { | |
| 1469 | + $upgrade_link = self::maybe_add_missing_utm( $upgrade_link, $utm ); | |
| 1470 | + } else { | |
| 1471 | + $upgrade_link = self::admin_upgrade_link( $utm ); | |
| 1472 | + } | |
| 1473 | + | |
| 1474 | + printf( | |
| 1475 | + /* translators: %1$s: Start link HTML, %2$s: CTA text ("upgrading to PRO" by default), %3$s: End link HTML */ | |
| 1476 | + esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$s%2$s%3$s.', 'formidable' ), | |
| 1477 | + '<a href="' . esc_url( $upgrade_link ) . '">', | |
| 1478 | + esc_html( $cta_text ), | |
| 1479 | + '</a>' | |
| 1480 | + ); | |
| 1481 | + ?> | |
| 1482 | + </div> | |
| 1217 | 1483 | </div> |
| 1218 | 1484 | <?php |
| 1219 | 1485 | } |
| 1220 | 1486 | |
| @@ -1231,8 +1497,10 @@ | ||
| 1231 | 1497 | * Render a button for a new item (Form, Application, etc). |
| 1232 | 1498 | * |
| 1233 | 1499 | * @since 3.0 |
| 1234 | 1500 | * @param array $atts { |
| 1501 | + * Details about the button. | |
| 1502 | + * | |
| 1235 | 1503 | * @type array $link_hook Custom link hook, calls do_action and exits early. |
| 1236 | 1504 | * @type string $new_link Href value, default #. |
| 1237 | 1505 | * @type string $class Custom class names, space separated. |
| 1238 | 1506 | * @type string $button_text Button text. Default "Add New". |
| @@ -1244,9 +1512,9 @@ | ||
| 1244 | 1512 | do_action( $atts['link_hook']['hook'], $atts['link_hook']['param'] ); |
| 1245 | 1513 | return; |
| 1246 | 1514 | } |
| 1247 | 1515 | |
| 1248 | - if ( empty( $atts['new_link'] ) && empty( $atts['trigger_new_form_modal'] ) && empty( $atts['class'] ) ) { | |
| 1516 | + if ( empty( $atts['new_link'] ) && empty( $atts['create_form'] ) && empty( $atts['class'] ) ) { | |
| 1249 | 1517 | // Do not render a button if none of these attributes are set. |
| 1250 | 1518 | return; |
| 1251 | 1519 | } |
| 1252 | 1520 | |
| @@ -1252,12 +1520,8 @@ | ||
| 1252 | 1520 | |
| 1253 | 1521 | $href = ! empty( $atts['new_link'] ) ? esc_url( $atts['new_link'] ) : '#'; |
| 1254 | 1522 | $class = 'button button-primary frm-button-primary'; |
| 1255 | 1523 | |
| 1256 | - if ( ! empty( $atts['trigger_new_form_modal'] ) ) { | |
| 1257 | - $class .= ' frm-trigger-new-form-modal'; | |
| 1258 | - } | |
| 1259 | - | |
| 1260 | 1524 | if ( ! empty( $atts['class'] ) ) { |
| 1261 | 1525 | $class .= ' ' . $atts['class']; |
| 1262 | 1526 | } |
| 1263 | 1527 | |
| @@ -1274,10 +1538,11 @@ | ||
| 1274 | 1538 | 'placeholder' => '', |
| 1275 | 1539 | 'tosearch' => '', |
| 1276 | 1540 | 'text' => __( 'Search', 'formidable' ), |
| 1277 | 1541 | 'input_id' => '', |
| 1542 | + 'value' => false, | |
| 1278 | 1543 | ); |
| 1279 | - $atts = array_merge( $defaults, $atts ); | |
| 1544 | + $atts = array_merge( $defaults, $atts ); | |
| 1280 | 1545 | |
| 1281 | 1546 | if ( $atts['input_id'] === 'template' && empty( $atts['tosearch'] ) ) { |
| 1282 | 1547 | $atts['tosearch'] = 'frm-card'; |
| 1283 | 1548 | } |
| @@ -1288,8 +1553,27 @@ | ||
| 1288 | 1553 | } |
| 1289 | 1554 | |
| 1290 | 1555 | $input_id = $atts['input_id'] . '-search-input'; |
| 1291 | 1556 | |
| 1557 | + $input_atts = array( | |
| 1558 | + 'type' => 'search', | |
| 1559 | + 'id' => $input_id, | |
| 1560 | + 'name' => 's', | |
| 1561 | + 'placeholder' => $atts['placeholder'], | |
| 1562 | + 'class' => $class, | |
| 1563 | + 'data-tosearch' => $atts['tosearch'], | |
| 1564 | + ); | |
| 1565 | + | |
| 1566 | + if ( is_string( $atts['value'] ) ) { | |
| 1567 | + $input_atts['value'] = $atts['value']; | |
| 1568 | + } elseif ( isset( $_REQUEST['s'] ) ) { | |
| 1569 | + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 1570 | + $input_atts['value'] = wp_unslash( $_REQUEST['s'] ); | |
| 1571 | + } | |
| 1572 | + | |
| 1573 | + if ( ! empty( $atts['tosearch'] ) ) { | |
| 1574 | + $input_atts['autocomplete'] = 'off'; | |
| 1575 | + } | |
| 1292 | 1576 | ?> |
| 1293 | 1577 | <p class="frm-search"> |
| 1294 | 1578 | <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"> |
| 1295 | 1579 | <?php echo esc_html( $atts['text'] ); ?>: |
| @@ -1294,15 +1578,9 @@ | ||
| 1294 | 1578 | <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"> |
| 1295 | 1579 | <?php echo esc_html( $atts['text'] ); ?>: |
| 1296 | 1580 | </label> |
| 1297 | 1581 | <span class="frmfont frm_search_icon"></span> |
| 1298 | - <input type="search" id="<?php echo esc_attr( $input_id ); ?>" name="s" | |
| 1299 | - value="<?php _admin_search_query(); ?>" placeholder="<?php echo esc_attr( $atts['placeholder'] ); ?>" | |
| 1300 | - class="<?php echo esc_attr( $class ); ?>" data-tosearch="<?php echo esc_attr( $atts['tosearch'] ); ?>" | |
| 1301 | - <?php if ( ! empty( $atts['tosearch'] ) ) { ?> | |
| 1302 | - autocomplete="off" | |
| 1303 | - <?php } ?> | |
| 1304 | - /> | |
| 1582 | + <input <?php self::array_to_html_params( $input_atts, true ); ?> /> | |
| 1305 | 1583 | <?php |
| 1306 | 1584 | if ( empty( $atts['tosearch'] ) ) { |
| 1307 | 1585 | submit_button( $atts['text'], 'button-secondary', '', false, array( 'id' => 'search-submit' ) ); |
| 1308 | 1586 | } |
| @@ -1312,8 +1590,9 @@ | ||
| 1312 | 1590 | } |
| 1313 | 1591 | |
| 1314 | 1592 | /** |
| 1315 | 1593 | * @param string $type |
| 1594 | + * @return void | |
| 1316 | 1595 | */ |
| 1317 | 1596 | public static function trigger_hook_load( $type, $object = null ) { |
| 1318 | 1597 | // Only load the form hooks once. |
| 1319 | 1598 | $hooks_loaded = apply_filters( 'frm_' . $type . '_hooks_loaded', false, $object ); |
| @@ -1357,9 +1636,9 @@ | ||
| 1357 | 1636 | 'new_file_path' => self::plugin_path() . '/js', |
| 1358 | 1637 | ) |
| 1359 | 1638 | ); |
| 1360 | 1639 | $new_file = new FrmCreateFile( $file_atts ); |
| 1361 | - $files = array( | |
| 1640 | + $files = array( | |
| 1362 | 1641 | FrmStrpLiteAppHelper::plugin_path() . 'js/frmstrp.min.js', |
| 1363 | 1642 | ); |
| 1364 | 1643 | |
| 1365 | 1644 | /** |
| @@ -1376,14 +1655,14 @@ | ||
| 1376 | 1655 | * True when value is 1, true, 'true', 'yes' |
| 1377 | 1656 | * |
| 1378 | 1657 | * @since 1.07.10 |
| 1379 | 1658 | * |
| 1380 | - * @param string $value The value to compare | |
| 1659 | + * @param string $value The value to compare. | |
| 1381 | 1660 | * |
| 1382 | - * @return boolean True or False | |
| 1661 | + * @return bool | |
| 1383 | 1662 | */ |
| 1384 | 1663 | public static function is_true( $value ) { |
| 1385 | - return ( true === $value || 1 == $value || 'true' == $value || 'yes' == $value ); | |
| 1664 | + return true === $value || 1 == $value || 'true' === $value || 'yes' === $value; | |
| 1386 | 1665 | } |
| 1387 | 1666 | |
| 1388 | 1667 | /** |
| 1389 | 1668 | * Gets all post from a specific post type. |
| @@ -1441,9 +1720,9 @@ | ||
| 1441 | 1720 | $args = self::preformat_selection_args( $args ); |
| 1442 | 1721 | |
| 1443 | 1722 | $pages_count = wp_count_posts( $args['post_type'] ); |
| 1444 | 1723 | |
| 1445 | - if ( $pages_count->publish <= 50 ) { | |
| 1724 | + if ( ! isset( $pages_count->publish ) || $pages_count->publish <= 50 ) { | |
| 1446 | 1725 | self::wp_pages_dropdown( $args ); |
| 1447 | 1726 | return; |
| 1448 | 1727 | } |
| 1449 | 1728 | |
| @@ -1449,9 +1728,9 @@ | ||
| 1449 | 1728 | |
| 1450 | 1729 | wp_enqueue_script( 'jquery-ui-autocomplete' ); |
| 1451 | 1730 | |
| 1452 | 1731 | $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' ); |
| 1453 | - $title = ''; | |
| 1732 | + $title = ''; | |
| 1454 | 1733 | |
| 1455 | 1734 | if ( $selected ) { |
| 1456 | 1735 | $title = get_the_title( $selected ); |
| 1457 | 1736 | } |
| @@ -1467,18 +1746,112 @@ | ||
| 1467 | 1746 | <?php |
| 1468 | 1747 | } |
| 1469 | 1748 | |
| 1470 | 1749 | /** |
| 1471 | - * @param array $args | |
| 1472 | - * @param string $page_id Deprecated. | |
| 1473 | - * @param boolean $truncate Deprecated. | |
| 1750 | + * Maybe show an HTML select or autocomplete input based on the number of options. | |
| 1751 | + * | |
| 1752 | + * @since 6.21 | |
| 1753 | + * | |
| 1754 | + * @param array $args Args. See the method for details. | |
| 1474 | 1755 | */ |
| 1756 | + public static function maybe_autocomplete_options( $args ) { | |
| 1757 | + $defaults = array( | |
| 1758 | + 'truncate' => false, | |
| 1759 | + 'placeholder' => ' ', | |
| 1760 | + 'name' => '', | |
| 1761 | + 'id' => '', | |
| 1762 | + 'selected' => '', | |
| 1763 | + 'source' => array(), | |
| 1764 | + 'dropdown_limit' => 50, | |
| 1765 | + 'autocomplete_placeholder' => __( 'Select an option', 'formidable' ), | |
| 1766 | + 'value_key' => 'value', | |
| 1767 | + 'label_key' => 'label', | |
| 1768 | + ); | |
| 1769 | + | |
| 1770 | + $args = wp_parse_args( $args, $defaults ); | |
| 1771 | + | |
| 1772 | + $html_attrs = array(); | |
| 1773 | + if ( ! empty( $args['name'] ) ) { | |
| 1774 | + $html_attrs['name'] = $args['name']; | |
| 1775 | + } | |
| 1776 | + | |
| 1777 | + if ( ! empty( $args['id'] ) ) { | |
| 1778 | + $html_attrs['id'] = $args['id']; | |
| 1779 | + } | |
| 1780 | + | |
| 1781 | + if ( count( $args['source'] ) <= $args['dropdown_limit'] ) { | |
| 1782 | + ?> | |
| 1783 | + <select <?php self::array_to_html_params( $html_attrs, true ); ?>> | |
| 1784 | + <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option> | |
| 1785 | + <?php | |
| 1786 | + foreach ( $args['source'] as $key => $source ) : | |
| 1787 | + $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args ); | |
| 1788 | + if ( ! empty( $args['truncate'] ) ) { | |
| 1789 | + $value_label['label'] = self::truncate( $value_label['label'], $args['truncate'] ); | |
| 1790 | + } | |
| 1791 | + ?> | |
| 1792 | + <option value="<?php echo esc_attr( $value_label['value'] ); ?>" <?php selected( $value_label['value'], $args['selected'] ); ?>><?php echo esc_html( $value_label['label'] ); ?></option> | |
| 1793 | + <?php endforeach; ?> | |
| 1794 | + </select> | |
| 1795 | + <?php | |
| 1796 | + } else { | |
| 1797 | + $options = array(); | |
| 1798 | + $autocomplete_value = ''; | |
| 1799 | + foreach ( $args['source'] as $key => $source ) { | |
| 1800 | + $value_label = self::get_dropdown_value_and_label_from_option( $source, $key, $args ); | |
| 1801 | + | |
| 1802 | + if ( $value_label['value'] === $args['selected'] ) { | |
| 1803 | + $autocomplete_value = $value_label['label']; | |
| 1804 | + } | |
| 1805 | + | |
| 1806 | + $options[] = $value_label; | |
| 1807 | + } | |
| 1808 | + | |
| 1809 | + $html_attrs['type'] = 'hidden'; | |
| 1810 | + $html_attrs['class'] = 'frm_autocomplete_value_input'; | |
| 1811 | + $html_attrs['value'] = $args['selected']; | |
| 1812 | + ?> | |
| 1813 | + <input type="text" class="frm-custom-search" | |
| 1814 | + data-source="<?php echo esc_attr( wp_json_encode( $options ) ); ?>" | |
| 1815 | + placeholder="<?php echo esc_attr( $args['autocomplete_placeholder'] ); ?>" | |
| 1816 | + value="<?php echo esc_attr( $autocomplete_value ); ?>" /> | |
| 1817 | + <input <?php self::array_to_html_params( $html_attrs, true ); ?> /> | |
| 1818 | + <?php | |
| 1819 | + }//end if | |
| 1820 | + } | |
| 1821 | + | |
| 1822 | + /** | |
| 1823 | + * Gets dropdown value and label from autodropdown option. | |
| 1824 | + * | |
| 1825 | + * @since 6.21 | |
| 1826 | + * | |
| 1827 | + * @param array|string $option Autocomplete option. | |
| 1828 | + * @param string $key Array key of the option. | |
| 1829 | + * @param array $args See {@see FrmAppHelper::maybe_autocomplete_options()}. | |
| 1830 | + * @return array | |
| 1831 | + */ | |
| 1832 | + private static function get_dropdown_value_and_label_from_option( $option, $key, $args ) { | |
| 1833 | + if ( is_array( $option ) ) { | |
| 1834 | + $value = isset( $option[ $args['value_key'] ] ) ? $option[ $args['value_key'] ] : ''; | |
| 1835 | + $label = isset( $option[ $args['label_key'] ] ) ? $option[ $args['label_key'] ] : ''; | |
| 1836 | + } else { | |
| 1837 | + $value = $key; | |
| 1838 | + $label = $option; | |
| 1839 | + } | |
| 1840 | + | |
| 1841 | + return compact( 'value', 'label' ); | |
| 1842 | + } | |
| 1843 | + | |
| 1844 | + /** | |
| 1845 | + * @param array $args | |
| 1846 | + * @param string $page_id Deprecated. | |
| 1847 | + * @param bool $truncate Deprecated. | |
| 1848 | + */ | |
| 1475 | 1849 | public static function wp_pages_dropdown( $args = array(), $page_id = '', $truncate = false ) { |
| 1476 | 1850 | self::prep_page_dropdown_params( $page_id, $truncate, $args ); |
| 1477 | 1851 | |
| 1478 | 1852 | $pages = self::get_post_ids_and_titles( $args['post_type'] ); |
| 1479 | 1853 | $selected = self::get_post_param( $args['field_name'], $args['page_id'], 'absint' ); |
| 1480 | - | |
| 1481 | 1854 | ?> |
| 1482 | 1855 | <select name="<?php echo esc_attr( $args['field_name'] ); ?>" id="<?php echo esc_attr( $args['field_name'] ); ?>" class="frm-pages-dropdown"> |
| 1483 | 1856 | <option value=""><?php echo esc_html( $args['placeholder'] ); ?></option> |
| 1484 | 1857 | <?php foreach ( $pages as $page ) { ?> |
| @@ -1515,13 +1888,13 @@ | ||
| 1515 | 1888 | * @since 4.10.01 Added `post_type` and `autocomplete_placeholder` to the arguments array. |
| 1516 | 1889 | */ |
| 1517 | 1890 | private static function preformat_selection_args( $args ) { |
| 1518 | 1891 | $defaults = array( |
| 1519 | - 'truncate' => false, | |
| 1520 | - 'placeholder' => ' ', | |
| 1521 | - 'field_name' => '', | |
| 1522 | - 'page_id' => '', | |
| 1523 | - 'post_type' => 'page', | |
| 1892 | + 'truncate' => false, | |
| 1893 | + 'placeholder' => ' ', | |
| 1894 | + 'field_name' => '', | |
| 1895 | + 'page_id' => '', | |
| 1896 | + 'post_type' => 'page', | |
| 1524 | 1897 | 'autocomplete_placeholder' => __( 'Select a Page', 'formidable' ), |
| 1525 | 1898 | ); |
| 1526 | 1899 | |
| 1527 | 1900 | return array_merge( $defaults, $args ); |
| @@ -1592,25 +1965,16 @@ | ||
| 1592 | 1965 | return self::is_admin_page( 'formidable-views-editor' ); |
| 1593 | 1966 | } |
| 1594 | 1967 | |
| 1595 | 1968 | /** |
| 1596 | - * @since 4.0 | |
| 1597 | - * @deprecated 5.5.3 | |
| 1969 | + * @param string $field_name | |
| 1970 | + * @param array|string $capability | |
| 1971 | + * @param string $multiple 'single' and 'multiple'. | |
| 1598 | 1972 | */ |
| 1599 | - public static function maybe_full_screen_link( $link ) { | |
| 1600 | - _deprecated_function( __METHOD__, '5.5.3' ); | |
| 1601 | - return $link; | |
| 1602 | - } | |
| 1603 | - | |
| 1604 | - /** | |
| 1605 | - * @param string $field_name | |
| 1606 | - * @param string|array $capability | |
| 1607 | - * @param string $multiple 'single' and 'multiple' | |
| 1608 | - */ | |
| 1609 | 1973 | public static function wp_roles_dropdown( $field_name, $capability, $multiple = 'single' ) { |
| 1610 | 1974 | ?> |
| 1611 | 1975 | <select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>" |
| 1612 | - <?php echo ( 'multiple' === $multiple ) ? 'multiple="multiple"' : ''; ?> | |
| 1976 | + <?php echo 'multiple' === $multiple ? 'multiple="multiple"' : ''; ?> | |
| 1613 | 1977 | class="frm_multiselect"> |
| 1614 | 1978 | <?php self::roles_options( $capability ); ?> |
| 1615 | 1979 | </select> |
| 1616 | 1980 | <?php |
| @@ -1618,9 +1982,9 @@ | ||
| 1618 | 1982 | |
| 1619 | 1983 | /** |
| 1620 | 1984 | * @since 4.07 |
| 1621 | 1985 | * @param array|string $selected |
| 1622 | - * @param string $current | |
| 1986 | + * @param string $current | |
| 1623 | 1987 | */ |
| 1624 | 1988 | private static function selected( $selected, $current ) { |
| 1625 | 1989 | if ( is_callable( 'FrmProAppHelper::selected' ) ) { |
| 1626 | 1990 | FrmProAppHelper::selected( $selected, $current ); |
| @@ -1629,9 +1993,9 @@ | ||
| 1629 | 1993 | } |
| 1630 | 1994 | } |
| 1631 | 1995 | |
| 1632 | 1996 | /** |
| 1633 | - * @param string|array $capability | |
| 1997 | + * @param array|string $capability | |
| 1634 | 1998 | */ |
| 1635 | 1999 | public static function roles_options( $capability ) { |
| 1636 | 2000 | global $frm_vars; |
| 1637 | 2001 | if ( isset( $frm_vars['editable_roles'] ) ) { |
| @@ -1643,9 +2007,9 @@ | ||
| 1643 | 2007 | |
| 1644 | 2008 | foreach ( $editable_roles as $role => $details ) { |
| 1645 | 2009 | $name = translate_user_role( $details['name'] ); |
| 1646 | 2010 | ?> |
| 1647 | - <option value="<?php echo esc_attr( $role ); ?>" <?php self::selected( $capability, $role ); ?>><?php echo esc_attr( $name ); ?> </option> | |
| 2011 | + <option value="<?php echo esc_attr( $role ); ?>" <?php self::selected( $capability, $role ); ?>><?php echo esc_html( $name ); ?> </option> | |
| 1648 | 2012 | <?php |
| 1649 | 2013 | unset( $role, $details ); |
| 1650 | 2014 | } |
| 1651 | 2015 | } |
| @@ -1666,9 +2030,8 @@ | ||
| 1666 | 2030 | $pro_cap = array( |
| 1667 | 2031 | 'frm_create_entries' => __( 'Add Entries from Admin Area', 'formidable' ), |
| 1668 | 2032 | 'frm_edit_entries' => __( 'Edit Entries from Admin Area', 'formidable' ), |
| 1669 | 2033 | 'frm_view_reports' => __( 'View Reports', 'formidable' ), |
| 1670 | - 'frm_edit_displays' => __( 'Add/Edit Views', 'formidable' ), | |
| 1671 | 2034 | ); |
| 1672 | 2035 | /** |
| 1673 | 2036 | * @since 5.3.1 |
| 1674 | 2037 | * |
| @@ -1675,8 +2038,14 @@ | ||
| 1675 | 2038 | * @param array<string,string> $pro_cap |
| 1676 | 2039 | */ |
| 1677 | 2040 | $pro_cap = apply_filters( 'frm_pro_capabilities', $pro_cap ); |
| 1678 | 2041 | |
| 2042 | + if ( ! array_key_exists( 'frm_edit_displays', $pro_cap ) && is_callable( 'FrmProAppHelper::views_is_installed' ) && FrmProAppHelper::views_is_installed() ) { | |
| 2043 | + // For backward compatibility, add the Add/Edit Views permission if Pro is not up to date. | |
| 2044 | + // This was added in 6.5.4. Remove this in the future. | |
| 2045 | + $pro_cap['frm_edit_displays'] = __( 'Add/Edit Views', 'formidable' ); | |
| 2046 | + } | |
| 2047 | + | |
| 1679 | 2048 | if ( 'pro_only' === $type ) { |
| 1680 | 2049 | return $pro_cap; |
| 1681 | 2050 | } |
| 1682 | 2051 | |
| @@ -1691,9 +2060,9 @@ | ||
| 1691 | 2060 | * @return array<string,string> |
| 1692 | 2061 | */ |
| 1693 | 2062 | private static function get_lite_capabilities() { |
| 1694 | 2063 | return array( |
| 1695 | - 'frm_view_forms' => __( 'View Forms', 'formidable' ), | |
| 2064 | + 'frm_view_forms' => __( 'View Forms List', 'formidable' ), | |
| 1696 | 2065 | 'frm_edit_forms' => __( 'Add and Edit Forms', 'formidable' ), |
| 1697 | 2066 | 'frm_delete_forms' => __( 'Delete Forms', 'formidable' ), |
| 1698 | 2067 | 'frm_change_settings' => __( 'Access this Settings Page', 'formidable' ), |
| 1699 | 2068 | 'frm_view_entries' => __( 'View Entries from Admin Area', 'formidable' ), |
| @@ -1734,9 +2103,9 @@ | ||
| 1734 | 2103 | return current_user_can( $role ); |
| 1735 | 2104 | } |
| 1736 | 2105 | |
| 1737 | 2106 | /** |
| 1738 | - * @param string|array $needed_role | |
| 2107 | + * @param array|string $needed_role | |
| 1739 | 2108 | * @return bool |
| 1740 | 2109 | */ |
| 1741 | 2110 | public static function user_has_permission( $needed_role ) { |
| 1742 | 2111 | if ( is_array( $needed_role ) ) { |
| @@ -1792,8 +2161,11 @@ | ||
| 1792 | 2161 | /** |
| 1793 | 2162 | * Make sure admins have permission to see the menu items |
| 1794 | 2163 | * |
| 1795 | 2164 | * @since 2.0.6 |
| 2165 | + * | |
| 2166 | + * @param string $cap | |
| 2167 | + * @return void | |
| 1796 | 2168 | */ |
| 1797 | 2169 | public static function force_capability( $cap = 'frm_change_settings' ) { |
| 1798 | 2170 | if ( current_user_can( 'administrator' ) && ! current_user_can( $cap ) ) { |
| 1799 | 2171 | $role = get_role( 'administrator' ); |
| @@ -1804,9 +2176,9 @@ | ||
| 1804 | 2176 | } |
| 1805 | 2177 | } |
| 1806 | 2178 | |
| 1807 | 2179 | /** |
| 1808 | - * Check if the user has permision for action. | |
| 2180 | + * Check if the user has permission for action. | |
| 1809 | 2181 | * Return permission message and stop the action if no permission |
| 1810 | 2182 | * |
| 1811 | 2183 | * @since 2.0 |
| 1812 | 2184 | * |
| @@ -1842,9 +2214,9 @@ | ||
| 1842 | 2214 | if ( empty( $nonce_name ) ) { |
| 1843 | 2215 | return $error; |
| 1844 | 2216 | } |
| 1845 | 2217 | |
| 1846 | - $nonce_value = ( $_REQUEST && isset( $_REQUEST[ $nonce_name ] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ) : ''; | |
| 2218 | + $nonce_value = $_REQUEST && isset( $_REQUEST[ $nonce_name ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ) : ''; | |
| 1847 | 2219 | if ( $_REQUEST && ( ! isset( $_REQUEST[ $nonce_name ] ) || ! wp_verify_nonce( $nonce_value, $nonce ) ) ) { |
| 1848 | 2220 | $frm_settings = self::get_settings(); |
| 1849 | 2221 | $error = $frm_settings->admin_permission; |
| 1850 | 2222 | } |
| @@ -1858,12 +2230,13 @@ | ||
| 1858 | 2230 | } |
| 1859 | 2231 | } |
| 1860 | 2232 | |
| 1861 | 2233 | public static function check_selected( $values, $current ) { |
| 1862 | - $values = self::recursive_function_map( $values, 'trim' ); | |
| 1863 | - $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' ); | |
| 1864 | - $current = htmlspecialchars_decode( trim( $current ) ); | |
| 2234 | + $values = self::recursive_function_map( $values, 'trim' ); | |
| 2235 | + $values = self::recursive_function_map( $values, 'htmlspecialchars_decode' ); | |
| 1865 | 2236 | |
| 2237 | + $current = is_null( $current ) ? '' : htmlspecialchars_decode( trim( $current ) ); | |
| 2238 | + | |
| 1866 | 2239 | return ( is_array( $values ) && in_array( $current, $values ) ) || ( ! is_array( $values ) && $values == $current ); |
| 1867 | 2240 | } |
| 1868 | 2241 | |
| 1869 | 2242 | public static function recursive_function_map( $value, $function ) { |
| @@ -1883,8 +2256,9 @@ | ||
| 1883 | 2256 | } |
| 1884 | 2257 | } |
| 1885 | 2258 | } |
| 1886 | 2259 | } else { |
| 2260 | + $value = self::maybe_update_value_if_null( $value, $function ); | |
| 1887 | 2261 | $value = call_user_func( $function, $value ); |
| 1888 | 2262 | } |
| 1889 | 2263 | |
| 1890 | 2264 | return $value; |
| @@ -1889,8 +2263,24 @@ | ||
| 1889 | 2263 | |
| 1890 | 2264 | return $value; |
| 1891 | 2265 | } |
| 1892 | 2266 | |
| 2267 | + /** | |
| 2268 | + * Updates value to empty string if it is null and being passed to a string function. | |
| 2269 | + * | |
| 2270 | + * @since 6.8.4 | |
| 2271 | + * @param mixed $value | |
| 2272 | + * @param string $function | |
| 2273 | + * @return mixed | |
| 2274 | + */ | |
| 2275 | + private static function maybe_update_value_if_null( $value, $function ) { | |
| 2276 | + if ( null === $value && in_array( $function, array( 'trim', 'strlen' ), true ) ) { | |
| 2277 | + $value = ''; | |
| 2278 | + } | |
| 2279 | + | |
| 2280 | + return $value; | |
| 2281 | + } | |
| 2282 | + | |
| 1893 | 2283 | public static function is_assoc( $array ) { |
| 1894 | 2284 | return (bool) count( array_filter( array_keys( $array ), 'is_string' ) ); |
| 1895 | 2285 | } |
| 1896 | 2286 | |
| @@ -1901,14 +2291,12 @@ | ||
| 1901 | 2291 | $return = array(); |
| 1902 | 2292 | foreach ( $array as $key => $value ) { |
| 1903 | 2293 | if ( is_array( $value ) ) { |
| 1904 | 2294 | $return = array_merge( $return, self::array_flatten( $value, $keys ) ); |
| 2295 | + } elseif ( $keys === 'keep' ) { | |
| 2296 | + $return[ $key ] = $value; | |
| 1905 | 2297 | } else { |
| 1906 | - if ( $keys === 'keep' ) { | |
| 1907 | - $return[ $key ] = $value; | |
| 1908 | - } else { | |
| 1909 | - $return[] = $value; | |
| 1910 | - } | |
| 2298 | + $return[] = $value; | |
| 1911 | 2299 | } |
| 1912 | 2300 | } |
| 1913 | 2301 | |
| 1914 | 2302 | return $return; |
| @@ -1913,8 +2301,27 @@ | ||
| 1913 | 2301 | |
| 1914 | 2302 | return $return; |
| 1915 | 2303 | } |
| 1916 | 2304 | |
| 2305 | + /** | |
| 2306 | + * Flatten an array before imploding it to avoid Array to string conversion warnings. | |
| 2307 | + * | |
| 2308 | + * @since 6.16.1 | |
| 2309 | + * | |
| 2310 | + * @param string $sep | |
| 2311 | + * @param array $array | |
| 2312 | + * @return string | |
| 2313 | + */ | |
| 2314 | + public static function safe_implode( $sep, $array ) { | |
| 2315 | + $array = self::array_flatten( $array ); | |
| 2316 | + return implode( $sep, $array ); | |
| 2317 | + } | |
| 2318 | + | |
| 2319 | + /** | |
| 2320 | + * @param string $text | |
| 2321 | + * @param bool $is_rich_text | |
| 2322 | + * @return string | |
| 2323 | + */ | |
| 1917 | 2324 | public static function esc_textarea( $text, $is_rich_text = false ) { |
| 1918 | 2325 | $safe_text = str_replace( '"', '"', $text ); |
| 1919 | 2326 | if ( ! $is_rich_text ) { |
| 1920 | 2327 | $safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES ); |
| @@ -1920,9 +2327,13 @@ | ||
| 1920 | 2327 | $safe_text = htmlspecialchars( $safe_text, ENT_NOQUOTES ); |
| 1921 | 2328 | } |
| 1922 | 2329 | $safe_text = str_replace( '& ', '& ', $safe_text ); |
| 1923 | 2330 | |
| 1924 | - return apply_filters( 'esc_textarea', $safe_text, $text ); | |
| 2331 | + /** | |
| 2332 | + * @param string $safe_text | |
| 2333 | + * @param string $text | |
| 2334 | + */ | |
| 2335 | + return (string) apply_filters( 'esc_textarea', $safe_text, $text ); | |
| 1925 | 2336 | } |
| 1926 | 2337 | |
| 1927 | 2338 | /** |
| 1928 | 2339 | * Add auto paragraphs to text areas |
| @@ -1929,9 +2340,9 @@ | ||
| 1929 | 2340 | * |
| 1930 | 2341 | * @since 2.0 |
| 1931 | 2342 | */ |
| 1932 | 2343 | public static function use_wpautop( $content ) { |
| 1933 | - if ( apply_filters( 'frm_use_wpautop', true ) && ! is_array( $content ) ) { | |
| 2344 | + if ( apply_filters( 'frm_use_wpautop', true ) && is_string( $content ) ) { | |
| 1934 | 2345 | $content = wpautop( str_replace( '<br>', '<br />', $content ) ); |
| 1935 | 2346 | } |
| 1936 | 2347 | |
| 1937 | 2348 | return $content; |
| @@ -1973,12 +2384,12 @@ | ||
| 1973 | 2384 | * @since 5.0.13 added $echo param. |
| 1974 | 2385 | * |
| 1975 | 2386 | * @param string $url |
| 1976 | 2387 | * @param bool $echo |
| 1977 | - * @return string|void | |
| 2388 | + * @return string|null | |
| 1978 | 2389 | */ |
| 1979 | 2390 | public static function js_redirect( $url, $echo = false ) { |
| 1980 | - $callback = function() use ( $url ) { | |
| 2391 | + $callback = function () use ( $url ) { | |
| 1981 | 2392 | echo '<script type="text/javascript">window.location="' . esc_url_raw( $url ) . '"</script>'; |
| 1982 | 2393 | }; |
| 1983 | 2394 | return self::clip( $callback, $echo ); |
| 1984 | 2395 | } |
| @@ -2006,8 +2417,13 @@ | ||
| 2006 | 2417 | |
| 2007 | 2418 | return $user_id; |
| 2008 | 2419 | } |
| 2009 | 2420 | |
| 2421 | + /** | |
| 2422 | + * @param string $filename | |
| 2423 | + * @param array $atts | |
| 2424 | + * @return false|string | |
| 2425 | + */ | |
| 2010 | 2426 | public static function get_file_contents( $filename, $atts = array() ) { |
| 2011 | 2427 | if ( ! is_file( $filename ) ) { |
| 2012 | 2428 | return false; |
| 2013 | 2429 | } |
| @@ -2013,9 +2429,9 @@ | ||
| 2013 | 2429 | } |
| 2014 | 2430 | |
| 2015 | 2431 | extract( $atts ); // phpcs:ignore WordPress.PHP.DontExtract |
| 2016 | 2432 | ob_start(); |
| 2017 | - include( $filename ); | |
| 2433 | + include $filename; | |
| 2018 | 2434 | $contents = ob_get_contents(); |
| 2019 | 2435 | ob_end_clean(); |
| 2020 | 2436 | |
| 2021 | 2437 | return $contents; |
| @@ -2070,9 +2486,9 @@ | ||
| 2070 | 2486 | ++$suffix; |
| 2071 | 2487 | } while ( in_array( $key_check, $similar_keys, true ) ); |
| 2072 | 2488 | |
| 2073 | 2489 | $key = $key_check; |
| 2074 | - } | |
| 2490 | + }//end if | |
| 2075 | 2491 | |
| 2076 | 2492 | return $key; |
| 2077 | 2493 | } |
| 2078 | 2494 | |
| @@ -2111,14 +2527,18 @@ | ||
| 2111 | 2527 | return $key; |
| 2112 | 2528 | } |
| 2113 | 2529 | |
| 2114 | 2530 | /** |
| 2531 | + * @since 6.21 This is changed from `private` to `public`. | |
| 2532 | + * | |
| 2115 | 2533 | * @param int $num_chars |
| 2116 | 2534 | * @return string |
| 2117 | 2535 | */ |
| 2118 | - private static function generate_new_key( $num_chars ) { | |
| 2536 | + public static function generate_new_key( $num_chars ) { | |
| 2119 | 2537 | $max_slug_value = pow( 36, $num_chars ); |
| 2120 | - $min_slug_value = 37; // we want to have at least 2 characters in the slug | |
| 2538 | + | |
| 2539 | + // We want to have at least 2 characters in the slug. | |
| 2540 | + $min_slug_value = 37; | |
| 2121 | 2541 | return base_convert( rand( $min_slug_value, $max_slug_value ), 10, 36 ); |
| 2122 | 2542 | } |
| 2123 | 2543 | |
| 2124 | 2544 | /** |
| @@ -2147,11 +2567,16 @@ | ||
| 2147 | 2567 | |
| 2148 | 2568 | /** |
| 2149 | 2569 | * Editing a Form or Entry |
| 2150 | 2570 | * |
| 2151 | - * @param string $table | |
| 2571 | + * @param object $record | |
| 2572 | + * @param string $table | |
| 2573 | + * @param array|string $fields | |
| 2574 | + * @param bool $default | |
| 2575 | + * @param array $post_values | |
| 2576 | + * @param array $args | |
| 2152 | 2577 | * |
| 2153 | - * @return bool|array | |
| 2578 | + * @return array|bool | |
| 2154 | 2579 | */ |
| 2155 | 2580 | public static function setup_edit_vars( $record, $table, $fields = '', $default = false, $post_values = array(), $args = array() ) { |
| 2156 | 2581 | if ( ! $record ) { |
| 2157 | 2582 | return false; |
| @@ -2204,13 +2629,12 @@ | ||
| 2204 | 2629 | $post_values = $args['post_values']; |
| 2205 | 2630 | |
| 2206 | 2631 | if ( $args['default'] ) { |
| 2207 | 2632 | $meta_value = $field->default_value; |
| 2208 | - } else { | |
| 2209 | - if ( $record->post_id && self::pro_is_installed() && isset( $field->field_options['post_field'] ) && $field->field_options['post_field'] ) { | |
| 2210 | - if ( ! isset( $field->field_options['custom_field'] ) ) { | |
| 2211 | - $field->field_options['custom_field'] = ''; | |
| 2212 | - } | |
| 2633 | + } elseif ( $record->post_id && self::pro_is_installed() && isset( $field->field_options['post_field'] ) && $field->field_options['post_field'] ) { | |
| 2634 | + if ( ! isset( $field->field_options['custom_field'] ) ) { | |
| 2635 | + $field->field_options['custom_field'] = ''; | |
| 2636 | + } | |
| 2213 | 2637 | $meta_value = FrmProEntryMetaHelper::get_post_value( |
| 2214 | 2638 | $record->post_id, |
| 2215 | 2639 | $field->field_options['post_field'], |
| 2216 | 2640 | $field->field_options['custom_field'], |
| @@ -2220,12 +2644,11 @@ | ||
| 2220 | 2644 | 'form_id' => $field->form_id, |
| 2221 | 2645 | 'field' => $field, |
| 2222 | 2646 | ) |
| 2223 | 2647 | ); |
| 2224 | - } else { | |
| 2225 | - $meta_value = FrmEntryMeta::get_meta_value( $record, $field->id ); | |
| 2226 | - } | |
| 2227 | - } | |
| 2648 | + } else { | |
| 2649 | + $meta_value = FrmEntryMeta::get_meta_value( $record, $field->id ); | |
| 2650 | + }//end if | |
| 2228 | 2651 | |
| 2229 | 2652 | $field_type = isset( $post_values['field_options'][ 'type_' . $field->id ] ) ? $post_values['field_options'][ 'type_' . $field->id ] : $field->type; |
| 2230 | 2653 | if ( isset( $post_values['item_meta'][ $field->id ] ) ) { |
| 2231 | 2654 | $new_value = $post_values['item_meta'][ $field->id ]; |
| @@ -2273,12 +2696,15 @@ | ||
| 2273 | 2696 | ); |
| 2274 | 2697 | } |
| 2275 | 2698 | |
| 2276 | 2699 | /** |
| 2700 | + * @param object $record | |
| 2277 | 2701 | * @param string $table |
| 2702 | + * @param array $post_values | |
| 2703 | + * @param array $values | |
| 2278 | 2704 | */ |
| 2279 | 2705 | private static function fill_form_opts( $record, $table, $post_values, array &$values ) { |
| 2280 | - if ( $table == 'entries' ) { | |
| 2706 | + if ( $table === 'entries' ) { | |
| 2281 | 2707 | $form = $record->form_id; |
| 2282 | 2708 | FrmForm::maybe_get_form( $form ); |
| 2283 | 2709 | } else { |
| 2284 | 2710 | $form = $record; |
| @@ -2314,9 +2740,9 @@ | ||
| 2314 | 2740 | $form_defaults = FrmFormsHelper::get_default_opts(); |
| 2315 | 2741 | |
| 2316 | 2742 | foreach ( $form_defaults as $opt => $default ) { |
| 2317 | 2743 | if ( ! isset( $values[ $opt ] ) || $values[ $opt ] == '' ) { |
| 2318 | - $values[ $opt ] = ( $post_values && isset( $post_values['options'][ $opt ] ) ) ? $post_values['options'][ $opt ] : $default; | |
| 2744 | + $values[ $opt ] = $post_values && isset( $post_values['options'][ $opt ] ) ? $post_values['options'][ $opt ] : $default; | |
| 2319 | 2745 | } |
| 2320 | 2746 | |
| 2321 | 2747 | unset( $opt, $default ); |
| 2322 | 2748 | } |
| @@ -2337,9 +2763,9 @@ | ||
| 2337 | 2763 | * @since 2.2.10 |
| 2338 | 2764 | * |
| 2339 | 2765 | * @param array $post_values |
| 2340 | 2766 | * |
| 2341 | - * @return boolean|int | |
| 2767 | + * @return bool|int | |
| 2342 | 2768 | */ |
| 2343 | 2769 | public static function custom_style_value( $post_values ) { |
| 2344 | 2770 | if ( ! empty( $post_values ) && isset( $post_values['options']['custom_style'] ) ) { |
| 2345 | 2771 | $custom_style = absint( $post_values['options']['custom_style'] ); |
| @@ -2344,29 +2770,37 @@ | ||
| 2344 | 2770 | if ( ! empty( $post_values ) && isset( $post_values['options']['custom_style'] ) ) { |
| 2345 | 2771 | $custom_style = absint( $post_values['options']['custom_style'] ); |
| 2346 | 2772 | } else { |
| 2347 | 2773 | $frm_settings = self::get_settings(); |
| 2348 | - $custom_style = ( $frm_settings->load_style != 'none' ); | |
| 2774 | + $custom_style = ( $frm_settings->load_style !== 'none' ); | |
| 2349 | 2775 | } |
| 2350 | 2776 | |
| 2351 | 2777 | return $custom_style; |
| 2352 | 2778 | } |
| 2353 | 2779 | |
| 2354 | - public static function truncate( $str, $length, $minword = 3, $continue = '...' ) { | |
| 2355 | - if ( is_array( $str ) ) { | |
| 2780 | + /** | |
| 2781 | + * @param mixed $original_string | |
| 2782 | + * @param int|string $length | |
| 2783 | + * @param int $minword | |
| 2784 | + * @param string $continue | |
| 2785 | + * @return string | |
| 2786 | + */ | |
| 2787 | + public static function truncate( $original_string, $length, $minword = 3, $continue = '...' ) { | |
| 2788 | + if ( ! is_string( $original_string ) && ! is_int( $original_string ) ) { | |
| 2356 | 2789 | return ''; |
| 2357 | 2790 | } |
| 2358 | 2791 | |
| 2359 | 2792 | $length = (int) $length; |
| 2360 | - $str = wp_strip_all_tags( $str ); | |
| 2793 | + $str = wp_strip_all_tags( (string) $original_string ); | |
| 2361 | 2794 | $original_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $str ) ); |
| 2362 | 2795 | |
| 2363 | 2796 | if ( $length == 0 ) { |
| 2364 | 2797 | return ''; |
| 2365 | - } elseif ( $length <= 10 ) { | |
| 2798 | + } | |
| 2799 | + | |
| 2800 | + if ( $length <= 10 ) { | |
| 2366 | 2801 | $sub = self::mb_function( array( 'mb_substr', 'substr' ), array( $str, 0, $length ) ); |
| 2367 | - | |
| 2368 | - return $sub . ( ( $length < $original_len ) ? $continue : '' ); | |
| 2802 | + return $sub . ( $length < $original_len ? $continue : '' ); | |
| 2369 | 2803 | } |
| 2370 | 2804 | |
| 2371 | 2805 | $sub = ''; |
| 2372 | 2806 | $len = 0; |
| @@ -2372,10 +2806,14 @@ | ||
| 2372 | 2806 | $len = 0; |
| 2373 | 2807 | |
| 2374 | 2808 | $words = self::mb_function( array( 'mb_split', 'explode' ), array( ' ', $str ) ); |
| 2375 | 2809 | |
| 2810 | + if ( ! is_array( $words ) ) { | |
| 2811 | + return $original_string; | |
| 2812 | + } | |
| 2813 | + | |
| 2376 | 2814 | foreach ( $words as $word ) { |
| 2377 | - $part = ( ( $sub != '' ) ? ' ' : '' ) . $word; | |
| 2815 | + $part = ( $sub != '' ? ' ' : '' ) . $word; | |
| 2378 | 2816 | $total_len = self::mb_function( array( 'mb_strlen', 'strlen' ), array( $sub . $part ) ); |
| 2379 | 2817 | if ( $total_len > $length && substr_count( $sub, ' ' ) ) { |
| 2380 | 2818 | break; |
| 2381 | 2819 | } |
| @@ -2389,11 +2827,37 @@ | ||
| 2389 | 2827 | |
| 2390 | 2828 | unset( $total_len, $word ); |
| 2391 | 2829 | } |
| 2392 | 2830 | |
| 2393 | - return $sub . ( ( $len < $original_len ) ? $continue : '' ); | |
| 2831 | + $sub = self::maybe_force_truncate_on_string_with_no_spaces( $sub, $length ); | |
| 2832 | + | |
| 2833 | + return $sub . ( $len < $original_len ? $continue : '' ); | |
| 2394 | 2834 | } |
| 2395 | 2835 | |
| 2836 | + /** | |
| 2837 | + * If the string is still too long because there may not have been any spaces, force truncate. | |
| 2838 | + * | |
| 2839 | + * @since 6.5.4 | |
| 2840 | + * | |
| 2841 | + * @param string $sub Current substring. | |
| 2842 | + * @param int $length The length limit. | |
| 2843 | + * @return string | |
| 2844 | + */ | |
| 2845 | + private static function maybe_force_truncate_on_string_with_no_spaces( $sub, $length ) { | |
| 2846 | + if ( strlen( $sub ) < $length + 50 ) { | |
| 2847 | + // If the string isn't way over the limit, leave it. | |
| 2848 | + return $sub; | |
| 2849 | + } | |
| 2850 | + | |
| 2851 | + $first_space = strpos( $sub, ' ', $length ); | |
| 2852 | + if ( false !== $first_space ) { | |
| 2853 | + // Ignore anything with spaces. | |
| 2854 | + return $sub; | |
| 2855 | + } | |
| 2856 | + | |
| 2857 | + return substr( $sub, 0, $length + 10 ); | |
| 2858 | + } | |
| 2859 | + | |
| 2396 | 2860 | public static function mb_function( $function_names, $args ) { |
| 2397 | 2861 | $mb_function_name = $function_names[0]; |
| 2398 | 2862 | $function_name = $function_names[1]; |
| 2399 | 2863 | if ( function_exists( $mb_function_name ) ) { |
| @@ -2426,8 +2890,13 @@ | ||
| 2426 | 2890 | |
| 2427 | 2891 | return $formatted; |
| 2428 | 2892 | } |
| 2429 | 2893 | |
| 2894 | + /** | |
| 2895 | + * @param string $time_format | |
| 2896 | + * @param string $date | |
| 2897 | + * @return string | |
| 2898 | + */ | |
| 2430 | 2899 | private static function add_time_to_date( $time_format, $date ) { |
| 2431 | 2900 | if ( empty( $time_format ) ) { |
| 2432 | 2901 | $time_format = get_option( 'time_format' ); |
| 2433 | 2902 | } |
| @@ -2450,12 +2919,12 @@ | ||
| 2450 | 2919 | return date_i18n( $date_format, strtotime( $date ) ); |
| 2451 | 2920 | } |
| 2452 | 2921 | |
| 2453 | 2922 | /** |
| 2454 | - * Gets the time ago in words | |
| 2923 | + * Gets the time ago in words. | |
| 2455 | 2924 | * |
| 2456 | - * @param int $from in seconds | |
| 2457 | - * @param int|string $to in seconds | |
| 2925 | + * @param int $from In seconds. | |
| 2926 | + * @param int|string $to In seconds. | |
| 2458 | 2927 | * |
| 2459 | 2928 | * @return string $time_ago |
| 2460 | 2929 | */ |
| 2461 | 2930 | public static function human_time_diff( $from, $to = '', $levels = 1 ) { |
| @@ -2470,9 +2939,9 @@ | ||
| 2470 | 2939 | $diff_object = $now->diff( $ago ); |
| 2471 | 2940 | $diff = get_object_vars( $diff_object ); |
| 2472 | 2941 | |
| 2473 | 2942 | // Add week amount and update day amount |
| 2474 | - $diff['w'] = floor( $diff['d'] / 7 ); | |
| 2943 | + $diff['w'] = floor( $diff['d'] / 7 ); | |
| 2475 | 2944 | $diff['d'] -= $diff['w'] * 7; |
| 2476 | 2945 | |
| 2477 | 2946 | $time_strings = self::get_time_strings(); |
| 2478 | 2947 | |
| @@ -2479,9 +2948,9 @@ | ||
| 2479 | 2948 | if ( ! is_numeric( $levels ) ) { |
| 2480 | 2949 | // Show time in specified unit. |
| 2481 | 2950 | $levels = self::get_unit( $levels ); |
| 2482 | 2951 | if ( isset( $time_strings[ $levels ] ) ) { |
| 2483 | - $diff = array( | |
| 2952 | + $diff = array( | |
| 2484 | 2953 | $levels => self::time_format( $levels, $diff ), |
| 2485 | 2954 | ); |
| 2486 | 2955 | $time_strings = array( |
| 2487 | 2956 | $levels => $time_strings[ $levels ], |
| @@ -2570,9 +3039,9 @@ | ||
| 2570 | 3039 | } |
| 2571 | 3040 | |
| 2572 | 3041 | /** |
| 2573 | 3042 | * Get the translatable time strings. The untranslated version is a failsafe |
| 2574 | - * in case langauges are changing for the unit set in the shortcode. | |
| 3043 | + * in case languages are changing for the unit set in the shortcode. | |
| 2575 | 3044 | * |
| 2576 | 3045 | * @since 2.0.20 |
| 2577 | 3046 | * @return array |
| 2578 | 3047 | */ |
| @@ -2618,23 +3087,28 @@ | ||
| 2618 | 3087 | |
| 2619 | 3088 | // Pagination Methods. |
| 2620 | 3089 | |
| 2621 | 3090 | /** |
| 2622 | - * @param integer $current_p | |
| 3091 | + * @param int $r_count | |
| 3092 | + * @param int $current_p | |
| 3093 | + * @param int $p_size | |
| 3094 | + * @return int | |
| 2623 | 3095 | */ |
| 2624 | 3096 | public static function get_last_record_num( $r_count, $current_p, $p_size ) { |
| 2625 | - return ( ( $r_count < ( $current_p * $p_size ) ) ? $r_count : ( $current_p * $p_size ) ); | |
| 3097 | + return ( $r_count < $current_p * $p_size ? $r_count : $current_p * $p_size ); | |
| 2626 | 3098 | } |
| 2627 | 3099 | |
| 2628 | 3100 | /** |
| 2629 | - * @param integer $current_p | |
| 3101 | + * @param int $r_count | |
| 3102 | + * @param int $current_p | |
| 3103 | + * @param int $p_size | |
| 3104 | + * @return int | |
| 2630 | 3105 | */ |
| 2631 | 3106 | public static function get_first_record_num( $r_count, $current_p, $p_size ) { |
| 2632 | 3107 | if ( $current_p == 1 ) { |
| 2633 | 3108 | return 1; |
| 2634 | - } else { | |
| 2635 | - return ( self::get_last_record_num( $r_count, ( $current_p - 1 ), $p_size ) + 1 ); | |
| 2636 | 3109 | } |
| 3110 | + return self::get_last_record_num( $r_count, $current_p - 1, $p_size ) + 1; | |
| 2637 | 3111 | } |
| 2638 | 3112 | |
| 2639 | 3113 | /** |
| 2640 | 3114 | * @return array |
| @@ -2657,9 +3131,9 @@ | ||
| 2657 | 3131 | if ( ! isset( $l3 ) ) { |
| 2658 | 3132 | $l3 = $name; |
| 2659 | 3133 | } |
| 2660 | 3134 | |
| 2661 | - $this_val = ( $p == $last ) ? $jv['value'] : array(); | |
| 3135 | + $this_val = $p == $last ? $jv['value'] : array(); | |
| 2662 | 3136 | |
| 2663 | 3137 | switch ( $p ) { |
| 2664 | 3138 | case 0: |
| 2665 | 3139 | $l1 = $name; |
| @@ -2681,12 +3155,12 @@ | ||
| 2681 | 3155 | self::add_value_to_array( $name, $l4, $this_val, $vars[ $l1 ][ $l2 ][ $l3 ] ); |
| 2682 | 3156 | } |
| 2683 | 3157 | |
| 2684 | 3158 | unset( $this_val, $n ); |
| 2685 | - } | |
| 3159 | + }//end foreach | |
| 2686 | 3160 | |
| 2687 | 3161 | unset( $last, $jv ); |
| 2688 | - } | |
| 3162 | + }//end foreach | |
| 2689 | 3163 | |
| 2690 | 3164 | return $vars; |
| 2691 | 3165 | } |
| 2692 | 3166 | |
| @@ -2934,8 +3408,11 @@ | ||
| 2934 | 3408 | } |
| 2935 | 3409 | |
| 2936 | 3410 | /** |
| 2937 | 3411 | * @since 4.02.03 |
| 3412 | + * | |
| 3413 | + * @param array|string $value | |
| 3414 | + * @return string | |
| 2938 | 3415 | */ |
| 2939 | 3416 | public static function maybe_json_encode( $value ) { |
| 2940 | 3417 | if ( is_array( $value ) ) { |
| 2941 | 3418 | $value = wp_json_encode( $value ); |
| @@ -2943,12 +3420,14 @@ | ||
| 2943 | 3420 | return $value; |
| 2944 | 3421 | } |
| 2945 | 3422 | |
| 2946 | 3423 | /** |
| 3424 | + * Echo The javascript to open and highlight the Formidable menu | |
| 3425 | + * | |
| 2947 | 3426 | * @since 1.07.10 |
| 2948 | 3427 | * |
| 2949 | - * @param string $post_type The name of the post type that may need to be highlighted | |
| 2950 | - * echo The javascript to open and highlight the Formidable menu | |
| 3428 | + * @param string $post_type The name of the post type that may need to be highlighted. | |
| 3429 | + * @return void | |
| 2951 | 3430 | */ |
| 2952 | 3431 | public static function maybe_highlight_menu( $post_type ) { |
| 2953 | 3432 | global $post; |
| 2954 | 3433 | |
| @@ -2967,8 +3446,11 @@ | ||
| 2967 | 3446 | /** |
| 2968 | 3447 | * Load the JS file on non-Formidable pages in the admin area |
| 2969 | 3448 | * |
| 2970 | 3449 | * @since 2.0 |
| 3450 | + * | |
| 3451 | + * @param bool $load | |
| 3452 | + * @return void | |
| 2971 | 3453 | */ |
| 2972 | 3454 | public static function load_admin_wide_js( $load = true ) { |
| 2973 | 3455 | $version = self::plugin_version(); |
| 2974 | 3456 | wp_register_script( 'formidable_admin_global', self::plugin_url() . '/js/formidable_admin_global.js', array( 'jquery' ), $version ); |
| @@ -2982,8 +3464,9 @@ | ||
| 2982 | 3464 | 'canAccessApplicationDashboard' => current_user_can( is_callable( 'FrmProApplicationsHelper::get_required_templates_capability' ) ? FrmProApplicationsHelper::get_required_templates_capability() : 'frm_edit_forms' ), |
| 2983 | 3465 | 'loading' => __( 'Loading…', 'formidable' ), |
| 2984 | 3466 | 'nonce' => wp_create_nonce( 'frm_ajax' ), |
| 2985 | 3467 | 'proIncludesSliderJs' => is_callable( 'FrmProFormsHelper::prepare_custom_currency' ), |
| 3468 | + 'inboxSlideIn' => FrmInbox::get_inbox_slide_in_value_for_js(), | |
| 2986 | 3469 | ); |
| 2987 | 3470 | wp_localize_script( 'formidable_admin_global', 'frmGlobal', $global_strings ); |
| 2988 | 3471 | |
| 2989 | 3472 | if ( $load ) { |
| @@ -2992,8 +3475,9 @@ | ||
| 2992 | 3475 | } |
| 2993 | 3476 | |
| 2994 | 3477 | /** |
| 2995 | 3478 | * @since 2.0.9 |
| 3479 | + * @return void | |
| 2996 | 3480 | */ |
| 2997 | 3481 | public static function load_font_style() { |
| 2998 | 3482 | wp_enqueue_style( 'frm_fonts', self::plugin_url() . '/css/frm_fonts.css', array(), self::plugin_version() ); |
| 2999 | 3483 | } |
| @@ -2999,26 +3483,29 @@ | ||
| 2999 | 3483 | } |
| 3000 | 3484 | |
| 3001 | 3485 | /** |
| 3002 | 3486 | * @param string $location |
| 3487 | + * @return void | |
| 3003 | 3488 | */ |
| 3004 | 3489 | public static function localize_script( $location ) { |
| 3005 | - global $wp_scripts; | |
| 3490 | + global $wp_scripts, $wp_version; | |
| 3006 | 3491 | |
| 3007 | 3492 | $script_strings = array( |
| 3008 | - 'ajax_url' => esc_url_raw( self::get_ajax_url() ), | |
| 3009 | - 'images_url' => self::plugin_url() . '/images', | |
| 3010 | - 'loading' => __( 'Loading…', 'formidable' ), | |
| 3011 | - 'remove' => __( 'Remove', 'formidable' ), | |
| 3012 | - 'offset' => apply_filters( 'frm_scroll_offset', 4 ), | |
| 3013 | - 'nonce' => wp_create_nonce( 'frm_ajax' ), | |
| 3014 | - 'id' => __( 'ID', 'formidable' ), | |
| 3015 | - 'no_results' => __( 'No results match', 'formidable' ), | |
| 3016 | - 'file_spam' => __( 'That file looks like Spam.', 'formidable' ), | |
| 3017 | - 'calc_error' => __( 'There is an error in the calculation in the field with key', 'formidable' ), | |
| 3018 | - 'empty_fields' => __( 'Please complete the preceding required fields before uploading a file.', 'formidable' ), | |
| 3019 | - 'focus_first_error' => self::should_focus_first_error(), | |
| 3020 | - 'include_alert_role' => self::should_include_alert_role_on_field_errors(), | |
| 3493 | + 'ajax_url' => esc_url_raw( self::get_ajax_url() ), | |
| 3494 | + 'images_url' => self::plugin_url() . '/images', | |
| 3495 | + 'loading' => __( 'Loading…', 'formidable' ), | |
| 3496 | + 'remove' => __( 'Remove', 'formidable' ), | |
| 3497 | + 'offset' => apply_filters( 'frm_scroll_offset', 4 ), | |
| 3498 | + 'nonce' => wp_create_nonce( 'frm_ajax' ), | |
| 3499 | + 'id' => __( 'ID', 'formidable' ), | |
| 3500 | + 'no_results' => __( 'No results match', 'formidable' ), | |
| 3501 | + 'file_spam' => __( 'That file looks like Spam.', 'formidable' ), | |
| 3502 | + 'calc_error' => __( 'There is an error in the calculation in the field with key', 'formidable' ), | |
| 3503 | + 'empty_fields' => __( 'Please complete the preceding required fields before uploading a file.', 'formidable' ), | |
| 3504 | + 'focus_first_error' => self::should_focus_first_error(), | |
| 3505 | + 'include_alert_role' => self::should_include_alert_role_on_field_errors(), | |
| 3506 | + // We need to keep this setting for a few versions because Pro checks for this. | |
| 3507 | + 'include_resend_email' => false, | |
| 3021 | 3508 | ); |
| 3022 | 3509 | |
| 3023 | 3510 | $data = $wp_scripts->get_data( 'formidable', 'data' ); |
| 3024 | 3511 | if ( ! $data ) { |
| @@ -3025,59 +3512,74 @@ | ||
| 3025 | 3512 | wp_localize_script( 'formidable', 'frm_js', $script_strings ); |
| 3026 | 3513 | } |
| 3027 | 3514 | |
| 3028 | 3515 | if ( $location === 'admin' ) { |
| 3029 | - $frm_settings = self::get_settings(); | |
| 3030 | 3516 | $admin_script_strings = array( |
| 3031 | - 'desc' => __( '(Click to add description)', 'formidable' ), | |
| 3032 | - 'blank' => __( '(Blank)', 'formidable' ), | |
| 3033 | - 'no_label' => __( '(no label)', 'formidable' ), | |
| 3034 | - 'ok' => __( 'OK', 'formidable' ), | |
| 3035 | - 'cancel' => __( 'Cancel', 'formidable' ), | |
| 3036 | - 'default_label' => __( 'Default', 'formidable' ), | |
| 3037 | - 'clear_default' => __( 'Clear default value when typing', 'formidable' ), | |
| 3038 | - 'no_clear_default' => __( 'Do not clear default value when typing', 'formidable' ), | |
| 3039 | - 'valid_default' => __( 'Default value will pass form validation', 'formidable' ), | |
| 3040 | - 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ), | |
| 3041 | - 'confirm' => __( 'Are you sure?', 'formidable' ), | |
| 3042 | - 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ), | |
| 3043 | - 'conf_delete_sec' => __( 'All fields inside this Section will be deleted along with their data. Are you sure you want to delete this group of fields?', 'formidable' ), | |
| 3044 | - 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ), | |
| 3045 | - 'default_unique' => $frm_settings->unique_msg, | |
| 3046 | - 'default_conf' => __( 'The entered values do not match', 'formidable' ), | |
| 3047 | - 'enter_email' => __( 'Enter Email', 'formidable' ), | |
| 3048 | - 'confirm_email' => __( 'Confirm Email', 'formidable' ), | |
| 3049 | - 'conditional_text' => __( 'Conditional content here', 'formidable' ), | |
| 3050 | - 'new_option' => __( 'New Option', 'formidable' ), | |
| 3051 | - 'css_invalid_size' => __( 'In certain browsers (e.g. Firefox) text will not display correctly if the field height is too small relative to the field padding and text size. Please increase your field height or decrease your field padding.', 'formidable' ), | |
| 3052 | - 'enter_password' => __( 'Enter Password', 'formidable' ), | |
| 3053 | - 'confirm_password' => __( 'Confirm Password', 'formidable' ), | |
| 3054 | - 'import_complete' => __( 'Import Complete', 'formidable' ), | |
| 3055 | - 'updating' => __( 'Please wait while your site updates.', 'formidable' ), | |
| 3056 | - 'no_save_warning' => __( 'Warning: There is no way to retrieve unsaved entries.', 'formidable' ), | |
| 3057 | - 'private_label' => __( 'Private', 'formidable' ), | |
| 3058 | - 'jquery_ui_url' => '', | |
| 3059 | - 'pro_url' => is_callable( 'FrmProAppHelper::plugin_url' ) ? FrmProAppHelper::plugin_url() : '', | |
| 3060 | - 'no_licenses' => __( 'No new licenses were found', 'formidable' ), | |
| 3061 | - 'unmatched_parens' => __( 'This calculation has at least one unmatched ( ) { } [ ].', 'formidable' ), | |
| 3062 | - 'view_shortcodes' => __( 'This calculation may have shortcodes that work in Views but not forms.', 'formidable' ), | |
| 3063 | - 'text_shortcodes' => __( 'This calculation may have shortcodes that work in text calculations but not numeric calculations.', 'formidable' ), | |
| 3064 | - 'only_one_action' => __( 'This form action is limited to one per form. Please edit the existing form action.', 'formidable' ), | |
| 3065 | - 'unsafe_params' => FrmFormsHelper::reserved_words(), | |
| 3517 | + 'desc' => __( '(Click to add description)', 'formidable' ), | |
| 3518 | + 'blank' => __( '(Blank)', 'formidable' ), | |
| 3519 | + 'no_label' => __( '(no label)', 'formidable' ), | |
| 3520 | + 'ok' => __( 'OK', 'formidable' ), | |
| 3521 | + 'cancel' => __( 'Cancel', 'formidable' ), | |
| 3522 | + 'default_label' => __( 'Default', 'formidable' ), | |
| 3523 | + 'clear_default' => __( 'Clear default value when typing', 'formidable' ), | |
| 3524 | + 'no_clear_default' => __( 'Do not clear default value when typing', 'formidable' ), | |
| 3525 | + 'valid_default' => __( 'Default value will pass form validation', 'formidable' ), | |
| 3526 | + 'no_valid_default' => __( 'Default value will NOT pass form validation', 'formidable' ), | |
| 3527 | + 'confirm' => __( 'Are you sure?', 'formidable' ), | |
| 3528 | + 'conf_delete' => __( 'Are you sure you want to delete this field and all data associated with it?', 'formidable' ), | |
| 3529 | + 'conf_delete_sec' => __( 'All fields inside this Section will be deleted along with their data. Are you sure you want to delete this group of fields?', 'formidable' ), | |
| 3530 | + 'conf_no_repeat' => __( 'Warning: If you have entries with multiple rows, all but the first row will be lost.', 'formidable' ), | |
| 3531 | + 'default_unique' => FrmFieldsHelper::default_unique_msg(), | |
| 3532 | + 'default_conf' => __( 'The entered values do not match', 'formidable' ), | |
| 3533 | + 'enter_email' => __( 'Enter Email', 'formidable' ), | |
| 3534 | + 'confirm_email' => __( 'Confirm Email', 'formidable' ), | |
| 3535 | + 'conditional_text' => __( 'Conditional content here', 'formidable' ), | |
| 3536 | + 'new_option' => __( 'New Option', 'formidable' ), | |
| 3537 | + 'css_invalid_size' => __( 'In certain browsers (e.g. Firefox) text will not display correctly if the field height is too small relative to the field padding and text size. Please increase your field height or decrease your field padding.', 'formidable' ), | |
| 3538 | + 'enter_password' => __( 'Enter Password', 'formidable' ), | |
| 3539 | + 'confirm_password' => __( 'Confirm Password', 'formidable' ), | |
| 3540 | + 'import_complete' => __( 'Import Complete', 'formidable' ), | |
| 3541 | + 'updating' => __( 'Please wait while your site updates.', 'formidable' ), | |
| 3542 | + 'no_save_warning' => __( 'Warning: There is no way to retrieve unsaved entries.', 'formidable' ), | |
| 3543 | + 'private_label' => __( 'Private', 'formidable' ), | |
| 3544 | + 'jquery_ui_url' => '', | |
| 3545 | + 'pro_url' => is_callable( 'FrmProAppHelper::plugin_url' ) ? FrmProAppHelper::plugin_url() : '', | |
| 3546 | + 'no_licenses' => __( 'No new licenses were found', 'formidable' ), | |
| 3547 | + 'unmatched_parens' => __( 'This calculation has at least one unmatched ( ) { } [ ].', 'formidable' ), | |
| 3548 | + 'view_shortcodes' => __( 'This calculation may have shortcodes that work in Views but not forms.', 'formidable' ), | |
| 3549 | + 'text_shortcodes' => __( 'This calculation may have shortcodes that work in text calculations but not numeric calculations.', 'formidable' ), | |
| 3550 | + /* translators: %d is the number of allowed actions per form */ | |
| 3551 | + 'only_one_action' => sprintf( __( 'This form action is limited to %d per form.', 'formidable' ), 1 ), | |
| 3552 | + 'edit_action_text' => __( 'Please edit the existing form action.', 'formidable' ), | |
| 3553 | + 'unsafe_params' => FrmFormsHelper::reserved_words(), | |
| 3066 | 3554 | /* Translators: %s is the name of a Detail Page Slug that is a reserved word.*/ |
| 3067 | - 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ), | |
| 3555 | + 'slug_is_reserved' => sprintf( __( 'The Detail Page Slug "%s" is reserved by WordPress. This may cause problems. Is this intentional?', 'formidable' ), '****' ), | |
| 3068 | 3556 | /* Translators: %s is the name of a parameter that is a reserved word. More than one word could be listed here, though that would not be common. */ |
| 3069 | - 'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ), | |
| 3070 | - 'reserved_words' => __( 'See the list of reserved words in WordPress.', 'formidable' ), | |
| 3071 | - 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ), | |
| 3072 | - 'checkbox_limit' => __( 'Please select a limit between 0 and 200.', 'formidable' ), | |
| 3073 | - 'install' => __( 'Install', 'formidable' ), | |
| 3074 | - 'active' => __( 'Active', 'formidable' ), | |
| 3075 | - 'select_a_field' => __( 'Select a Field', 'formidable' ), | |
| 3076 | - 'no_items_found' => __( 'No items found.', 'formidable' ), | |
| 3077 | - 'field_already_used' => __( 'Oops. You have already used that field.', 'formidable' ), | |
| 3078 | - 'saving' => '', // Deprecated in 6.0. | |
| 3079 | - 'saved' => '', // Deprecated in 6.0. | |
| 3557 | + 'param_is_reserved' => sprintf( __( 'The parameter "%s" is reserved by WordPress. This may cause problems when included in the URL. Is this intentional? ', 'formidable' ), '****' ), | |
| 3558 | + 'reserved_words' => __( 'See the list of reserved words in WordPress.', 'formidable' ), | |
| 3559 | + 'repeat_limit_min' => __( 'Please enter a Repeat Limit that is greater than 1.', 'formidable' ), | |
| 3560 | + 'checkbox_limit' => __( 'Please select a limit between 0 and 200.', 'formidable' ), | |
| 3561 | + 'install' => __( 'Install', 'formidable' ), | |
| 3562 | + 'active' => __( 'Active', 'formidable' ), | |
| 3563 | + 'installed' => __( 'Installed', 'formidable' ), | |
| 3564 | + 'not_installed' => __( 'Not Installed', 'formidable' ), | |
| 3565 | + 'select_a_field' => __( 'Select a Field', 'formidable' ), | |
| 3566 | + 'no_items_found' => __( 'No items found.', 'formidable' ), | |
| 3567 | + 'field_already_used' => __( 'Oops. You have already used that field.', 'formidable' ), | |
| 3568 | + | |
| 3569 | + // Deprecated in 6.0. | |
| 3570 | + 'saving' => '', | |
| 3571 | + | |
| 3572 | + // Deprecated in 6.0. | |
| 3573 | + 'saved' => '', | |
| 3574 | + | |
| 3575 | + // translators: %1$s: HTML open tag, %2$s: HTML end tag. | |
| 3576 | + 'holdShiftMsg' => esc_html__( 'You can hold %1$sShift%2$s on your keyboard to select multiple fields', 'formidable' ), | |
| 3577 | + 'noTitleText' => FrmFormsHelper::get_no_title_text(), | |
| 3578 | + | |
| 3579 | + // In older versions this event listener causes the section to immediately close again | |
| 3580 | + // when the h3 element is clicked. It's only required in WP 6.7+. | |
| 3581 | + 'requireAccordionTitleClickListener' => version_compare( $wp_version, '6.7', '>=' ), | |
| 3080 | 3582 | ); |
| 3081 | 3583 | /** |
| 3082 | 3584 | * @param array $admin_script_strings |
| 3083 | 3585 | */ |
| @@ -3086,9 +3588,9 @@ | ||
| 3086 | 3588 | $data = $wp_scripts->get_data( 'formidable_admin', 'data' ); |
| 3087 | 3589 | if ( ! $data ) { |
| 3088 | 3590 | wp_localize_script( 'formidable_admin', 'frm_admin_js', $admin_script_strings ); |
| 3089 | 3591 | } |
| 3090 | - } | |
| 3592 | + }//end if | |
| 3091 | 3593 | } |
| 3092 | 3594 | |
| 3093 | 3595 | /** |
| 3094 | 3596 | * @since 6.5 |
| @@ -3132,9 +3634,10 @@ | ||
| 3132 | 3634 | * Echo the message on the plugins listing page |
| 3133 | 3635 | * |
| 3134 | 3636 | * @since 1.07.10 |
| 3135 | 3637 | * |
| 3136 | - * @param float $min_version The version the add-on requires | |
| 3638 | + * @param float $min_version The version the add-on requires. | |
| 3639 | + * @return void | |
| 3137 | 3640 | */ |
| 3138 | 3641 | public static function min_version_notice( $min_version ) { |
| 3139 | 3642 | $frm_version = self::plugin_version(); |
| 3140 | 3643 | |
| @@ -3168,9 +3671,8 @@ | ||
| 3168 | 3671 | if ( ! $is_pro || self::meets_min_pro_version( $min_version ) ) { |
| 3169 | 3672 | return; |
| 3170 | 3673 | } |
| 3171 | 3674 | |
| 3172 | - $pro_version = FrmProDb::$plug_version; | |
| 3173 | 3675 | $expired = FrmAddonsController::is_license_expired(); |
| 3174 | 3676 | ?> |
| 3175 | 3677 | <div class="frm-banner-alert frm_error_style frm_previous_install"> |
| 3176 | 3678 | <?php |
| @@ -3188,8 +3690,11 @@ | ||
| 3188 | 3690 | /** |
| 3189 | 3691 | * If Pro is installed, check the version number. |
| 3190 | 3692 | * |
| 3191 | 3693 | * @since 4.0.01 |
| 3694 | + * | |
| 3695 | + * @param string $min_version | |
| 3696 | + * @return bool | |
| 3192 | 3697 | */ |
| 3193 | 3698 | public static function meets_min_pro_version( $min_version ) { |
| 3194 | 3699 | return ! class_exists( 'FrmProDb' ) || version_compare( FrmProDb::$plug_version, $min_version, '>=' ); |
| 3195 | 3700 | } |
| @@ -3194,24 +3699,19 @@ | ||
| 3194 | 3699 | return ! class_exists( 'FrmProDb' ) || version_compare( FrmProDb::$plug_version, $min_version, '>=' ); |
| 3195 | 3700 | } |
| 3196 | 3701 | |
| 3197 | 3702 | /** |
| 3198 | - * Show a message if the browser or PHP version is below the recommendations. | |
| 3703 | + * Show a message if the PHP version is below the recommendations. | |
| 3199 | 3704 | * |
| 3200 | 3705 | * @since 4.0.02 |
| 3706 | + * @return void | |
| 3201 | 3707 | */ |
| 3202 | 3708 | private static function php_version_notice() { |
| 3203 | 3709 | $message = array(); |
| 3204 | - if ( version_compare( phpversion(), '5.6', '<' ) ) { | |
| 3710 | + if ( version_compare( phpversion(), '7.0', '<' ) ) { | |
| 3205 | 3711 | $message[] = __( 'The version of PHP on your server is too low. If this is not corrected, you may see issues with Formidable Forms. Please contact your web host and ask to be updated to PHP 7.0+.', 'formidable' ); |
| 3206 | 3712 | } |
| 3207 | 3713 | |
| 3208 | - $browser = self::get_server_value( 'HTTP_USER_AGENT' ); | |
| 3209 | - $is_ie = strpos( $browser, 'MSIE' ) !== false; | |
| 3210 | - if ( $is_ie ) { | |
| 3211 | - $message[] = __( 'You are using an outdated browser that is not compatible with Formidable Forms. Please update to a more current browser (we recommend Chrome).', 'formidable' ); | |
| 3212 | - } | |
| 3213 | - | |
| 3214 | 3714 | foreach ( $message as $m ) { |
| 3215 | 3715 | ?> |
| 3216 | 3716 | <div class="frm-banner-alert frm_error_style frm_previous_install"> |
| 3217 | 3717 | <?php echo esc_html( $m ); ?> |
| @@ -3341,16 +3841,10 @@ | ||
| 3341 | 3841 | return $locales; |
| 3342 | 3842 | } |
| 3343 | 3843 | |
| 3344 | 3844 | /** |
| 3345 | - * Output HTML containing reference text for accessibility | |
| 3346 | - * | |
| 3347 | - * @deprecated 5.1 | |
| 3845 | + * @return string | |
| 3348 | 3846 | */ |
| 3349 | - public static function multiselect_accessibility() { | |
| 3350 | - _deprecated_function( __METHOD__, '5.1' ); | |
| 3351 | - } | |
| 3352 | - | |
| 3353 | 3847 | public static function get_menu_icon_class() { |
| 3354 | 3848 | if ( is_callable( 'FrmProAppHelper::get_settings' ) ) { |
| 3355 | 3849 | $settings = FrmProAppHelper::get_settings(); |
| 3356 | 3850 | if ( is_object( $settings ) && ! empty( $settings->menu_icon ) ) { |
| @@ -3460,8 +3954,18 @@ | ||
| 3460 | 3954 | return apply_filters( 'frm_images_dropdown_input_attrs', $input_attrs_str, $args ); |
| 3461 | 3955 | } |
| 3462 | 3956 | |
| 3463 | 3957 | /** |
| 3958 | + * @since 6.7.1 | |
| 3959 | + */ | |
| 3960 | + public static function get_images_dropdown_atts( $option, $args ) { | |
| 3961 | + $image = self::get_images_dropdown_option_image( $option, $args ); | |
| 3962 | + $classes = self::get_images_dropdown_option_classes( $option, $args ); | |
| 3963 | + $custom_attrs = self::get_images_dropdown_option_html_attrs( $option, $args ); | |
| 3964 | + return compact( 'image', 'classes', 'custom_attrs' ); | |
| 3965 | + } | |
| 3966 | + | |
| 3967 | + /** | |
| 3464 | 3968 | * Gets the image of each option in images_dropdown() method. |
| 3465 | 3969 | * |
| 3466 | 3970 | * @since 5.0.04 |
| 3467 | 3971 | * |
| @@ -3472,9 +3976,9 @@ | ||
| 3472 | 3976 | private static function get_images_dropdown_option_image( $option, $args ) { |
| 3473 | 3977 | $image = self::icon_by_class( |
| 3474 | 3978 | 'frmfont ' . $option['svg'], |
| 3475 | 3979 | array( |
| 3476 | - 'echo' => false, | |
| 3980 | + 'echo' => false, | |
| 3477 | 3981 | ) |
| 3478 | 3982 | ); |
| 3479 | 3983 | |
| 3480 | 3984 | $args['option'] = $option; |
| @@ -3612,15 +4116,15 @@ | ||
| 3612 | 4116 | return $values; |
| 3613 | 4117 | } |
| 3614 | 4118 | |
| 3615 | 4119 | /** |
| 3616 | - * Some back end fields allow privleged users to add scripts. | |
| 4120 | + * Some back end fields allow privileged users to add scripts. | |
| 3617 | 4121 | * A site that uses the DISALLOW_UNFILTERED_HTML always remove scripts on echo. |
| 3618 | 4122 | * |
| 3619 | 4123 | * @since 5.0.13 |
| 3620 | 4124 | * |
| 3621 | 4125 | * @param string $value |
| 3622 | - * @param array|string $allowed 'all' for everything included as defaults | |
| 4126 | + * @param array|string $allowed 'all' for everything included as defaults. | |
| 3623 | 4127 | * @return string |
| 3624 | 4128 | */ |
| 3625 | 4129 | public static function maybe_kses( $value, $allowed = 'all' ) { |
| 3626 | 4130 | if ( self::should_never_allow_unfiltered_html() ) { |
| @@ -3629,8 +4133,64 @@ | ||
| 3629 | 4133 | return $value; |
| 3630 | 4134 | } |
| 3631 | 4135 | |
| 3632 | 4136 | /** |
| 4137 | + * Check if an option attribute used in an [input] shortcode is safe. | |
| 4138 | + * | |
| 4139 | + * @since 6.11.2 | |
| 4140 | + * | |
| 4141 | + * @param string $key | |
| 4142 | + * @param string $context Either 'display' or 'update'. On update, we want to allow a few keys that are never displayed. | |
| 4143 | + * @return bool | |
| 4144 | + */ | |
| 4145 | + public static function input_key_is_safe( $key, $context = 'display' ) { | |
| 4146 | + if ( 'update' === $context && in_array( $key, array( 'opt', 'label' ), true ) ) { | |
| 4147 | + $safe = true; | |
| 4148 | + } elseif ( 0 === strpos( $key, 'data-' ) ) { | |
| 4149 | + // Allow all data attributes. | |
| 4150 | + $safe = true; | |
| 4151 | + } elseif ( 0 === strpos( $key, 'aria-' ) ) { | |
| 4152 | + // Allow all aria attributes. | |
| 4153 | + $safe = true; | |
| 4154 | + } else { | |
| 4155 | + $safe_keys = array( | |
| 4156 | + 'class', | |
| 4157 | + 'required', | |
| 4158 | + 'title', | |
| 4159 | + 'placeholder', | |
| 4160 | + 'value', | |
| 4161 | + 'readonly', | |
| 4162 | + 'disabled', | |
| 4163 | + 'size', | |
| 4164 | + 'maxlength', | |
| 4165 | + 'min', | |
| 4166 | + 'max', | |
| 4167 | + 'pattern', | |
| 4168 | + 'step', | |
| 4169 | + 'autofocus', | |
| 4170 | + 'width', | |
| 4171 | + 'height', | |
| 4172 | + 'autocomplete', | |
| 4173 | + 'tabindex', | |
| 4174 | + 'role', | |
| 4175 | + 'style', | |
| 4176 | + ); | |
| 4177 | + $safe = in_array( $key, $safe_keys, true ); | |
| 4178 | + }//end if | |
| 4179 | + | |
| 4180 | + /** | |
| 4181 | + * Filter the $safe value so additional keys can be allowed or disallowed. | |
| 4182 | + * | |
| 4183 | + * @since 6.11.2 | |
| 4184 | + * | |
| 4185 | + * @param bool $safe True if the key is considered safe. | |
| 4186 | + * @param string $key | |
| 4187 | + * @param string $context Either 'display' or 'update'. | |
| 4188 | + */ | |
| 4189 | + return (bool) apply_filters( 'frm_input_key_is_safe', $safe, $key, $context ); | |
| 4190 | + } | |
| 4191 | + | |
| 4192 | + /** | |
| 3633 | 4193 | * @since 5.0.16 |
| 3634 | 4194 | * |
| 3635 | 4195 | * @return bool |
| 3636 | 4196 | */ |
| @@ -3655,20 +4215,9 @@ | ||
| 3655 | 4215 | |
| 3656 | 4216 | /** |
| 3657 | 4217 | * @since 5.0.17 |
| 3658 | 4218 | * |
| 3659 | - * @param string $plugin | |
| 3660 | - * @return string|false | |
| 3661 | - */ | |
| 3662 | - private static function get_plan_required( $plugin ) { | |
| 3663 | - $link = FrmAddonsController::install_link( $plugin ); | |
| 3664 | - return FrmFormsHelper::get_plan_required( $link ); | |
| 3665 | - } | |
| 3666 | - | |
| 3667 | - /** | |
| 3668 | - * @since 5.0.17 | |
| 3669 | - * | |
| 3670 | - * @param string | |
| 4219 | + * @param string $feature | |
| 3671 | 4220 | * @return bool |
| 3672 | 4221 | */ |
| 3673 | 4222 | public static function show_new_feature( $feature ) { |
| 3674 | 4223 | $link = FrmAddonsController::install_link( $feature ); |
| @@ -3741,9 +4290,9 @@ | ||
| 3741 | 4290 | public static function show_pill_text( $text = null ) { |
| 3742 | 4291 | if ( null === $text ) { |
| 3743 | 4292 | $text = __( 'NEW', 'formidable' ); |
| 3744 | 4293 | } |
| 3745 | - echo '<span class="frm-new-pill">' . esc_html( $text ) . '</span>'; | |
| 4294 | + echo '<span class="frm-meta-tag frm-new-pill">' . esc_html( $text ) . '</span>'; | |
| 3746 | 4295 | } |
| 3747 | 4296 | |
| 3748 | 4297 | /** |
| 3749 | 4298 | * Count the number of decimals digits. |
| @@ -3750,9 +4299,9 @@ | ||
| 3750 | 4299 | * |
| 3751 | 4300 | * @since 5.2.07 |
| 3752 | 4301 | * |
| 3753 | 4302 | * @param mixed $num Number. |
| 3754 | - * @return int|false Returns `false` if the passed parameter is not number. | |
| 4303 | + * @return false|int Returns `false` if the passed parameter is not number. | |
| 3755 | 4304 | */ |
| 3756 | 4305 | public static function count_decimals( $num ) { |
| 3757 | 4306 | if ( ! is_numeric( $num ) ) { |
| 3758 | 4307 | return false; |
| @@ -3783,9 +4332,9 @@ | ||
| 3783 | 4332 | } |
| 3784 | 4333 | |
| 3785 | 4334 | add_filter( |
| 3786 | 4335 | 'option_gmt_offset', |
| 3787 | - function( $offset ) { | |
| 4336 | + function ( $offset ) { | |
| 3788 | 4337 | if ( ! is_string( $offset ) || is_numeric( $offset ) ) { |
| 3789 | 4338 | // Leave a valid value alone. |
| 3790 | 4339 | return $offset; |
| 3791 | 4340 | } |
| @@ -3867,65 +4416,8 @@ | ||
| 3867 | 4416 | return true; |
| 3868 | 4417 | } |
| 3869 | 4418 | |
| 3870 | 4419 | /** |
| 3871 | - * @since 4.08 | |
| 3872 | - * @deprecated 4.09.01 | |
| 3873 | - */ | |
| 3874 | - public static function expiring_message() { | |
| 3875 | - _deprecated_function( __METHOD__, '4.09.01', 'FrmProAddonsController::expiring_message' ); | |
| 3876 | - if ( is_callable( 'FrmProAddonsController::expiring_message' ) ) { | |
| 3877 | - FrmProAddonsController::expiring_message(); | |
| 3878 | - } | |
| 3879 | - } | |
| 3880 | - | |
| 3881 | - /** | |
| 3882 | - * Use the WP 4.7 wp_doing_ajax function | |
| 3883 | - * | |
| 3884 | - * @since 2.05.07 | |
| 3885 | - * @deprecated 4.04.04 | |
| 3886 | - */ | |
| 3887 | - public static function wp_doing_ajax() { | |
| 3888 | - _deprecated_function( __METHOD__, '4.04.04', 'wp_doing_ajax' ); | |
| 3889 | - return wp_doing_ajax(); | |
| 3890 | - } | |
| 3891 | - | |
| 3892 | - /** | |
| 3893 | - * @deprecated 4.0 | |
| 3894 | - */ | |
| 3895 | - public static function insert_opt_html( $args ) { | |
| 3896 | - _deprecated_function( __METHOD__, '4.0', 'FrmFormsHelper::insert_opt_html' ); | |
| 3897 | - FrmFormsHelper::insert_opt_html( $args ); | |
| 3898 | - } | |
| 3899 | - | |
| 3900 | - /** | |
| 3901 | - * @deprecated 3.01 | |
| 3902 | - * @codeCoverageIgnore | |
| 3903 | - */ | |
| 3904 | - public static function sanitize_array( &$values ) { | |
| 3905 | - FrmDeprecated::sanitize_array( $values ); | |
| 3906 | - } | |
| 3907 | - | |
| 3908 | - /** | |
| 3909 | - * @since 2.0 | |
| 3910 | - * @deprecated 5.0.13 | |
| 3911 | - * | |
| 3912 | - * @return string The base Google APIS url for the current version of jQuery UI | |
| 3913 | - */ | |
| 3914 | - public static function jquery_ui_base_url() { | |
| 3915 | - _deprecated_function( __FUNCTION__, '5.0.13', 'FrmProAppHelper::jquery_ui_base_url' ); | |
| 3916 | - return is_callable( 'FrmProAppHelper::jquery_ui_base_url' ) ? FrmProAppHelper::jquery_ui_base_url() : ''; | |
| 3917 | - } | |
| 3918 | - | |
| 3919 | - /** | |
| 3920 | - * @since 4.07 | |
| 3921 | - * @deprecated 6.0 | |
| 3922 | - */ | |
| 3923 | - public static function renewal_message() { | |
| 3924 | - _deprecated_function( __METHOD__, '6.0', 'FrmProAddonsController::renewal_message' ); | |
| 3925 | - } | |
| 3926 | - | |
| 3927 | - /** | |
| 3928 | 4420 | * Display a dismissable warning message and save its dismissal state. |
| 3929 | 4421 | * |
| 3930 | 4422 | * @since 6.3 |
| 3931 | 4423 | * |
| @@ -3937,9 +4429,9 @@ | ||
| 3937 | 4429 | if ( ! $message || ! $option ) { |
| 3938 | 4430 | return; |
| 3939 | 4431 | } |
| 3940 | 4432 | |
| 3941 | - $ajax_callback = function() use ( $option ) { | |
| 4433 | + $ajax_callback = function () use ( $option ) { | |
| 3942 | 4434 | self::dismiss_warning_message( $option ); |
| 3943 | 4435 | }; |
| 3944 | 4436 | |
| 3945 | 4437 | // We're handling JS codes with `doJsonPost` and it adds 'frm_' to the beginning of the action. |
| @@ -3947,9 +4439,9 @@ | ||
| 3947 | 4439 | add_action( 'wp_ajax_frm_' . $option, $ajax_callback ); |
| 3948 | 4440 | |
| 3949 | 4441 | add_filter( |
| 3950 | 4442 | 'frm_message_list', |
| 3951 | - function( $show_messages ) use ( $message, $option ) { | |
| 4443 | + function ( $show_messages ) use ( $message, $option ) { | |
| 3952 | 4444 | if ( get_option( $option, false ) ) { |
| 3953 | 4445 | return $show_messages; |
| 3954 | 4446 | } |
| 3955 | 4447 | |
| @@ -3956,9 +4448,9 @@ | ||
| 3956 | 4448 | $dismiss_icon = self::icon_by_class( |
| 3957 | 4449 | 'frmfont frm_close_icon', |
| 3958 | 4450 | array( |
| 3959 | 4451 | 'aria-label' => _x( 'Dismiss', 'warning message: close icon label', 'formidable' ), |
| 3960 | - 'echo' => false, | |
| 4452 | + 'echo' => false, | |
| 3961 | 4453 | ) |
| 3962 | 4454 | ); |
| 3963 | 4455 | |
| 3964 | 4456 | $show_messages[] = $message; |
| @@ -3985,6 +4477,124 @@ | ||
| 3985 | 4477 | update_option( $option, true, 'no' ); |
| 3986 | 4478 | } |
| 3987 | 4479 | |
| 3988 | 4480 | wp_send_json_success(); |
| 4481 | + } | |
| 4482 | + | |
| 4483 | + /** | |
| 4484 | + * Lite license copy. | |
| 4485 | + * Used in FrmDashboardController & FrmSettingsController | |
| 4486 | + * | |
| 4487 | + * @since 6.8 | |
| 4488 | + * | |
| 4489 | + * @return string | |
| 4490 | + */ | |
| 4491 | + public static function copy_for_lite_license() { | |
| 4492 | + $message = __( 'You\'re using Formidable Forms Lite - no license needed. Enjoy!', 'formidable' ) . ' 🙂'; | |
| 4493 | + | |
| 4494 | + if ( is_callable( 'FrmProAddonsController::get_readable_license_type' ) && ! class_exists( 'FrmProDashboardController' ) ) { | |
| 4495 | + // Manage PRO versions without PRO dashboard functionality. | |
| 4496 | + $license_type = FrmProAddonsController::get_readable_license_type(); | |
| 4497 | + if ( 'lite' !== strtolower( $license_type ) ) { | |
| 4498 | + $message = 'Formidable Pro ' . $license_type; | |
| 4499 | + } | |
| 4500 | + } | |
| 4501 | + | |
| 4502 | + return apply_filters( 'frm_license_type_text', $message ); | |
| 4503 | + } | |
| 4504 | + | |
| 4505 | + /** | |
| 4506 | + * Removes scripts that are unnecessarily loaded across the pages! | |
| 4507 | + * | |
| 4508 | + * @since 6.9 | |
| 4509 | + * @return void | |
| 4510 | + */ | |
| 4511 | + public static function dequeue_extra_global_scripts() { | |
| 4512 | + wp_dequeue_script( 'frm-surveys-admin' ); | |
| 4513 | + wp_dequeue_script( 'frm-quizzes-form-action' ); | |
| 4514 | + } | |
| 4515 | + | |
| 4516 | + /** | |
| 4517 | + * Shows tooltip icon. | |
| 4518 | + * | |
| 4519 | + * @since 6.12 | |
| 4520 | + * | |
| 4521 | + * @param string $tooltip_text Tooltip text. | |
| 4522 | + * @param array $atts Tooltip wrapper HTML attributes. | |
| 4523 | + * | |
| 4524 | + * @return void | |
| 4525 | + */ | |
| 4526 | + public static function tooltip_icon( $tooltip_text, $atts = array() ) { | |
| 4527 | + $atts['title'] = $tooltip_text; | |
| 4528 | + if ( isset( $atts['class'] ) ) { | |
| 4529 | + $atts['class'] .= ' frm_help'; | |
| 4530 | + } else { | |
| 4531 | + $atts['class'] = 'frm_help'; | |
| 4532 | + } | |
| 4533 | + ?> | |
| 4534 | + <span <?php self::array_to_html_params( $atts, true ); ?>> | |
| 4535 | + <?php self::icon_by_class( 'frmfont frm_tooltip_icon' ); ?> | |
| 4536 | + </span> | |
| 4537 | + <?php | |
| 4538 | + } | |
| 4539 | + | |
| 4540 | + /** | |
| 4541 | + * Prints errors for settings in onboarding wizard or template settings. | |
| 4542 | + * | |
| 4543 | + * @since 6.15 | |
| 4544 | + * | |
| 4545 | + * @param array $args Args. | |
| 4546 | + * | |
| 4547 | + * @return void | |
| 4548 | + */ | |
| 4549 | + public static function print_setting_error( $args ) { | |
| 4550 | + $args = wp_parse_args( | |
| 4551 | + $args, | |
| 4552 | + array( | |
| 4553 | + 'id' => '', | |
| 4554 | + 'errors' => array(), | |
| 4555 | + 'class' => '', | |
| 4556 | + ) | |
| 4557 | + ); | |
| 4558 | + | |
| 4559 | + $args['class'] .= ' frm-validation-error frm-mt-xs frm_hidden'; | |
| 4560 | + ?> | |
| 4561 | + <span id="<?php echo esc_attr( $args['id'] ); ?>" class="<?php echo esc_attr( $args['class'] ); ?>"> | |
| 4562 | + <?php | |
| 4563 | + if ( is_array( $args['errors'] ) ) { | |
| 4564 | + foreach ( $args['errors'] as $key => $msg ) { | |
| 4565 | + ?> | |
| 4566 | + <span frm-error="<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $msg ); ?></span> | |
| 4567 | + <?php | |
| 4568 | + } | |
| 4569 | + } else { | |
| 4570 | + echo '<span>' . esc_html( $args['errors'] ) . '</span>'; | |
| 4571 | + } | |
| 4572 | + ?> | |
| 4573 | + </span> | |
| 4574 | + <?php | |
| 4575 | + } | |
| 4576 | + | |
| 4577 | + /** | |
| 4578 | + * Check if GDPR is enabled. | |
| 4579 | + * | |
| 4580 | + * @since 6.19 | |
| 4581 | + * | |
| 4582 | + * @return bool | |
| 4583 | + */ | |
| 4584 | + public static function is_gdpr_enabled() { | |
| 4585 | + $frm_settings = self::get_settings(); | |
| 4586 | + return $frm_settings->enable_gdpr || $frm_settings->no_ips || $frm_settings->custom_header_ip || $frm_settings->no_gdpr_cookies; | |
| 4587 | + } | |
| 4588 | + | |
| 4589 | + /** | |
| 4590 | + * Check if GDPR cookies are disabled. | |
| 4591 | + * | |
| 4592 | + * @since 6.19 | |
| 4593 | + * | |
| 4594 | + * @return bool | |
| 4595 | + */ | |
| 4596 | + public static function no_gdpr_cookies() { | |
| 4597 | + $frm_settings = self::get_settings(); | |
| 4598 | + return $frm_settings->enable_gdpr && $frm_settings->no_gdpr_cookies; | |
| 3989 | 4599 | } |
| 3990 | 4600 | } |