Sin descripción

admin.php 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. <?php
  2. /**
  3. * Global admin related items and functionality.
  4. *
  5. * @since 1.3.9
  6. */
  7. /**
  8. * Load styles for all WPForms-related admin screens.
  9. *
  10. * @since 1.3.9
  11. */
  12. function wpforms_admin_styles() {
  13. if ( ! wpforms_is_admin_page() ) {
  14. return;
  15. }
  16. $min = wpforms_get_min_suffix();
  17. // jQuery confirm.
  18. wp_enqueue_style(
  19. 'jquery-confirm',
  20. WPFORMS_PLUGIN_URL . 'assets/css/jquery-confirm.min.css',
  21. array(),
  22. '3.3.2'
  23. );
  24. // Minicolors (color picker).
  25. wp_enqueue_style(
  26. 'minicolors',
  27. WPFORMS_PLUGIN_URL . 'assets/css/jquery.minicolors.css',
  28. array(),
  29. '2.2.6'
  30. );
  31. // FontAwesome.
  32. wp_enqueue_style(
  33. 'wpforms-font-awesome',
  34. WPFORMS_PLUGIN_URL . 'assets/css/font-awesome.min.css',
  35. null,
  36. '4.7.0'
  37. );
  38. // Main admin styles.
  39. wp_enqueue_style(
  40. 'wpforms-admin',
  41. WPFORMS_PLUGIN_URL . "assets/css/admin{$min}.css",
  42. array(),
  43. WPFORMS_VERSION
  44. );
  45. // Remove TinyMCE editor styles from third-party themes and plugins.
  46. remove_editor_styles();
  47. // WordPress 5.7 color set.
  48. if ( version_compare( get_bloginfo( 'version' ), '5.7', '>=' ) ) {
  49. wp_enqueue_style(
  50. 'wpforms-admin-wp5.7-color',
  51. WPFORMS_PLUGIN_URL . "assets/css/admin-wp5.7-colors{$min}.css",
  52. [ 'wpforms-admin' ],
  53. WPFORMS_VERSION
  54. );
  55. }
  56. }
  57. add_action( 'admin_enqueue_scripts', 'wpforms_admin_styles' );
  58. /**
  59. * Load scripts for all WPForms-related admin screens.
  60. *
  61. * @since 1.3.9
  62. */
  63. function wpforms_admin_scripts() {
  64. if ( ! wpforms_is_admin_page() ) {
  65. return;
  66. }
  67. $min = wpforms_get_min_suffix();
  68. wp_enqueue_media();
  69. // jQuery confirm.
  70. wp_enqueue_script(
  71. 'jquery-confirm',
  72. WPFORMS_PLUGIN_URL . 'assets/js/jquery.jquery-confirm.min.js',
  73. [ 'jquery' ],
  74. '3.3.2',
  75. false
  76. );
  77. // Minicolors (color picker).
  78. wp_enqueue_script(
  79. 'minicolors',
  80. WPFORMS_PLUGIN_URL . 'assets/js/jquery.minicolors.min.js',
  81. [ 'jquery' ],
  82. '2.2.6',
  83. false
  84. );
  85. // Choices.js.
  86. wp_enqueue_script(
  87. 'choicesjs',
  88. WPFORMS_PLUGIN_URL . 'assets/js/choices.min.js',
  89. [],
  90. '9.0.1',
  91. false
  92. );
  93. // jQuery Conditionals.
  94. wp_enqueue_script(
  95. 'jquery-conditionals',
  96. WPFORMS_PLUGIN_URL . 'assets/js/jquery.conditionals.min.js',
  97. [ 'jquery' ],
  98. '1.0.1',
  99. false
  100. );
  101. // Main admin script.
  102. wp_enqueue_script(
  103. 'wpforms-admin',
  104. WPFORMS_PLUGIN_URL . "assets/js/admin{$min}.js",
  105. [ 'jquery' ],
  106. WPFORMS_VERSION,
  107. false
  108. );
  109. $strings = [
  110. 'addon_activate' => esc_html__( 'Activate', 'wpforms-lite' ),
  111. 'addon_activated' => esc_html__( 'Activated', 'wpforms-lite' ),
  112. 'addon_active' => esc_html__( 'Active', 'wpforms-lite' ),
  113. 'addon_deactivate' => esc_html__( 'Deactivate', 'wpforms-lite' ),
  114. 'addon_inactive' => esc_html__( 'Inactive', 'wpforms-lite' ),
  115. 'addon_install' => esc_html__( 'Install Addon', 'wpforms-lite' ),
  116. 'addon_error' => esc_html__( 'Could not install the addon. Please download it from wpforms.com and install it manually.', 'wpforms-lite' ),
  117. 'plugin_error' => esc_html__( 'Could not install the plugin automatically. Please download and install it manually.', 'wpforms-lite' ),
  118. 'addon_search' => esc_html__( 'Searching Addons', 'wpforms-lite' ),
  119. 'ajax_url' => admin_url( 'admin-ajax.php' ),
  120. 'cancel' => esc_html__( 'Cancel', 'wpforms-lite' ),
  121. 'close' => esc_html__( 'Close', 'wpforms-lite' ),
  122. 'entry_delete_confirm' => esc_html__( 'Are you sure you want to delete this entry and all its information (files, notes, logs, etc.)?', 'wpforms-lite' ),
  123. 'entry_delete_all_confirm' => esc_html__( 'Are you sure you want to delete ALL entries and all their information (files, notes, logs, etc.)?', 'wpforms-lite' ),
  124. 'entry_delete_n_confirm' => sprintf( /* translators: %s - entry count. */
  125. esc_html__( 'Are you sure you want to delete %s entry(s) and all the information (files, notes, logs, etc.)?', 'wpforms-lite' ),
  126. '{entry_count}'
  127. ),
  128. 'entry_empty_fields_hide' => esc_html__( 'Hide Empty Fields', 'wpforms-lite' ),
  129. 'entry_empty_fields_show' => esc_html__( 'Show Empty Fields', 'wpforms-lite' ),
  130. 'entry_field_columns' => esc_html__( 'Entries Field Columns', 'wpforms-lite' ),
  131. 'entry_note_delete_confirm' => esc_html__( 'Are you sure you want to delete this note?', 'wpforms-lite' ),
  132. 'entry_unstar' => esc_html__( 'Unstar entry', 'wpforms-lite' ),
  133. 'entry_star' => esc_html__( 'Star entry', 'wpforms-lite' ),
  134. 'entry_read' => esc_html__( 'Mark entry read', 'wpforms-lite' ),
  135. 'entry_unread' => esc_html__( 'Mark entry unread', 'wpforms-lite' ),
  136. 'form_delete_confirm' => esc_html__( 'Are you sure you want to delete this form and all its information?', 'wpforms-lite' ),
  137. 'form_duplicate_confirm' => esc_html__( 'Are you sure you want to duplicate this form?', 'wpforms-lite' ),
  138. 'heads_up' => esc_html__( 'Heads up!', 'wpforms-lite' ),
  139. 'importer_forms_required' => esc_html__( 'Please select at least one form to import.', 'wpforms-lite' ),
  140. 'isPro' => wpforms()->pro,
  141. 'nonce' => wp_create_nonce( 'wpforms-admin' ),
  142. 'almost_done' => esc_html__( 'Almost Done', 'wpforms-lite' ),
  143. 'oops' => esc_html__( 'Oops!', 'wpforms-lite' ),
  144. 'ok' => esc_html__( 'OK', 'wpforms-lite' ),
  145. 'plugin_install_activate_btn' => esc_html__( 'Install and Activate', 'wpforms-lite' ),
  146. 'plugin_install_activate_confirm' => esc_html__( 'needs to be installed and activated to import its forms. Would you like us to install and activate it for you?', 'wpforms-lite' ),
  147. 'plugin_activate_btn' => esc_html__( 'Activate', 'wpforms-lite' ),
  148. 'plugin_activate_confirm' => esc_html__( 'needs to be activated to import its forms. Would you like us to activate it for you?', 'wpforms-lite' ),
  149. 'provider_delete_confirm' => esc_html__( 'Are you sure you want to disconnect this account?', 'wpforms-lite' ),
  150. 'provider_delete_error' => esc_html__( 'Could not disconnect this account.', 'wpforms-lite' ),
  151. 'provider_auth_error' => esc_html__( 'Could not authenticate with the provider.', 'wpforms-lite' ),
  152. 'save_refresh' => esc_html__( 'Save and Refresh', 'wpforms-lite' ),
  153. 'server_error' => esc_html__( 'Unfortunately there was a server connection error.', 'wpforms-lite' ),
  154. 'settings_form_style_base' => sprintf(
  155. wp_kses( /* translators: %s - WPForms.com docs page URL. */
  156. __( 'You\'ve selected <strong>Base Styling Only</strong>, which may result in styling issues. <a href="%s" target="_blank" rel="noopener noreferrer">Please check out our tutorial</a> for common issues and recommendations.', 'wpforms-lite' ),
  157. [
  158. 'strong' => [],
  159. 'a' => [
  160. 'href' => [],
  161. 'target' => [],
  162. 'rel' => [],
  163. ],
  164. ]
  165. ),
  166. 'https://wpforms.com/docs/how-to-choose-an-include-form-styling-setting/'
  167. ),
  168. 'settings_form_style_none' => sprintf(
  169. wp_kses( /* translators: %s - WPForms.com docs page URL. */
  170. __( 'You\'ve selected <strong>No Styling</strong>, which will likely result in significant styling issues and is recommended only for developers. <a href="%s" target="_blank" rel="noopener noreferrer">Please check out our tutorial</a> for more details and recommendations.', 'wpforms-lite' ),
  171. [
  172. 'strong' => [],
  173. 'a' => [
  174. 'href' => [],
  175. 'target' => [],
  176. 'rel' => [],
  177. ],
  178. ]
  179. ),
  180. 'https://wpforms.com/docs/how-to-choose-an-include-form-styling-setting/'
  181. ),
  182. 'testing' => esc_html__( 'Testing', 'wpforms-lite' ),
  183. 'upgrade_completed' => esc_html__( 'Upgrade was successfully completed!', 'wpforms-lite' ),
  184. 'upload_image_title' => esc_html__( 'Upload or Choose Your Image', 'wpforms-lite' ),
  185. 'upload_image_button' => esc_html__( 'Use Image', 'wpforms-lite' ),
  186. 'upgrade_modal' => wpforms_get_upgrade_modal_text(),
  187. 'choicesjs_loading' => esc_html__( 'Loading...', 'wpforms-lite' ),
  188. 'choicesjs_no_results' => esc_html__( 'No results found', 'wpforms-lite' ),
  189. 'choicesjs_no_choices' => esc_html__( 'No choices to choose from', 'wpforms-lite' ),
  190. 'choicesjs_item_select' => esc_html__( 'Press to select', 'wpforms-lite' ),
  191. 'debug' => wpforms_debug(),
  192. 'edit_license' => esc_html__( 'To edit the License Key, please first click the Deactivate Key button. Please note that deactivating this key will remove access to updates, addons, and support.', 'wpforms-lite' ),
  193. 'something_went_wrong' => esc_html__( 'Something went wrong', 'wpforms-lite' ),
  194. ];
  195. $strings = apply_filters( 'wpforms_admin_strings', $strings );
  196. wp_localize_script(
  197. 'wpforms-admin',
  198. 'wpforms_admin',
  199. $strings
  200. );
  201. }
  202. add_action( 'admin_enqueue_scripts', 'wpforms_admin_scripts' );
  203. /**
  204. * Add body class to WPForms admin pages for easy reference.
  205. *
  206. * @since 1.3.9
  207. *
  208. * @param string $classes CSS classes, space separated.
  209. *
  210. * @return string
  211. */
  212. function wpforms_admin_body_class( $classes ) {
  213. if ( ! wpforms_is_admin_page() ) {
  214. return $classes;
  215. }
  216. return "$classes wpforms-admin-page";
  217. }
  218. add_filter( 'admin_body_class', 'wpforms_admin_body_class', 10, 1 );
  219. /**
  220. * Output the WPForms admin header.
  221. *
  222. * @since 1.3.9
  223. */
  224. function wpforms_admin_header() {
  225. // Bail if we're not on a WPForms screen or page (also exclude form builder).
  226. if ( ! wpforms_is_admin_page() ) {
  227. return;
  228. }
  229. if ( ! apply_filters( 'wpforms_admin_header', true ) ) {
  230. return;
  231. }
  232. // Omit header from Welcome activation screen.
  233. if ( 'wpforms-getting-started' === $_REQUEST['page'] ) {
  234. return;
  235. }
  236. do_action( 'wpforms_admin_header_before' );
  237. ?>
  238. <div id="wpforms-header-temp"></div>
  239. <div id="wpforms-header" class="wpforms-header">
  240. <img class="wpforms-header-logo" src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/logo.png" alt="WPForms Logo"/>
  241. </div>
  242. <?php
  243. do_action( 'wpforms_admin_header_after' );
  244. }
  245. add_action( 'in_admin_header', 'wpforms_admin_header', 100 );
  246. /**
  247. * Remove non-WPForms notices from WPForms pages.
  248. *
  249. * @since 1.3.9
  250. * @since 1.6.9 Added callback for removing on `admin_footer` hook.
  251. */
  252. function wpforms_admin_hide_unrelated_notices() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded, Generic.Metrics.NestingLevel.MaxExceeded
  253. if ( ! wpforms_is_admin_page() ) {
  254. return;
  255. }
  256. global $wp_filter;
  257. // Define rules to remove callbacks.
  258. $rules = [
  259. 'user_admin_notices' => [], // remove all callbacks.
  260. 'admin_notices' => [],
  261. 'all_admin_notices' => [],
  262. 'admin_footer' => [
  263. 'render_delayed_admin_notices', // remove this particular callback.
  264. ],
  265. ];
  266. // Extra deny callbacks (will be removed for each hook tag defined in $rules).
  267. $common_deny_callbacks = [
  268. 'wpformsdb_admin_notice', // 'Database for WPForms' plugin.
  269. ];
  270. $notice_types = array_keys( $rules );
  271. foreach ( $notice_types as $notice_type ) {
  272. if ( empty( $wp_filter[ $notice_type ]->callbacks ) || ! is_array( $wp_filter[ $notice_type ]->callbacks ) ) {
  273. continue;
  274. }
  275. $remove_all_filters = empty( $rules[ $notice_type ] );
  276. foreach ( $wp_filter[ $notice_type ]->callbacks as $priority => $hooks ) {
  277. foreach ( $hooks as $name => $arr ) {
  278. if ( is_object( $arr['function'] ) && is_callable( $arr['function'] ) ) {
  279. if ( $remove_all_filters ) {
  280. unset( $wp_filter[ $notice_type ]->callbacks[ $priority ][ $name ] );
  281. }
  282. continue;
  283. }
  284. $class = ! empty( $arr['function'][0] ) && is_object( $arr['function'][0] ) ? strtolower( get_class( $arr['function'][0] ) ) : '';
  285. // Remove all callbacks except WPForms notices.
  286. if ( $remove_all_filters && strpos( $class, 'wpforms' ) === false ) {
  287. unset( $wp_filter[ $notice_type ]->callbacks[ $priority ][ $name ] );
  288. continue;
  289. }
  290. $cb = is_array( $arr['function'] ) ? $arr['function'][1] : $arr['function'];
  291. // Remove a specific callback.
  292. if ( ! $remove_all_filters ) {
  293. if ( in_array( $cb, $rules[ $notice_type ], true ) ) {
  294. unset( $wp_filter[ $notice_type ]->callbacks[ $priority ][ $name ] );
  295. }
  296. continue;
  297. }
  298. // Remove non-WPForms callbacks from `$common_deny_callbacks` denylist.
  299. if ( in_array( $cb, $common_deny_callbacks, true ) ) {
  300. unset( $wp_filter[ $notice_type ]->callbacks[ $priority ][ $name ] );
  301. }
  302. }
  303. }
  304. }
  305. }
  306. add_action( 'admin_print_scripts', 'wpforms_admin_hide_unrelated_notices' );
  307. /**
  308. * Upgrade link used within the various admin pages.
  309. *
  310. * Previously was only included as a method in wpforms-lite.php, but made
  311. * available globally in 1.3.9.
  312. *
  313. * @since 1.3.9
  314. *
  315. * @param string $medium URL parameter: utm_medium.
  316. * @param string $content URL parameter: utm_content.
  317. *
  318. * @return string.
  319. */
  320. function wpforms_admin_upgrade_link( $medium = 'link', $content = '' ) {
  321. $medium = apply_filters( 'wpforms_upgrade_link_medium', $medium );
  322. $license_key = wpforms_get_license_key();
  323. if ( wpforms()->pro ) {
  324. $upgrade = add_query_arg(
  325. [
  326. 'utm_source' => 'WordPress',
  327. 'utm_campaign' => 'plugin',
  328. 'utm_medium' => $medium,
  329. 'license_key' => sanitize_text_field( $license_key ),
  330. ],
  331. 'https://wpforms.com/pricing/'
  332. );
  333. } else {
  334. $upgrade = add_query_arg(
  335. [
  336. 'discount' => 'LITEUPGRADE',
  337. 'utm_source' => 'WordPress',
  338. 'utm_campaign' => 'liteplugin',
  339. 'utm_medium' => $medium,
  340. ],
  341. 'https://wpforms.com/lite-upgrade/'
  342. );
  343. }
  344. if ( ! empty( $content ) ) {
  345. $upgrade = add_query_arg( 'utm_content', $content, $upgrade );
  346. }
  347. return apply_filters( 'wpforms_upgrade_link', $upgrade );
  348. }
  349. /**
  350. * Check the current PHP version and display a notice if on unsupported PHP.
  351. *
  352. * @since 1.4.0.1
  353. * @since 1.5.0 Raising this awareness of old PHP version message from 5.2 to 5.3.
  354. */
  355. function wpforms_check_php_version() {
  356. // Display for PHP below 5.6.
  357. if ( version_compare( PHP_VERSION, '5.5', '>=' ) ) {
  358. return;
  359. }
  360. // Display for admins only.
  361. if ( ! is_super_admin() ) {
  362. return;
  363. }
  364. // Display on Dashboard page only.
  365. if ( isset( $GLOBALS['pagenow'] ) && 'index.php' !== $GLOBALS['pagenow'] ) {
  366. return;
  367. }
  368. // Display the notice, finally.
  369. \WPForms\Admin\Notice::error(
  370. '<p>' .
  371. sprintf(
  372. wp_kses( /* translators: %1$s - WPForms plugin name; %2$s - WPForms.com URL to a related doc. */
  373. __( 'Your site is running an outdated version of PHP that is no longer supported and may cause issues with %1$s. <a href="%2$s" target="_blank" rel="noopener noreferrer">Read more</a> for additional information.', 'wpforms-lite' ),
  374. [
  375. 'a' => [
  376. 'href' => [],
  377. 'target' => [],
  378. 'rel' => [],
  379. ],
  380. ]
  381. ),
  382. '<strong>WPForms</strong>',
  383. 'https://wpforms.com/docs/supported-php-version/'
  384. ) .
  385. '<br><br><em>' .
  386. wp_kses(
  387. __( '<strong>Please Note:</strong> Support for PHP 5.5 will be discontinued in 2020. After this, if no further action is taken, WPForms functionality will be disabled.', 'wpforms-lite' ),
  388. [
  389. 'strong' => [],
  390. 'em' => [],
  391. ]
  392. ) .
  393. '</em></p>'
  394. );
  395. }
  396. add_action( 'admin_init', 'wpforms_check_php_version' );
  397. /**
  398. * Get an upgrade modal text.
  399. *
  400. * @since 1.4.4
  401. *
  402. * @param string $type Either "pro" or "elite". Default is "pro".
  403. *
  404. * @return string
  405. */
  406. function wpforms_get_upgrade_modal_text( $type = 'pro' ) {
  407. switch ( $type ) {
  408. case 'elite':
  409. $level = 'WPForms Elite';
  410. break;
  411. case 'pro':
  412. default:
  413. $level = 'WPForms Pro';
  414. }
  415. return
  416. '<p>' .
  417. sprintf( /* translators: %s - license level, WPForms Pro or WPForms Elite. */
  418. esc_html__( 'Thanks for your interest in %s!', 'wpforms-lite' ),
  419. $level
  420. ) . '<br>' .
  421. sprintf(
  422. wp_kses(
  423. /* translators: %s - WPForms.com contact page URL. */
  424. __( 'If you have any questions or issues just <a href="%s" target="_blank" rel="noopener noreferrer">let us know</a>.', 'wpforms-lite' ),
  425. array(
  426. 'a' => array(
  427. 'href' => array(),
  428. 'target' => array(),
  429. 'rel' => array(),
  430. ),
  431. )
  432. ),
  433. 'https://wpforms.com/contact/'
  434. ) .
  435. '</p>' .
  436. '<p>' .
  437. sprintf(
  438. wp_kses( /* translators: %s - license level, WPForms Pro or WPForms Elite. */
  439. __( 'After purchasing a license,<br>just <strong>enter your license key on the WPForms Settings page</strong>.<br>This will let your site automatically upgrade to %s!', 'wpforms-lite' ),
  440. [
  441. 'strong' => [],
  442. 'br' => [],
  443. ]
  444. ),
  445. $level
  446. ) . '<br>' .
  447. esc_html__( '(Don\'t worry, all your forms and settings will be preserved.)', 'wpforms-lite' ) .
  448. '</p>' .
  449. '<p>' .
  450. sprintf(
  451. wp_kses( /* translators: %s - WPForms.com upgrade from Lite to paid docs page URL. */
  452. __( 'Check out <a href="%s" target="_blank" rel="noopener noreferrer">our documentation</a> for step-by-step instructions.', 'wpforms-lite' ),
  453. array(
  454. 'a' => array(
  455. 'href' => array(),
  456. 'target' => array(),
  457. 'rel' => array(),
  458. ),
  459. )
  460. ),
  461. 'https://wpforms.com/docs/upgrade-wpforms-lite-paid-license/?utm_source=WordPress&amp;utm_medium=link&amp;utm_campaign=liteplugin'
  462. ) .
  463. '</p>';
  464. }
  465. /**
  466. * Hide the wp-admin area "Version x.x" in footer on WPForms pages.
  467. *
  468. * @since 1.5.7
  469. *
  470. * @param string $text Default "Version x.x" or "Get Version x.x" text.
  471. *
  472. * @return string
  473. */
  474. function wpforms_admin_hide_wp_version( $text ) {
  475. // Reset text if we're not on a WPForms screen or page.
  476. if ( wpforms_is_admin_page() ) {
  477. return '';
  478. }
  479. return $text;
  480. }
  481. add_filter( 'update_footer', 'wpforms_admin_hide_wp_version', PHP_INT_MAX );