PluginProbe
Form Maker by 10Web – Mobile-Friendly Drag & Drop Contact Form Builder / 1.13.48
Form Maker by 10Web – Mobile-Friendly Drag & Drop Contact Form Builder v1.13.48
1.15.47 1.15.46 1.15.45 1.15.44 1.15.43 1.13.45 1.13.46 1.13.47 1.13.48 1.13.49 1.13.5 1.13.50 1.13.51 1.13.52 1.13.53 1.13.54 1.13.55 1.13.56 1.13.57 1.13.58 1.13.59 1.13.60 1.13.7 1.13.8 1.13.9 All 351 releases
form-maker / form-maker.php

form-maker.php in Form Maker by 10Web – Mobile-Friendly Drag & Drop Contact Form Builder 1.13.48, at form-maker.php

1,667 lines 90.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Form Maker
4 * Plugin URI: https://10web.io/plugins/wordpress-form-maker/?utm_source=form_maker&utm_medium=free_plugin
5 * Description: This plugin is a modern and advanced tool for easy and fast creating of a WordPress Form. The backend interface is intuitive and user friendly which allows users far from scripting and programming to create WordPress Forms.
6 * Version: 1.13.48
7 * Author: 10Web Form Builder Team
8 * Author URI: https://10web.io/plugins/?utm_source=form_maker&utm_medium=free_plugin
9 * License: GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
10 */
11
12 defined('ABSPATH') || die('Access Denied');
13
14 final class WDFM {
15 /**
16 * PLUGIN = 2 points to Contact Form Maker
17 */
18 const PLUGIN = 1;
19
20 /**
21 * The single instance of the class.
22 */
23 protected static $_instance = null;
24 /**
25 * Plugin directory path.
26 */
27 public $plugin_dir = '';
28 /**
29 * Plugin directory url.
30 */
31 public $plugin_url = '';
32 /**
33 * Plugin front urls.
34 */
35 public $front_urls = array();
36 /**
37 * Plugin main file.
38 */
39 public $main_file = '';
40 /**
41 * Plugin version.
42 */
43 public $plugin_version = '';
44 /**
45 * Plugin database version.
46 */
47 public $db_version = '';
48 /**
49 * Plugin menu slug.
50 */
51 public $menu_slug = '';
52 /**
53 * Plugin menu slug.
54 */
55 public $prefix = '';
56 public $handle_prefix = '';
57 public $css_prefix = '';
58 public $js_prefix = '';
59
60 public $nicename = '';
61 public $nonce = 'nonce_fm';
62 public $fm_form_nonce = 'fm_form_nonce';
63 public $is_free = 1;
64 public $is_demo = false;
65 public $fm_settings = array();
66
67 /**
68 * Main WDFM Instance.
69 *
70 * Ensures only one instance is loaded or can be loaded.
71 *
72 * @static
73 * @return WDFM - Main instance.
74 */
75 public static function instance() {
76 if ( is_null( self::$_instance ) ) {
77 self::$_instance = new self();
78 }
79 return self::$_instance;
80 }
81
82 public function __construct() {
83 $this->define_constants();
84 require_once($this->plugin_dir . '/framework/WDW_FM_Library.php');
85 if (is_admin()) {
86 require_once(wp_normalize_path($this->plugin_dir . '/admin/controllers/controller.php'));
87 require_once(wp_normalize_path($this->plugin_dir . '/admin/models/model.php'));
88 require_once(wp_normalize_path($this->plugin_dir . '/admin/views/view.php'));
89 }
90 $this->add_actions();
91 }
92
93 /**
94 * Define Constants.
95 */
96 private function define_constants() {
97 $this->plugin_dir = WP_PLUGIN_DIR . "/" . plugin_basename(dirname(__FILE__));
98 $this->plugin_url = plugins_url(plugin_basename(dirname(__FILE__)));
99 $this->front_urls = $this->get_front_urls();
100 $this->main_file = plugin_basename(__FILE__);
101 $this->plugin_version = '1.13.48';
102 $this->db_version = '2.13.48';
103 $this->menu_postfix = ($this->is_free == 2 ? '_fmc' : '_fm');
104 $this->plugin_postfix = ($this->is_free == 2 ? '_fmc' : '');
105 $this->menu_slug = 'manage' . $this->menu_postfix;
106 $this->prefix = 'form_maker' . $this->plugin_postfix;
107 $this->css_prefix = 'fm_';
108 $this->js_prefix = 'fm_';
109 $this->handle_prefix = ($this->is_free == 2 ? 'fmc' : 'fm');
110 $this->nicename = ($this->is_free == 2 ? __('Contact Form', $this->prefix) : __('Form Maker', $this->prefix));
111 $this->slug = ($this->is_free == 2 ? 'contact-form-maker' : 'form-maker');
112 $this->fm_settings = get_option( $this->handle_prefix . '_settings' );
113 if ( empty($this->fm_settings['fm_advanced_layout']) ) {
114 $this->fm_settings['fm_advanced_layout'] = 0;
115 }
116 if ( empty($this->fm_settings['fm_antispam_referer']) ) {
117 $this->fm_settings['fm_antispam_referer'] = 0;
118 }
119 if ( empty($this->fm_settings['fm_antispam_bot_validation']) ) {
120 $this->fm_settings['fm_antispam_bot_validation'] = 0;
121 }
122 if ( empty($this->fm_settings['fm_antispam_nonce']) ) {
123 $this->fm_settings['fm_antispam_nonce'] = 0;
124 }
125 if ( empty($this->fm_settings['fm_block_ip_exceeded_limit']) ) {
126 $this->fm_settings['fm_block_ip_exceeded_limit'] = 0;
127 }
128 if ( empty($this->fm_settings['fm_developer_mode']) ) {
129 $this->fm_settings['fm_developer_mode'] = 0;
130 }
131 if ( empty($this->fm_settings['fm_file_read']) ) {
132 $this->fm_settings['fm_file_read'] = 0;
133 }
134 if ( empty($this->fm_settings['fm_ajax_submit']) ) {
135 $this->fm_settings['fm_ajax_submit'] = 0;
136 }
137 }
138
139 /**
140 * Add actions.
141 */
142 private function add_actions() {
143 add_action('init', array($this, 'init'), 9);
144 add_action('admin_menu', array( $this, 'form_maker_options_panel' ) );
145
146 add_action('wp_ajax_manage' . $this->menu_postfix, array($this, 'form_maker_ajax')); //Post/page search on display options pages.
147 add_action('wp_ajax_get_stats' . $this->plugin_postfix, array($this, 'form_maker')); //Show statistics
148 add_action('wp_ajax_generete_csv' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Export csv.
149 add_action('wp_ajax_generete_xml' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Export xml.
150 add_action('wp_ajax_formmakerwdcaptcha' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Generete captcha image and save it code in session.
151 add_action('wp_ajax_nopriv_formmakerwdcaptcha' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Generete captcha image and save it code in session for all users.
152 add_action('wp_ajax_formmakerwdmathcaptcha' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Generete math captcha image and save it code in session.
153 add_action('wp_ajax_nopriv_formmakerwdmathcaptcha' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Generete math captcha image and save it code in session for all users.
154 add_action('wp_ajax_product_option' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Open product options on add paypal field.
155 add_action('wp_ajax_FormMakerEditCountryinPopup' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Open country list.
156 add_action('wp_ajax_FormMakerMapEditinPopup' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Open map in submissions.
157 add_action('wp_ajax_FormMakerIpinfoinPopup' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Open ip in submissions.
158 add_action('wp_ajax_show_matrix' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Edit matrix in submissions.
159 add_action('wp_ajax_FormMakerSubmits' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Open submissions in submissions.
160
161 if ( !$this->is_demo ) {
162 add_action('wp_ajax_FormMakerSQLMapping' . $this->plugin_postfix, array($this, 'form_maker_ajax')); // Add/Edit SQLMaping from form options.
163 add_action('wp_ajax_select_data_from_db' . $this->plugin_postfix, array( $this, 'form_maker_ajax' )); // select data from db.
164 }
165
166 add_action('wp_ajax_manage' . $this->plugin_postfix, array($this, 'form_maker_ajax')); //Show statistics
167
168 if ( !$this->is_free ) {
169 add_action('wp_ajax_paypal_info', array($this, 'form_maker_ajax')); // Paypal info in submissions page.
170 add_action('wp_ajax_checkpaypal', array($this, 'form_maker_ajax')); // Notify url from Paypal Sandbox.
171 add_action('wp_ajax_nopriv_checkpaypal', array($this, 'form_maker_ajax')); // Notify url from Paypal Sandbox for all users.
172 add_action('wp_ajax_get_frontend_stats', array($this, 'form_maker_ajax_frontend')); //Show statistics frontend
173 add_action('wp_ajax_nopriv_get_frontend_stats', array($this, 'form_maker_ajax_frontend')); //Show statistics frontend
174 add_action('wp_ajax_frontend_show_map', array($this, 'form_maker_ajax_frontend')); //Show map frontend
175 add_action('wp_ajax_nopriv_frontend_show_map', array($this, 'form_maker_ajax_frontend')); //Show map frontend
176 add_action('wp_ajax_frontend_show_matrix', array($this, 'form_maker_ajax_frontend')); //Show matrix frontend
177 add_action('wp_ajax_nopriv_frontend_show_matrix', array($this, 'form_maker_ajax_frontend')); //Show matrix frontend
178 add_action('wp_ajax_frontend_paypal_info', array($this, 'form_maker_ajax_frontend')); //Show paypal info frontend
179 add_action('wp_ajax_nopriv_frontend_paypal_info', array($this, 'form_maker_ajax_frontend')); //Show paypal info frontend
180 add_action('wp_ajax_frontend_generate_csv', array($this, 'form_maker_ajax_frontend')); //generate csv frontend
181 add_action('wp_ajax_nopriv_frontend_generate_csv', array($this, 'form_maker_ajax_frontend')); //generate csv frontend
182 add_action('wp_ajax_frontend_generate_xml', array($this, 'form_maker_ajax_frontend')); //generate xml frontend
183 add_action('wp_ajax_nopriv_frontend_generate_xml', array($this, 'form_maker_ajax_frontend')); //generate xml frontend
184 }
185 add_action('wp_ajax_fm_reload_input', array($this, 'form_maker_ajax_frontend'));
186 add_action('wp_ajax_nopriv_fm_reload_input', array($this, 'form_maker_ajax_frontend'));
187 add_action('wp_ajax_fm_submit_form', array($this, 'FM_front_end_main')); //Show statistics
188 add_action( 'wp_ajax_nopriv_fm_submit_form', array($this, 'FM_front_end_main') );
189 // Add media button to WP editor.
190 add_action('wp_ajax_FMShortocde' . $this->plugin_postfix, array($this, 'form_maker_ajax'));
191 add_action('media_buttons', array($this, 'media_button'));
192
193 add_action('admin_head', array($this, 'form_maker_admin_ajax'));//js variables for admin.
194
195 // Form maker shortcodes.
196 if ( !is_admin() ) {
197 add_shortcode('FormPreview' . $this->plugin_postfix, array($this, 'fm_form_preview_shortcode'));
198 if ($this->is_free != 2) {
199 add_shortcode('Form', array($this, 'fm_shortcode'));
200 }
201 if (!($this->is_free == 1)) {
202 add_shortcode('contact_form', array($this, 'fm_shortcode'));
203 add_shortcode('wd_contact_form', array($this, 'fm_shortcode'));
204 }
205 add_shortcode('email_verification' . $this->plugin_postfix, array($this, 'fm_email_verification_shortcode'));
206 }
207 // Action to display not emedded type forms.
208 global $pagenow;
209 if (!is_admin() || !in_array($pagenow, array('wp-login.php', 'wp-register.php'))) {
210 add_action('wp_footer', array($this, 'FM_front_end_main'));
211 }
212
213 // Form Maker Widget.
214 if (class_exists('WP_Widget')) {
215 add_action('widgets_init', array($this, 'register_widgets'));
216 }
217
218 // Plugin activation.
219 register_activation_hook(__FILE__, array($this, 'global_activate'));
220 // Plugin deactivate.
221 register_deactivation_hook( __FILE__, array($this, 'global_deactivate'));
222 add_action('wpmu_new_blog', array($this, 'new_blog_added'), 10, 6);
223
224 if ( (!isset($_GET['action']) || $_GET['action'] != 'deactivate')
225 && (!isset($_GET['page']) || $_GET['page'] != 'uninstall' . $this->menu_postfix) ) {
226 add_action('admin_init', array($this, 'form_maker_activate'));
227 }
228
229 // Register scripts/styles.
230 add_action('wp_enqueue_scripts', array($this, 'register_frontend_scripts'));
231 add_action('admin_enqueue_scripts', array($this, 'register_admin_scripts'));
232
233 // Set per_page option for submissions.
234 add_filter('set-screen-option', array($this, 'set_option_submissions'), 10, 3);
235
236 // Check extensions versions.
237 if ( $this->is_free != 2 && isset( $_GET[ 'page' ] ) && strpos( esc_html( $_GET[ 'page' ] ), '_' . $this->handle_prefix ) !== FALSE ) {
238 add_action('admin_notices', array($this, 'fm_check_addons_compatibility'));
239 }
240
241 add_action('plugins_loaded', array($this, 'plugins_loaded'), 9);
242
243 add_filter('wpseo_whitelist_permalink_vars', array($this, 'add_query_vars_seo'));
244
245 // Enqueue block editor assets for Gutenberg.
246 add_filter('tw_get_block_editor_assets', array($this, 'register_block_editor_assets'));
247 add_filter('tw_get_plugin_blocks', array($this, 'register_plugin_block'));
248 add_action( 'enqueue_block_editor_assets', array($this, 'enqueue_block_editor_assets') );
249
250 // Privacy policy.
251 add_action( 'admin_init', array($this, 'add_privacy_policy_content') );
252
253 // Personal data export.
254 add_filter( 'wp_privacy_personal_data_exporters', array($this, 'register_privacy_personal_data_exporter') );
255 // Personal data erase.
256 add_filter( 'wp_privacy_personal_data_erasers', array($this, 'register_privacy_personal_data_eraser') );
257
258 // Register widget for Elementor builder.
259 add_action('elementor/widgets/widgets_registered', array($this, 'register_elementor_widget'));
260 // Register 10Web category for Elementor widget if 10Web builder doesn't installed.
261 add_action('elementor/elements/categories_registered', array($this, 'register_widget_category'), 1, 1);
262 //fires after elementor editor styles and scripts are enqueued.
263 add_action('elementor/editor/after_enqueue_styles', array($this, 'enqueue_editor_styles'), 11);
264 add_action('elementor/editor/after_enqueue_scripts', array($this, 'enqueue_elementor_widget_scripts'));
265
266 // Divi frontend builder assets.
267 add_action('et_fb_enqueue_assets', array($this, 'enqueue_divi_bulder_assets'));
268 add_action('et_fb_enqueue_assets', array($this, 'form_maker_admin_ajax'));
269
270 if ( $this->is_free == 1 ) {
271 /* Add wordpress.org support custom link in plugin page */
272 add_filter('plugin_action_links_' . plugin_basename(__FILE__), array( $this, 'add_ask_question_links' ));
273 }
274 }
275
276 public function enqueue_divi_bulder_assets() {
277 wp_enqueue_style('thickbox');
278 wp_enqueue_script('thickbox');
279 }
280
281 /**
282 * Add plugin action links.
283 *
284 * Add a link to the settings page on the plugins.php page.
285 *
286 * @since 1.0.0
287 *
288 * @param array $links List of existing plugin action links.
289 * @return array List of modified plugin action links.
290 */
291 function add_ask_question_links ( $links ) {
292 $url = 'https://wordpress.org/support/plugin/' . (WDFMInstance(self::PLUGIN)->is_free == 2 ? 'contact-form-maker' : 'form-maker') . '/#new-post';
293 $fm_ask_question_link = array('<a href="' . $url . '" target="_blank">' . __('Help', $this->prefix) . '</a>');
294 return array_merge( $links, $fm_ask_question_link );
295 }
296
297 public function enqueue_editor_styles() {
298 wp_enqueue_style($this->handle_prefix . '-icons', $this->plugin_url . '/css/fonts.css', array(), '1.0.1');
299 }
300
301 public function enqueue_elementor_widget_scripts(){
302 wp_enqueue_script($this->handle_prefix . 'elementor_widget_js', $this->plugin_url.'/js/fm_elementor_widget.js', array('jquery'));
303 }
304
305 /**
306 * Register widget for Elementor builder.
307 */
308 public function register_elementor_widget() {
309 if ( defined('ELEMENTOR_PATH') && class_exists('Elementor\Widget_Base') ) {
310 require_once ($this->plugin_dir . '/admin/controllers/elementorWidget.php');
311 }
312 }
313
314 /**
315 * Register 10Web category for Elementor widget if 10Web builder doesn't installed.
316 *
317 * @param $elements_manager
318 */
319 public function register_widget_category( $elements_manager ) {
320 $elements_manager->add_category('tenweb-plugins-widgets', array(
321 'title' => __('10WEB Plugins', 'tenweb-builder'),
322 'icon' => 'fa fa-plug',
323 ));
324 }
325
326 function add_privacy_policy_content() {
327 if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) {
328 return;
329 }
330
331 $content = __( 'When you leave a comment on this site, we send your name, email
332 address, IP address and comment text to example.com. Example.com does
333 not retain your personal data.', $this->prefix );
334
335 wp_add_privacy_policy_content(
336 $this->nicename,
337 wp_kses_post( wpautop( $content, false ) )
338 );
339 }
340
341 public function register_privacy_personal_data_exporter( $exporters ) {
342 $exporters[ $this->slug ] = array(
343 'exporter_friendly_name' => $this->nicename,
344 'callback' => array( WDW_FM_Library(self::PLUGIN), 'privacy_personal_data_export' ),
345 );
346 return $exporters;
347 }
348
349 public function register_privacy_personal_data_eraser( $erasers ) {
350 $erasers[ $this->slug ] = array(
351 'eraser_friendly_name' => $this->nicename,
352 'callback' => array( WDW_FM_Library(self::PLUGIN), 'privacy_personal_data_erase' ),
353 );
354 return $erasers;
355 }
356
357 public function register_block_editor_assets($assets) {
358 $version = '2.0.3';
359 $js_path = $this->plugin_url . '/js/tw-gb/block.js';
360 $css_path = $this->plugin_url . '/css/tw-gb/block.css';
361 if (!isset($assets['version']) || version_compare($assets['version'], $version) === -1) {
362 $assets['version'] = $version;
363 $assets['js_path'] = $js_path;
364 $assets['css_path'] = $css_path;
365 }
366 return $assets;
367 }
368
369 public function register_plugin_block($blocks) {
370 if ($this->is_free == 2) {
371 $key = 'tw/contact-form-maker';
372 $key_submissions = 'tw/cfm-submissions';
373 }
374 else {
375 $key = 'tw/form-maker';
376 $key_submissions = 'tw/fm-submissions';
377 }
378 $fm_nonce = wp_create_nonce('fm_ajax_nonce');
379 $plugin_name = $this->nicename;
380 $plugin_name_submissions = __('Submissions', $this->prefix);
381 $icon_url = $this->plugin_url . '/images/tw-gb/icon_colored.svg';
382 $icon_svg = $this->plugin_url . '/images/tw-gb/icon.svg';
383 $url = add_query_arg(array('action' => 'FMShortocde' . $this->plugin_postfix, 'task' => 'submissions', 'nonce' => $fm_nonce), admin_url('admin-ajax.php'));
384 $data = WDW_FM_Library(self::PLUGIN)->get_shortcode_data();
385 $blocks[$key] = array(
386 'title' => $plugin_name,
387 'titleSelect' => sprintf(__('Select %s', $this->prefix), $plugin_name),
388 'iconUrl' => $icon_url,
389 'iconSvg' => array('width' => 20, 'height' => 20, 'src' => $icon_svg),
390 'isPopup' => false,
391 'data' => $data,
392 );
393 $blocks[$key_submissions] = array(
394 'title' => $plugin_name_submissions,
395 'titleSelect' => sprintf(__('Select %s', $this->prefix), $plugin_name),
396 'iconUrl' => $icon_url,
397 'iconSvg' => array('width' => 20, 'height' => 20, 'src' => $icon_svg),
398 'isPopup' => true,
399 'containerClass' => 'tw-container-wrap-520-400',
400 'data' => array('shortcodeUrl' => $url),
401 );
402 return $blocks;
403 }
404
405 public function enqueue_block_editor_assets() {
406 // Remove previously registered or enqueued versions
407 $wp_scripts = wp_scripts();
408 foreach ($wp_scripts->registered as $key => $value) {
409 // Check for an older versions with prefix.
410 if (strpos($key, 'tw-gb-block') > 0) {
411 wp_deregister_script( $key );
412 wp_deregister_style( $key );
413 }
414 }
415 // Get plugin blocks from all 10Web plugins.
416 $blocks = apply_filters('tw_get_plugin_blocks', array());
417 // Get the last version from all 10Web plugins.
418 $assets = apply_filters('tw_get_block_editor_assets', array());
419 // Not performing unregister or unenqueue as in old versions all are with prefixes.
420 wp_enqueue_script('tw-gb-block', $assets['js_path'], array( 'wp-blocks', 'wp-element' ), $assets['version']);
421 wp_localize_script('tw-gb-block', 'tw_obj_translate', array(
422 'nothing_selected' => __('Nothing selected.', $this->prefix),
423 'empty_item' => __('- Select -', $this->prefix),
424 'blocks' => json_encode($blocks)
425 ));
426 wp_enqueue_style('tw-gb-block', $assets['css_path'], array( 'wp-edit-blocks' ), $assets['version']);
427 }
428
429 /**
430 * Wordpress init actions.
431 */
432 public function init() {
433 ob_start();
434 $this->fm_overview();
435
436 // Register fmemailverification post type
437 $this->register_fmemailverification_cpt();
438
439 // Register fmformpreview post type
440 $this->register_form_preview_cpt();
441 }
442
443 /**
444 * Plugins loaded actions.
445 */
446 public function plugins_loaded() {
447 // Languages localization.
448 load_plugin_textdomain($this->prefix, FALSE, basename(dirname(__FILE__)) . '/languages');
449
450 if ($this->is_free != 2 && !function_exists('WDFM')) {
451 require_once($this->plugin_dir . '/WDFM.php');
452 }
453
454 // Initialize extensions.
455 if ($this->is_free != 2) {
456 do_action('fm_init_addons');
457 }
458 // Prevent adding shortcode conflict with some builders.
459 $this->before_shortcode_add_builder_editor();
460 }
461
462 /**
463 * Plugin menu.
464 */
465 public function form_maker_options_panel() {
466 $parent_slug = $this->menu_slug;
467 add_menu_page($this->nicename, $this->nicename, 'manage_options', $this->menu_slug, array( $this, 'form_maker' ), $this->plugin_url . '/images/FormMakerLogo-16.png');
468 add_submenu_page($parent_slug, __('Forms', $this->prefix), __('Forms', $this->prefix), 'manage_options', $this->menu_slug, array($this, 'form_maker'));
469 $submissions_page = add_submenu_page($parent_slug, __('Submissions', $this->prefix), __('Submissions', $this->prefix), 'manage_options', 'submissions' . $this->menu_postfix, array($this, 'form_maker'));
470 add_action('load-' . $submissions_page, array($this, 'submissions_per_page'));
471
472 add_submenu_page(null, __('Blocked IPs', $this->prefix), __('Blocked IPs', $this->prefix), 'manage_options', 'blocked_ips' . $this->menu_postfix, array($this, 'form_maker'));
473 add_submenu_page($parent_slug, __('Themes', $this->prefix), __('Themes', $this->prefix), 'manage_options', 'themes' . $this->menu_postfix, array($this, 'form_maker'));
474 add_submenu_page($parent_slug, __('Options', $this->prefix), __('Options', $this->prefix), 'manage_options', 'options' . $this->menu_postfix, array($this, 'form_maker'));
475 add_submenu_page(null, __('Uninstall', $this->prefix), __('Uninstall', $this->prefix), 'manage_options', 'uninstall' . $this->menu_postfix, array($this, 'form_maker'));
476
477 if ( $this->is_free ) {
478 /* Custom link to wordpress.org*/
479 global $submenu;
480 $url = 'https://wordpress.org/support/plugin/' . (WDFMInstance(self::PLUGIN)->is_free == 2 ? 'contact-form-maker' : 'form-maker') . '/#new-post';
481 $submenu[$parent_slug][] = array(
482 '<div id="fm_ask_question">' . __('Ask a question', $this->prefix) . '</div>',
483 'manage_options',
484 $url
485 );
486 }
487 }
488
489 /**
490 * Set front plugin url.
491 *
492 * return string $plugin_url
493 */
494 private function set_front_plugin_url() {
495 $plugin_url = plugins_url(plugin_basename(dirname(__FILE__)));
496
497 return $plugin_url;
498 }
499
500 /**
501 * Set front upload url.
502 *
503 * return string $upload_url
504 */
505 private function set_front_upload_url() {
506 $wp_upload_dir = wp_upload_dir();
507 $upload_url = $wp_upload_dir['baseurl'];
508 $http = 'http://';
509 $https = 'https://';
510 if ( $_SERVER['SERVER_PORT'] == 443 || strpos(get_option('home'), $https) > -1 ) {
511 $upload_url = str_replace($http, $https, $wp_upload_dir['baseurl']);
512 }
513
514 return $upload_url;
515 }
516
517 /**
518 * Get front urls.
519 *
520 * return array $urls
521 */
522 public function get_front_urls() {
523 $urls = array();
524 $urls['plugin_url'] = $this->set_front_plugin_url();
525 $urls['upload_url'] = $this->set_front_upload_url();
526
527 return $urls;
528 }
529
530 /**
531 * Add per_page screen option for submissions page.
532 */
533 function submissions_per_page() {
534 $option = 'per_page';
535 $args_rates = array(
536 'label' => __('Number of items per page:', $this->prefix),
537 'default' => 20,
538 'option' => 'fm_submissions_per_page'
539 );
540 add_screen_option( $option, $args_rates );
541 }
542
543 /**
544 * Set per_page option for submissions page.
545 *
546 * @param $status
547 * @param $option
548 * @param $value
549 * @return mixed
550 */
551 function set_option_submissions($status, $option, $value) {
552 if ( 'fm_submissions_per_page' == $option ) return $value;
553 return $status;
554 }
555
556 /**
557 * Output for admin pages.
558 */
559 public function form_maker() {
560 if (function_exists('current_user_can')) {
561 if (!current_user_can('manage_options')) {
562 die('Access Denied');
563 }
564 }
565 else {
566 die('Access Denied');
567 }
568 $page = WDW_FM_Library(self::PLUGIN)->get('page');
569 if (($page != '') && (($page == 'manage' . $this->menu_postfix) || ($page == 'options' . $this->menu_postfix) || ($page == 'submissions' . $this->menu_postfix) || ($page == 'blocked_ips' . $this->menu_postfix) || ($page == 'themes' . $this->menu_postfix) || ($page == 'uninstall' . $this->menu_postfix))) {
570
571 $page = ucfirst(substr($page, 0, strlen($page) - strlen($this->menu_postfix)));
572 echo '<div id="fm_loading"></div>';
573 echo '<div id="fm_admin_container" class="fm-form-container" style="display: none;">';
574 try {
575 require_once ($this->plugin_dir . '/admin/controllers/' . $page . '_fm.php');
576 $controller_class = 'FMController' . $page . $this->menu_postfix;
577 $controller = new $controller_class();
578 $controller->execute();
579 } catch (Exception $e) {
580 ob_start();
581 debug_print_backtrace();
582 error_log(ob_get_clean());
583 }
584 echo '</div>';
585 }
586 }
587
588 /**
589 * Register widgets.
590 */
591 public function register_widgets() {
592 require_once($this->plugin_dir . '/admin/controllers/Widget.php');
593 register_widget('FMControllerWidget' . $this->plugin_postfix);
594 }
595
596 /**
597 * Register Admin styles/scripts.
598 */
599 public function register_admin_scripts() {
600 $current_screen = get_current_screen();
601 if ( $this->is_free && !empty($current_screen->id) && $current_screen->id == "toplevel_page_fm_subscribe" ) {
602 wp_enqueue_style($this->handle_prefix . '_subscribe', $this->plugin_url . '/css/fm_subscribe.css', array(), $this->plugin_version);
603 }
604 $fm_settings = $this->fm_settings;
605 // Admin styles.
606 wp_register_style($this->handle_prefix . '-tables', $this->plugin_url . '/css/form_maker_tables.css', array(), $this->plugin_version);
607 wp_register_style($this->handle_prefix . '-phone_field_css', $this->plugin_url . '/css/intlTelInput.css', array(), $this->plugin_version);
608 wp_register_style($this->handle_prefix . '-jquery-ui', $this->plugin_url . '/css/jquery-ui.custom.css', array(), $this->plugin_version);
609 wp_register_style($this->handle_prefix . '-codemirror', $this->plugin_url . '/css/codemirror.css', array(), $this->plugin_version);
610 wp_register_style($this->handle_prefix . '-layout', $this->plugin_url . '/css/form_maker_layout.css', array(), $this->plugin_version);
611 wp_register_style($this->handle_prefix . '-bootstrap', $this->plugin_url . '/css/fm-bootstrap.css', array(), $this->plugin_version);
612 wp_register_style($this->handle_prefix . '-colorpicker', $this->plugin_url . '/css/spectrum.css', array(), $this->plugin_version);
613 // Roboto font for top bar.
614 wp_register_style($this->handle_prefix . '-roboto', 'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap');
615
616 if ( !$this->is_free ) {
617 wp_register_style('jquery.fancybox', $this->plugin_url . '/js/fancybox/jquery.fancybox.css', array(), '3.5.7');
618 }
619 // Admin scripts.
620 $localize_key_all = $this->handle_prefix . '-admin';
621 $localize_key_manage = $this->handle_prefix . '-manage';
622 $localize_key_add_fields = $this->handle_prefix . '-add-fields';
623 $localize_key_formmaker_div = $this->handle_prefix . '-formmaker_div';
624
625 if (!$fm_settings['fm_developer_mode']) {
626 $localize_key_all = $this->handle_prefix . '-scripts';
627 if (WDW_FM_Library(self::PLUGIN)->get('page') == 'submissions_' . $this->handle_prefix) {
628 $localize_key_all = $this->handle_prefix . '-submission';
629 }
630 if (WDW_FM_Library(self::PLUGIN)->get('page') == 'manage_' . $this->handle_prefix) {
631 $localize_key_all = $this->handle_prefix . '-manage';
632 }
633 $localize_key_manage .= '-edit';
634 $localize_key_add_fields = $localize_key_manage;
635 $localize_key_formmaker_div = $localize_key_manage;
636 wp_register_style($this->handle_prefix . '-styles', $this->plugin_url . '/css/fm-styles.min.css', array(), $this->plugin_version);
637 wp_register_script($this->handle_prefix . '-scripts', $this->plugin_url . '/js/fm-scripts.min.js', array(), $this->plugin_version);
638
639 wp_register_style($this->handle_prefix . '-manage', $this->plugin_url . '/css/manage-styles.min.css', array(), $this->plugin_version);
640 wp_register_script($this->handle_prefix . '-manage', $this->plugin_url . '/js/manage-scripts.min.js', array(), $this->plugin_version);
641
642 wp_register_style($this->handle_prefix . '-manage-edit', $this->plugin_url . '/css/manage-edit-styles.min.css', array(), $this->plugin_version);
643 wp_register_script($this->handle_prefix . '-manage-edit', $this->plugin_url . '/js/manage-edit-scripts.min.js', array(), $this->plugin_version);
644
645 wp_register_style($this->handle_prefix . '-submission', $this->plugin_url . '/css/submission-styles.min.css', array(), $this->plugin_version);
646 wp_register_script($this->handle_prefix . '-submission', $this->plugin_url . '/js/submission-scripts.min.js', array(), $this->plugin_version);
647
648 wp_register_style($this->handle_prefix . '-theme-edit', $this->plugin_url . '/css/theme-edit-styles.min.css', array(), $this->plugin_version);
649 wp_register_script($this->handle_prefix . '-theme-edit', $this->plugin_url . '/js/theme-edit-scripts.min.js', array(), $this->plugin_version);
650 }
651
652 $google_map_key = !empty($fm_settings['map_key']) ? '&key=' . $fm_settings['map_key'] : '';
653 wp_register_script('google-maps', 'https://maps.google.com/maps/api/js?v=3.exp' . $google_map_key);
654 wp_register_script($this->handle_prefix . '-gmap_form', $this->plugin_url . '/js/if_gmap_back_end.js', array(), $this->plugin_version);
655
656 wp_register_script($this->handle_prefix . '-phone_field', $this->plugin_url . '/js/intlTelInput.js', array(), '11.0.0');
657
658 // For drag and drop on mobiles.
659 wp_register_script($this->handle_prefix . '_jquery.ui.touch-punch.min', $this->plugin_url . '/js/jquery.ui.touch-punch.min.js', array('jquery'), '0.2.3');
660
661 wp_register_script($this->handle_prefix . '-admin', $this->plugin_url . '/js/form_maker_admin.js', array(), $this->plugin_version);
662 wp_register_script($localize_key_manage, $this->plugin_url . '/js/form_maker_manage.js', array(), $this->plugin_version);
663 wp_register_script($this->handle_prefix . '-manage-edit', $this->plugin_url . '/js/form_maker_manage_edit.js', array(), $this->plugin_version);
664 wp_register_script($localize_key_formmaker_div, $this->plugin_url . '/js/formmaker_div.js', array(), $this->plugin_version);
665 wp_register_script($this->handle_prefix . '-form-options', $this->plugin_url . '/js/form_maker_form_options.js', array(), $this->plugin_version);
666 wp_register_script($this->handle_prefix . '-form-advanced-layout', $this->plugin_url . '/js/form_maker_form_advanced_layout.js', array(), $this->plugin_version);
667 wp_register_script($localize_key_add_fields, $this->plugin_url . '/js/add_field.js', array($this->handle_prefix . '-formmaker_div'), $this->plugin_version);
668
669 wp_localize_script($localize_key_manage, 'form_maker_manage', array(
670 'add_new_field' => __('Add Field', $this->prefix),
671 'add_column' => __('Add Column', $this->prefix),
672 'required_field' => __('Field is required.', $this->prefix),
673 'not_valid_value' => __('Enter a valid value.', $this->prefix),
674 'not_valid_email' => __('Enter a valid email address.', $this->prefix),
675 ));
676
677 wp_localize_script($localize_key_all, 'form_maker', array(
678 'countries' => WDW_FM_Library(self::PLUGIN)->get_countries(),
679 'delete_confirmation' => __('Do you want to delete selected items?', $this->prefix),
680 'select_at_least_one_item' => __('You must select at least one item.', $this->prefix),
681 'add_placeholder' => __('Add placeholder', $this->prefix),
682 ));
683
684 wp_localize_script($localize_key_add_fields, 'form_maker', array(
685 'countries' => WDW_FM_Library(self::PLUGIN)->get_countries(),
686 'states' => WDW_FM_Library(self::PLUGIN)->get_states(),
687 'provinces' => WDW_FM_Library(self::PLUGIN)->get_provinces_canada(),
688 'plugin_url' => $this->plugin_url,
689 'nothing_found' => __('Nothing found.', $this->prefix),
690 'captcha_created' => __('The captcha already has been created.', $this->prefix),
691 'update' => __('Update', $this->prefix),
692 'add' => __('Add', $this->prefix),
693 'add_field' => __('Add Field', $this->prefix),
694 'edit_field' => __('Edit Field', $this->prefix),
695 'stripe3' => __('To use this feature, please go to Settings > Payment Options and select "Stripe" as the Payment Method.', $this->prefix),
696 'sunday' => __('Sunday', $this->prefix),
697 'monday' => __('Monday', $this->prefix),
698 'tuesday' => __('Tuesday', $this->prefix),
699 'wednesday' => __('Wednesday', $this->prefix),
700 'thursday' => __('Thursday', $this->prefix),
701 'friday' => __('Friday', $this->prefix),
702 'saturday' => __('Saturday', $this->prefix),
703 'leave_empty' => __('Leave empty to set the width to 100%.', $this->prefix),
704 'is_demo' => $this->is_demo,
705 'important_message' => __('The free version is limited up to 7 fields to add. If you need this functionality, you need to buy the commercial version.', $this->prefix),
706 'no_preview' => __('No preview available for reCAPTCHA.', $this->prefix),
707 'invisible_recaptcha_error' => sprintf(__('%s Old reCAPTCHA keys will not work for %s. Please make sure to enable the API keys for Invisible reCAPTCHA.', $this->prefix), '<b>' . __('Note:', $this->prefix) . '</b>', '<b>' . __('Invisible reCAPTCHA', $this->prefix) . '</b>'),
708 'type_text_description' => __('This field is a single line text input.', $this->prefix) . '<br><br>' . __('To set a default value, just fill the field above.', $this->prefix) . '<br><br>' . __('You can set the text input as Required, making sure the submitter provides a value for it.', $this->prefix) . '<br><br>' . __('Validation (RegExp.) option in Advanced options lets you configure Regular Expression for your Single Line Text field. Use Common Regular Expressions select box to use built-in validation patterns. For instance, in case you can add a validation for decimal number, IP address or zip code by selecting corresponding options of Common Regular Expressions drop-down.', $this->prefix) . '<br><br>' . __('Additionally, you can add HTML attributes to your form fields with Additional Attributes.', $this->prefix),
709 'type_textarea_description' => __('This field adds a textarea box to your form. Users can write alphanumeric text, special characters and line breaks.', $this->prefix) . '<br><br>' . __('You can set the text input as Required, making sure the submitter provides a value for it.', $this->prefix) . '<br><br>' . __('Set the width and height of the textarea box using Size(px) option.', $this->prefix),
710 'type_number_description' => __('This is an input text that accepts only numbers. Users can type a number directly, or use the spinner arrows to specify it.', $this->prefix) . '<br><br>' . __('Step option defines the number to increment/decrement the spinner value, when the users press up or down arrows.', $this->prefix) . '<br><br>' . __('Use Min Value and Max Value options to set lower and upper limitation for the value of this Number field.', $this->prefix) . '<br><br>' . __('To set a default value, just fill the field above.', $this->prefix),
711 'type_select_description' => __('This field allows the submitter to choose values from select box. Just click (+) Option button and fill in all options you will need or click (+) From Database to fill the options from a database table.', $this->prefix) . '<br><br>' . __('In case you need to have option values to be different from option names, mark Enable option\'s value from Advanced options as checked.', $this->prefix),
712 'type_radio_description' => __('Using this field you can add a list of Radio buttons to your form. Just click (+) Option button and fill in all options you will need or click (+) From Database to fill the options from a database table.', $this->prefix) . '<br><br>' . __('Relative Position lets you choose the position of options in relation to each other. Whereas Option Label Position lets you select the position of radio button label.', $this->prefix) . '<br><br>' . __('In case you need to have option values to be different from option names, mark Enable option\'s value from Advanced options as checked.', $this->prefix) . '<br><br>' . __('And by enabling Allow other, you can let the user to write their own specific value.', $this->prefix),
713 'type_checkbox_description' => __('Multiple Choice field lets you have a list of Checkboxes. This field allows the submitter to choose more than one values.', $this->prefix) . '<br><br>' . __('Just click (+) Option button and fill in all options you will need or click (+) From Database to fill the options from a database table.', $this->prefix) . '<br><br>' . __('Relative Position lets you choose the position of options in relation to each other. Whereas Option Label Position lets you select the position of radio button label.', $this->prefix) . '<br><br>' . __('In case you need to have option values to be different from option names, mark Enable option\'s value from Advanced options as checked.', $this->prefix) . '<br><br>' . __('And by enabling Allow other, you can let the user to write their own specific value.', $this->prefix),
714 'type_recaptcha_description' => sprintf(__('Form Maker is integrated with Google ReCaptcha, which protects your forms from spam bots. Before adding ReCaptcha to your form, you need to configure Site and Secret Keys by registering your website on %s', $this->prefix), '<a href="https://www.google.com/recaptcha/intro/" target="_blank">' . __('Google ReCaptcha website', $this->prefix) . '</a>') . '<br><br>' . __('After registering and creating the keys, copy them to Form Maker > Options page.', $this->prefix),
715 'type_submit_description' => __('The Submit button validates all form field values, saves them on MySQL database of your website, sends emails and performs other actions configured in Form Options. You can have more than one submit button in your form.', $this->prefix),
716 'type_captcha_description' => __('You can use this field as an alternative to ReCaptcha to protect your forms against spambots. It’s a random combination of numbers and letters, and users need to type them in correctly to submit the form.', $this->prefix) . '<br><br>' . __('You can specify the number of symbols in Simple Captcha using Symbols (3 - 9) option.', $this->prefix),
717 'type_name_description' => __('This field lets the user write their name.', $this->prefix) . '<br><br>' . __('To set a default value, just fill the field above.', $this->prefix) . '<br><br>' . __('Enabling Autofill with user name setting will automatically fill in Name field with the name of the logged in user.', $this->prefix) . '<br><br>' . __('In case you do not wish to receive the same data for the same Name field twice, activate Allow only unique values option.', $this->prefix),
718 'type_email_description' => __('This field is an input field that accepts an email address.', $this->prefix) . '<br><br>' . __('To set a default value, just fill the field above.', $this->prefix) . '<br><br>' . __('Using Confirmation Email setting in Advanced Options you can require the submitter to re-type their email address.', $this->prefix) . '<br><br>' . __('Autofill with user email will autofill Email field with the email address of the logged in user.', $this->prefix) . '<br><br>' . __('Upon successful submission of the Form, you have the option to send the submitted data (or just a confirmation message) to the email address entered here. To do this you need to set the corresponding options on Form Options > Email Options page.', $this->prefix),
719 'type_phone_description' => __('This field is an input for a phone number. It provides a list of country flags, which users can select and have their country code automatically added to the phone number.', $this->prefix) . '<br><br>' . __('In case you do not wish to receive the same data for the same Phone field more than once, activate Allow only unique values setting from Advanced options.', $this->prefix),
720 'type_address_description' => __('This field lets you skip a few steps and quickly add one set for requesting the address of the submitter. Use Overall size(px) option to set the width of Address field.', $this->prefix) . '<br><br>' . __('You can enable or disable elements of Address field using Disable Field(s) setting in Advanced Options.', $this->prefix) . '<br><br>' . __('You can turn State/Province/Region field into a list of US states by activating Use list for US states setting from Advanced Options. Note: This only works in case United States is selected for Country select box.', $this->prefix),
721 'type_mark_on_map_description' => __('Mark on Map field lets users to drag the map pin and drop it on their selected location. You can specify a default address for the location pin with Address option.', $this->prefix) . '<br><br>' . __('In addition, Marker Info setting allows you to provide additional details about the location. It will appear after users click on the location pin.', $this->prefix),
722 'type_country_list_description' => __('Country List is a select box which provides a list of all countries in alphabetical order.', $this->prefix) . '<br><br>' . __('You can include/exclude specific countries from the list using the Edit country list setting in Advanced Options.', $this->prefix),
723 'type_date_of_birth_description' => __('Users can specify their birthday or any date with this field.', $this->prefix) . '<br><br>' . __('Use Fields separator setting in Advanced options to change the divider between day, month and year boxes.', $this->prefix) . '<br><br>' . __('You can set the fields to be text inputs or select boxes using Day field type, Month field type and Year field type options.', $this->prefix) . '<br><br>' . __('In addition, you can specify the width of day, month and year fields using Day field size(px), Month field size(px) and Year field size(px) settings.', $this->prefix),
724 'type_file_upload_description' => __('You can allow users to upload single or multiple documents, images and various files through your form.', $this->prefix) . '<br><br>' . __('Use Allowed file extensions option to specify all acceptable file formats. Make sure to separate them with commas.', $this->prefix) . '<br><br>' . __('Mark Allow Uploading Multiple Files option in Advanced Options to allow users to select and upload multiple files.', $this->prefix),
725 'type_map_description' => __('Map field can be used for pinning one or more locations on Google Map and displaying them on your form.', $this->prefix) . '<br><br>' . __('Press the small Plus icon to add a location pin.', $this->prefix),
726 'type_time_description' => __('Time field of Form Maker plugin will allow users to specify time value. Set the time format of the field to 24-hour or 12-hour using Time Format option.', $this->prefix),
727 'type_send_copy_description' => __('When users fill in an email address using Email Field, this checkbox will allow them to choose if they wish to receive a copy of the submission email.', $this->prefix) . '<br><br>' . __('Note: Make sure to configure Form Options > Email Options of your form.', $this->prefix),
728 'type_stars_description' => __('Add Star rating field to your form with this field. You can display as many stars, as you will need, set the number using Number of Stars option.', $this->prefix),
729 'type_rating_description' => __('Place Rating field on your form to have radio buttons, which indicate rating from worst to best. You can set many radio buttons to display using Scale Range option.', $this->prefix),
730 'type_slider_description' => __('Slider field lets users specify the field value by dragging its handle from Min Value to Max Value.', $this->prefix),
731 'type_range_description' => __('You can use this field to let users choose a numeric range by providing values for 2 number inputs. Its Step option allows to set the increment/decrement of spinners’ values, when users click on up or down arrows.', $this->prefix),
732 'type_grades_description' => __('Users will be able to grade specified items with this field. The sum of all values will appear below the field with Total parameter.', $this->prefix) . '<br><br>' . __('Items option allows you to add multiple options to your Grades field.', $this->prefix),
733 'type_matrix_description' => __('Table of Fields lets you place a matrix on your form, which will let the submitter to answer a few questions with one field.', $this->prefix) . '<br><br>' . __('It allows you to configure the matrix with radio buttons, checkboxes, text boxes or drop-downs. Use Input Type option to set this.', $this->prefix),
734 'type_hidden_description' => __('Hidden Input field is similar to Single Line Text field, but it is not visible to users. Hidden Fields are handy, in case you need to run a custom Javascript and submit the result with the info on your form.', $this->prefix) . '<br><br>' . __('Name option of this field is mandatory. Note: we highly recommend you to avoid using spaces or special characters in Hidden Input name. You can write the custom Javascript code using the editor on Form Options > Javascript page.', $this->prefix),
735 'type_button_description' => __('In case you wish to run custom Javascript on your form, you can place Custom Button on your form. Its lets you call the script with its OnClick function.', $this->prefix) . '<br><br>' . __('You can write the custom Javascript code using the editor on Form Options > Javascript page.', $this->prefix),
736 'type_password_description' => __('Password input can be used to allow users provide secret text, such as passwords. All symbols written in this field are replaced with dots.', $this->prefix) . '<br><br>' . __('You can activate Password Confirmation option to ask users to repeat the password.', $this->prefix),
737 'type_phone_area_code_description' => __('Phone-Area Code is a Phone type field, which allows users to write Area Code and Phone Number into separate inputs.', $this->prefix),
738 'type_arithmetic_captcha_description' => __('Arithmetic Captcha is quite similar to Simple Captcha. However, instead of showing random symbols, it displays arithmetic operations.', $this->prefix) . '<br><br>' . __('You can set the operations using Operations option. The field can use addition (+), subtraction (-), multiplication (*) and division (/).', $this->prefix) . '<br><br>' . __('Make sure to separate the operations with commas.', $this->prefix),
739 'type_price_description' => __('Users can set a payment amount of their choice with Price field. Assigns minimum and maximum limits on its value using Range option.', $this->prefix) . '<br><br>' . __('To set a default value, just fill the field above.', $this->prefix) . '<br><br>' . __('Additionally, you can activate Readonly attribute. This way, users will not be able to edit the value of Price.', $this->prefix) . '<br><br>' . __('Note: Make sure to configure Form Options > Payment Options of your form.', $this->prefix),
740 'type_payment_select_description' => __('Payment Select field lets you create lists of products, one of which the submitter can choose to buy through your form. Add or edit list items using Options setting of the fields.', $this->prefix) . '<br><br>' . __('Enable Quantity property from Advanced Options, in case you would like the users to mention the quantity of items they purchase.', $this->prefix) . '<br><br>' . __('Also, you can configure custom or built-in Product Properties for your products, such as Color, T-Shirt Size or Print Size.', $this->prefix) . '<br><br>' . __('Note: Make sure to configure Form Options > Payment Options of your form.', $this->prefix),
741 'type_payment_radio_description' => __('Payment Single Choice field lets you create lists of products, one of which the submitter can choose to buy through your form. Add or edit list items using Options setting of the fields.', $this->prefix) . '<br><br>' . __('Enable Quantity property from Advanced Options, in case you would like the users to mention the quantity of items they purchase.', $this->prefix) . '<br><br>' . __('Also, you can configure custom or built-in Product Properties for your products, such as Color, T-Shirt Size or Print Size.', $this->prefix) . '<br><br>' . __('Note: Make sure to configure Form Options > Payment Options of your form.', $this->prefix),
742 'type_payment_checkbox_description' => __('Payment Multiple Choice field lets you create lists of products, which the submitter can choose to buy through your form. Add or edit list items using Options setting of the fields.', $this->prefix) . '<br><br>' . __('Enable Quantity property from Advanced Options, in case you would like the users to mention the quantity of items they purchase.', $this->prefix) . '<br><br>' . __('Also, you can configure custom or built-in Product Properties for your products, such as Color, T-Shirt Size or Print Size.', $this->prefix) . '<br><br>' . __('Note: Make sure to configure Form Options > Payment Options of your form.', $this->prefix),
743 'type_shipping_description' => __('Shipping allows you to configure shipping types, set price for each of them and display them on your form as radio buttons.', $this->prefix),
744 'type_total_description' => __('Please Total field to your payment form to sum up the values of Payment fields. ', $this->prefix),
745 'type_stripe_description' => __('This field adds the credit card details inputs (card number, expiration date, etc.) and allows you to accept direct payments made by credit cards.', $this->prefix),
746 'upload_max_size' => __('Your upload_max_filesize directive in php.ini is '.intval(ini_get('upload_max_filesize'))*1024 .'KB', $this->prefix),
747 ));
748
749 wp_register_script($this->handle_prefix . '-codemirror', $this->plugin_url . '/js/layout/codemirror.js', array(), '2.3');
750 wp_register_script($this->handle_prefix . '-clike', $this->plugin_url . '/js/layout/clike.js', array(), '1.0.0');
751 wp_register_script($this->handle_prefix . '-formatting', $this->plugin_url . '/js/layout/formatting.js', array(), '1.0.0');
752 wp_register_script($this->handle_prefix . '-css', $this->plugin_url . '/js/layout/css.js', array(), '1.0.0');
753 wp_register_script($this->handle_prefix . '-javascript', $this->plugin_url . '/js/layout/javascript.js', array(), '1.0.0');
754 wp_register_script($this->handle_prefix . '-xml', $this->plugin_url . '/js/layout/xml.js', array(), '1.0.0');
755 wp_register_script($this->handle_prefix . '-php', $this->plugin_url . '/js/layout/php.js', array(), '1.0.0');
756 wp_register_script($this->handle_prefix . '-htmlmixed', $this->plugin_url . '/js/layout/htmlmixed.js', array(), '1.0.0');
757 wp_register_script($this->handle_prefix . '-colorpicker', $this->plugin_url . '/js/spectrum.js', array(), $this->plugin_version);
758 wp_register_script($this->handle_prefix . '-themes', $this->plugin_url . '/js/themes.js', array(), $this->plugin_version);
759 wp_register_script($this->handle_prefix . '-submissions', $this->plugin_url . '/js/form_maker_submissions.js', array(), $this->plugin_version);
760 wp_register_script($this->handle_prefix . '-ng-js', 'https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js', array(), '1.5.0');
761 wp_register_script($this->handle_prefix . '-theme-edit-ng', $this->plugin_url . '/js/fm-theme-edit-ng.js', array(), $this->plugin_version);
762
763 if (!$this->is_free) {
764 wp_register_script('jquery.fancybox.pack', $this->plugin_url . '/js/fancybox/jquery.fancybox.pack.js', array(), '3.5.7');
765 } else {
766 wp_register_style($this->handle_prefix . '-deactivate-css', $this->plugin_url . '/wd/assets/css/deactivate_popup.css', array(), $this->plugin_version);
767 wp_register_script($this->handle_prefix . '-deactivate-popup', $this->plugin_url . '/wd/assets/js/deactivate_popup.js', array(), $this->plugin_version, true);
768 $admin_data = wp_get_current_user();
769 wp_localize_script($this->handle_prefix . '-deactivate-popup', ($this->is_free == 2 ? 'cfmWDDeactivateVars' : 'fmWDDeactivateVars'), array(
770 "prefix" => "fm",
771 "deactivate_class" => 'fm_deactivate_link',
772 "email" => $admin_data->data->user_email,
773 "plugin_wd_url" => "https://10web.io/plugins/wordpress-form-maker/?utm_source=form_maker&utm_medium=free_plugin",
774 ));
775 }
776 wp_register_style($this->handle_prefix . '-topbar', $this->plugin_url . '/css/topbar.css', array(), $this->plugin_version);
777 wp_register_style($this->handle_prefix . '-icons', $this->plugin_url . '/css/fonts.css', array(), '1.0.1');
778
779 wp_localize_script($localize_key_all, 'fm_ajax', array(
780 'ajaxnonce' => wp_create_nonce('fm_ajax_nonce'),
781 ));
782 wp_localize_script($localize_key_add_fields, 'fm_ajax', array(
783 'ajaxnonce' => wp_create_nonce('fm_ajax_nonce'),
784 ));
785 wp_localize_script($localize_key_formmaker_div, 'fm_ajax', array(
786 'ajaxnonce' => wp_create_nonce('fm_ajax_nonce'),
787 ));
788 }
789
790 /**
791 * Admin ajax scripts.
792 */
793 public function register_admin_ajax_scripts() {
794 $fm_settings = $this->fm_settings;
795 wp_register_style($this->handle_prefix . '-tables', $this->plugin_url . '/css/form_maker_tables.css', array(), $this->plugin_version);
796 wp_register_style($this->handle_prefix . '-jquery-ui', $this->plugin_url . '/css/jquery-ui.custom.css', array(), $this->plugin_version);
797
798 wp_register_script($this->handle_prefix . '-shortcode' . $this->menu_postfix, $this->plugin_url . '/js/shortcode.js', array('jquery'), $this->plugin_version);
799 $google_map_key = !empty($fm_settings['map_key']) ? '&key=' . $fm_settings['map_key'] : '';
800
801 wp_register_script('google-maps', 'https://maps.google.com/maps/api/js?v=3.exp' . $google_map_key);
802 wp_register_script($this->handle_prefix . '-gmap_form', $this->plugin_url . '/js/if_gmap_back_end.js', array(), $this->plugin_version);
803
804 wp_localize_script($this->handle_prefix . '-shortcode' . $this->menu_postfix, 'form_maker', array(
805 'insert_form' => __('You must select a form', $this->prefix),
806 'update' => __('Update', $this->prefix),
807 ));
808 wp_register_style($this->handle_prefix . '-topbar', $this->plugin_url . '/css/topbar.css', array(), $this->plugin_version);
809 // Roboto font for submissions shortcode.
810 wp_register_style($this->handle_prefix . '-roboto', 'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap');
811 }
812
813 /**
814 * admin-ajax actions for admin.
815 */
816 public function form_maker_ajax() {
817 $page = WDW_FM_Library(self::PLUGIN)->get('action');
818 $ajax_nonce = WDW_FM_Library(self::PLUGIN)->get('nonce');
819
820 $allowed_pages = array(
821 'manage' . $this->menu_postfix,
822 'manage' . $this->plugin_postfix,
823 'generete_csv' . $this->plugin_postfix,
824 'generete_xml' . $this->plugin_postfix,
825 'formmakerwdcaptcha' . $this->plugin_postfix,
826 'formmakerwdmathcaptcha' . $this->plugin_postfix,
827 'product_option' . $this->plugin_postfix,
828 'FormMakerEditCountryinPopup' . $this->plugin_postfix,
829 'FormMakerMapEditinPopup' . $this->plugin_postfix,
830 'FormMakerIpinfoinPopup' . $this->plugin_postfix,
831 'show_matrix' . $this->plugin_postfix,
832 'FormMakerSubmits' . $this->plugin_postfix,
833 'FMShortocde' . $this->plugin_postfix,
834 );
835 if ( !$this->is_demo ) {
836 $allowed_pages[] = 'FormMakerSQLMapping' . $this->plugin_postfix;
837 $allowed_pages[] = 'select_data_from_db' . $this->plugin_postfix;
838 }
839 if ( !$this->is_free ) {
840 $allowed_pages[] = 'paypal_info';
841 $allowed_pages[] = 'checkpaypal';
842 }
843 $allowed_nonce_pages = array('checkpaypal', 'formmakerwdcaptcha' . $this->plugin_postfix, 'formmakerwdmathcaptcha' . $this->plugin_postfix);
844
845 if ( !in_array($page, $allowed_nonce_pages) && wp_verify_nonce($ajax_nonce , 'fm_ajax_nonce') == FALSE ) {
846 die(-1);
847 }
848
849 if ( !empty($page) && in_array($page, $allowed_pages) ) {
850 if ( $page != 'formmakerwdcaptcha' . $this->plugin_postfix
851 && $page != 'formmakerwdmathcaptcha' . $this->plugin_postfix
852 && $page != 'checkpaypal' ) {
853 if ( function_exists('current_user_can') ) {
854 if ( !current_user_can('manage_options') ) {
855 die('Access Denied');
856 }
857 }
858 else {
859 die('Access Denied');
860 }
861 }
862 $page = ucfirst(substr($page, 0, strlen($page) - strlen($this->plugin_postfix)));
863 $this->register_admin_ajax_scripts();
864 require_once($this->plugin_dir . '/admin/controllers/' . $page . '.php');
865 $controller_class = 'FMController' . $page . $this->plugin_postfix;
866 $controller = new $controller_class();
867 $controller->execute();
868 }
869 }
870
871 /**
872 * admin-ajax actions for site.
873 */
874 public function form_maker_ajax_frontend() {
875 $page = WDW_FM_Library(self::PLUGIN)->get('page');
876 $action = WDW_FM_Library(self::PLUGIN)->get('action');
877 $ajax_nonce = WDW_FM_Library(self::PLUGIN)->get('nonce');
878
879 $allowed_pages = array(
880 'form_submissions',
881 'form_maker',
882 );
883 $allowed_actions = array(
884 'frontend_generate_xml',
885 'frontend_generate_csv',
886 'frontend_paypal_info',
887 'frontend_show_matrix',
888 'frontend_show_map',
889 'get_frontend_stats',
890 'fm_reload_input',
891 );
892
893 if ( wp_verify_nonce($ajax_nonce , 'fm_ajax_nonce') == FALSE ) {
894 die(-1);
895 }
896 if ( !empty($page) && in_array($page, $allowed_pages)
897 && !empty($action) && in_array($action, $allowed_actions) ) {
898 $this->register_frontend_ajax_scripts();
899 require_once ($this->plugin_dir . '/frontend/controllers/' . $page . '.php');
900 $controller_class = 'FMController' . ucfirst($page) . $this->plugin_postfix;
901 $controller = new $controller_class();
902 $controller->execute();
903 }
904 }
905
906 /**
907 * Javascript variables for admin.
908 * todo: change to array.
909 */
910 public function form_maker_admin_ajax() {
911 $upload_dir = wp_upload_dir();
912 ?>
913 <script>
914 var fm_site_url = '<?php echo site_url() .'/'; ?>';
915 var admin_url = '<?php echo admin_url('admin.php'); ?>';
916 var plugin_url = '<?php echo $this->plugin_url; ?>';
917 var upload_url = '<?php echo $upload_dir['baseurl']; ?>';
918 var nonce_fm = '<?php echo wp_create_nonce($this->nonce); ?>';
919 // Set shortcode popup dimensions.
920 function fm_set_shortcode_popup_dimensions(tbWidth, tbHeight) {
921 var tbWindow = jQuery('#TB_window'), H = jQuery(window).height(), W = jQuery(window).width(), w, h;
922 w = (tbWidth && tbWidth < W - 90) ? tbWidth : W - 40;
923 h = (tbHeight && tbHeight < H - 60) ? tbHeight : H - 40;
924 if (tbWindow.length) {
925 tbWindow.width(w).height(h);
926 jQuery('#TB_iframeContent').width(w).height(h - 27);
927 tbWindow.css({'margin-left': '-' + parseInt((w / 2), 10) + 'px'});
928 if (typeof document.body.style.maxWidth != 'undefined') {
929 tbWindow.css({'top': (H - h) / 2, 'margin-top': '0'});
930 }
931 }
932 }
933 </script>
934 <?php
935 }
936
937 /**
938 * Form maker preview shortcode output.
939 *
940 * @return mixed|string
941 */
942 public function fm_form_preview_shortcode() {
943 // check is adminstrator
944 if ( !current_user_can('manage_options') ) {
945 echo __('Sorry, you are not allowed to access this page.', $this->prefix);
946 }
947 else {
948 $id = WDW_FM_Library(self::PLUGIN)->get('wdform_id', 0);
949 $display_options = WDW_FM_Library(self::PLUGIN)->display_options( $id );
950 $type = $display_options->type;
951 $attrs = array( 'id' => $id );
952 if ($type == "embedded") {
953 ob_start();
954 $this->FM_front_end_main($attrs, $type); // embedded popover topbar scrollbox
955 return str_replace(array("\r\n", "\n", "\r"), '', ob_get_clean());
956 }
957 }
958 }
959
960 /**
961 * Form maker shortcode output.
962 *
963 * @param $attrs
964 * @return mixed|string
965 */
966 public function fm_shortcode($attrs) {
967 ob_start();
968 $this->FM_front_end_main($attrs, 'embedded');
969
970 return str_replace(array("\r\n", "\n", "\r"), '', ob_get_clean());
971 }
972
973 /**
974 * Form maker output.
975 *
976 * @param array $params
977 * @param string $type
978 */
979 public function FM_front_end_main($params = array(), $type = '') {
980 if ( !isset($params['type']) ) {
981 $form_id = isset($params['id']) ? (int) $params['id'] : 0;
982 if ($this->is_free == 2) {
983 wd_contact_form_maker($form_id, $type);
984 }
985 else {
986 wd_form_maker( $form_id, $type );
987 }
988 }
989 else if (!$this->is_free) {
990 $shortcode_deafults = array(
991 'id' => 0,
992 'startdate' => '',
993 'enddate' => '',
994 'submit_date' => '',
995 'submitter_ip' => '',
996 'username' => '',
997 'useremail' => '',
998 'form_fields' => '1',
999 'show' => '1,1,1,1,1,1,1,1,1,1',
1000 );
1001 shortcode_atts($shortcode_deafults, $params);
1002
1003 require_once($this->plugin_dir . '/frontend/controllers/form_submissions.php');
1004 $controller = new FMControllerForm_submissions();
1005
1006 $submissions = $controller->execute($params);
1007
1008 echo $submissions;
1009 }
1010 return;
1011 }
1012
1013 /**
1014 * Email verification output.
1015 */
1016 public function fm_email_verification_shortcode() {
1017 require_once($this->plugin_dir . '/frontend/controllers/verify_email.php');
1018 $controller_class = 'FMControllerVerify_email' . $this->plugin_postfix;
1019 $controller = new $controller_class();
1020 $controller->execute();
1021 }
1022
1023 /**
1024 * Register email verification custom post type.
1025 */
1026 public function register_fmemailverification_cpt() {
1027 $args = array(
1028 'label' => 'FM Mail Verification',
1029 'public' => true,
1030 'exclude_from_search' => true,
1031 'show_in_menu' => false,
1032 'show_in_nav_menus' => false,
1033 'create_posts' => 'do_not_allow',
1034 'capabilities' => array(
1035 'create_posts' => FALSE,
1036 'edit_post' => 'edit_posts',
1037 'read_post' => 'edit_posts',
1038 'delete_posts' => FALSE,
1039 )
1040 );
1041
1042 register_post_type(($this->is_free == 2 ? 'cfmemailverification' : 'fmemailverification'), $args);
1043 }
1044
1045 /**
1046 * Register form preview custom post type.
1047 */
1048 public function register_form_preview_cpt() {
1049 $args = array(
1050 'label' => 'FM Preview',
1051 'public' => true,
1052 'exclude_from_search' => true,
1053 'show_in_menu' => false,
1054 'show_in_nav_menus' => false,
1055 'create_posts' => 'do_not_allow',
1056 'capabilities' => array(
1057 'create_posts' => FALSE,
1058 'edit_post' => 'edit_posts',
1059 'read_post' => 'edit_posts',
1060 'delete_posts' => FALSE,
1061 )
1062 );
1063
1064 register_post_type('form-maker' . $this->plugin_postfix, $args);
1065 }
1066
1067 /**
1068 * Frontend scripts/styles.
1069 */
1070 public function register_frontend_scripts() {
1071 $fm_settings = $this->fm_settings;
1072 $front_plugin_url = $this->front_urls['plugin_url'];
1073
1074 $required_scripts = array(
1075 'jquery',
1076 'jquery-ui-widget',
1077 'jquery-effects-shake',
1078 );
1079 $required_styles = array(
1080 $this->handle_prefix . '-googlefonts'
1081 );
1082 if ($fm_settings['fm_developer_mode']) {
1083 array_push($required_styles, $this->handle_prefix . '-jquery-ui', $this->handle_prefix . '-animate');
1084 }
1085
1086 wp_register_style($this->handle_prefix . '-jquery-ui', $front_plugin_url . '/css/jquery-ui.custom.css', array(), $this->plugin_version);
1087 wp_register_style($this->handle_prefix . '-animate', $front_plugin_url . '/css/fm-animate.css', array(), $this->plugin_version);
1088
1089 $google_map_key = !empty($fm_settings['map_key']) ? '&key=' . $fm_settings['map_key'] : '';
1090 wp_register_script('google-maps', 'https://maps.google.com/maps/api/js?v=3.exp' . $google_map_key);
1091
1092 wp_register_script($this->handle_prefix . '-phone_field', $front_plugin_url . '/js/intlTelInput.js', array(), $this->plugin_version);
1093 wp_register_style($this->handle_prefix . '-phone_field_css', $front_plugin_url . '/css/intlTelInput.css', array(), $this->plugin_version);
1094
1095 wp_register_script($this->handle_prefix . '-gmap_form', $front_plugin_url . '/js/if_gmap_front_end.js', array('google-maps'), $this->plugin_version);
1096 wp_register_style($this->handle_prefix . '-googlefonts', WDW_FM_Library(self::PLUGIN)->get_all_used_google_fonts(), null, null);
1097
1098 wp_register_script($this->handle_prefix . '-g-recaptcha', 'https://www.google.com/recaptcha/api.js?onload=fmRecaptchaInit&render=explicit');
1099 if ( isset($fm_settings['public_key']) ) {
1100 wp_register_script($this->handle_prefix . '-g-recaptcha-v3', 'https://www.google.com/recaptcha/api.js?onload=fmRecaptchaInit&render=' . $fm_settings['public_key']);
1101 }
1102 // Register admin styles to use in frontend submissions.
1103 wp_register_script('gmap_form_back', $front_plugin_url . '/js/if_gmap_back_end.js', array(), $this->plugin_version);
1104
1105 if (!$this->is_free) {
1106 wp_register_script($this->handle_prefix . '-file-upload', $front_plugin_url . '/js/file-upload.js', array(), $this->plugin_version);
1107 wp_register_style($this->handle_prefix . '-submissions_css', $front_plugin_url . '/css/style_submissions.css', array(), $this->plugin_version);
1108
1109 if (WDW_FM_Library(self::PLUGIN)->elementor_is_active() && $fm_settings['fm_developer_mode']) {
1110 array_push($required_styles, $this->handle_prefix . '-submissions_css');
1111 array_push($required_scripts, $this->handle_prefix . '-file-upload', 'gmap_form_back');
1112 }
1113 }
1114
1115 if (WDW_FM_Library(self::PLUGIN)->elementor_is_active()) {
1116 array_push($required_scripts,
1117 'jquery-ui-spinner',
1118 'jquery-ui-datepicker',
1119 'jquery-ui-slider'
1120 );
1121
1122 if ($fm_settings['fm_developer_mode']) {
1123 array_push($required_scripts, $this->handle_prefix . '-phone_field', $this->handle_prefix . '-gmap_form');
1124 array_push($required_styles, $this->handle_prefix . '-phone_field_css');
1125 }
1126 }
1127
1128 $style_file = '/css/styles.min.css';
1129 $script_file = '/js/scripts.min.js';
1130 if ($fm_settings['fm_developer_mode']) {
1131 $style_file = '/css/form_maker_frontend.css';
1132 $script_file = '/js/main_div_front_end.js';
1133 }
1134
1135 wp_register_style($this->handle_prefix . '-frontend', $front_plugin_url . $style_file, $required_styles, $this->plugin_version);
1136 wp_register_script($this->handle_prefix . '-frontend', $front_plugin_url . $script_file, $required_scripts, $this->plugin_version);
1137
1138 if (WDW_FM_Library(self::PLUGIN)->elementor_is_active()) {
1139 wp_enqueue_style($this->handle_prefix . '-frontend');
1140 wp_enqueue_script($this->handle_prefix . '-frontend');
1141 }
1142
1143 wp_localize_script($this->handle_prefix . '-frontend', 'fm_objectL10n', array(
1144 'states' => WDW_FM_Library(self::PLUGIN)->get_states(),
1145 'provinces' => WDW_FM_Library(self::PLUGIN)->get_provinces_canada(),
1146 'plugin_url' => $front_plugin_url,
1147 'form_maker_admin_ajax' => admin_url('admin-ajax.php'),
1148 'fm_file_type_error' => addslashes(__('Can not upload this type of file', $this->prefix)),
1149 'fm_field_is_required' => addslashes(__('Field is required', $this->prefix)),
1150 'fm_min_max_check_1' => addslashes((__('The ', $this->prefix))),
1151 'fm_min_max_check_2' => addslashes((__(' value must be between ', $this->prefix))),
1152 'fm_spinner_check' => addslashes((__('Value must be between ', $this->prefix))),
1153 'fm_clear_data' => addslashes((__('Are you sure you want to clear saved data?', $this->prefix))),
1154 'fm_grading_text' => addslashes(__('Your score should be less than', $this->prefix)),
1155 'time_validation' => addslashes(__('This is not a valid time value.', $this->prefix)),
1156 'number_validation' => addslashes(__('This is not a valid number value.', $this->prefix)),
1157 'date_validation' => addslashes(__('This is not a valid date value.', $this->prefix)),
1158 'year_validation' => addslashes(sprintf(__('The year must be between %s and %s', $this->prefix), '%%start%%', '%%end%%')),
1159 ));
1160
1161 wp_localize_script($this->handle_prefix . '-frontend', 'fm_ajax', array(
1162 'ajaxnonce' => wp_create_nonce('fm_ajax_nonce'),
1163 ));
1164 }
1165
1166 /**
1167 * Frontend ajax scripts.
1168 */
1169 public function register_frontend_ajax_scripts() {
1170 $fm_settings = $this->fm_settings;
1171 $front_plugin_url = $this->front_urls['plugin_url'];
1172 $google_map_key = !empty($fm_settings['map_key']) ? '&key=' . $fm_settings['map_key'] : '';
1173 wp_register_script('google-maps', 'https://maps.google.com/maps/api/js?v=3.exp' . $google_map_key);
1174 wp_register_script($this->handle_prefix . '-gmap_form_back', $front_plugin_url . '/js/if_gmap_back_end.js', array(), $this->plugin_version);
1175 }
1176
1177 /*
1178 * Global activate.
1179 *
1180 * @param $networkwide
1181 */
1182 public function global_activate($networkwide) {
1183 if ( function_exists('is_multisite') && is_multisite() ) {
1184 // Check if it is a network activation - if so, run the activation function for each blog id.
1185 if ( $networkwide ) {
1186 global $wpdb;
1187 // Get all blog ids.
1188 $blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
1189 foreach ( $blogids as $blog_id ) {
1190 switch_to_blog($blog_id);
1191 $this->form_maker_on_activate();
1192 restore_current_blog();
1193 }
1194
1195 return;
1196 }
1197 }
1198 $this->form_maker_on_activate();
1199 }
1200
1201 public function new_blog_added( $blog_id, $user_id, $domain, $path, $site_id, $meta ) {
1202 if ( is_plugin_active_for_network( $this->main_file ) ) {
1203 switch_to_blog($blog_id);
1204 $this->form_maker_on_activate();
1205 restore_current_blog();
1206 }
1207 }
1208
1209 /**
1210 * Activate plugin.
1211 */
1212 public function form_maker_on_activate() {
1213 $this->form_maker_activate();
1214 if ($this->is_free == 2) {
1215 WDCFMInsert::install_demo_forms();
1216 }
1217 else {
1218 WDFMInsert::install_demo_forms();
1219 }
1220 $this->init();
1221 // Using this insted of flush_rewrite_rule() for better performance with multisite.
1222 global $wp_rewrite;
1223 $wp_rewrite->init();
1224 $wp_rewrite->flush_rules();
1225 }
1226
1227 /**
1228 * Global deactivate.
1229 *
1230 * @param $networkwide
1231 */
1232 public function global_deactivate($networkwide) {
1233 if ( function_exists('is_multisite') && is_multisite() ) {
1234 if ( $networkwide ) {
1235 global $wpdb;
1236 // Check if it is a network activation - if so, run the activation function for each blog id.
1237 // Get all blog ids.
1238 $blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
1239 foreach ( $blogids as $blog_id ) {
1240 switch_to_blog($blog_id);
1241 $this->deactivate();
1242 restore_current_blog();
1243 }
1244
1245 return;
1246 }
1247 }
1248 $this->deactivate();
1249 }
1250
1251 /**
1252 * Deactivate.
1253 */
1254 public function deactivate() {
1255 // Using this insted of flush_rewrite_rule() for better performance with multisite.
1256 global $wp_rewrite;
1257 $wp_rewrite->init();
1258 $wp_rewrite->flush_rules();
1259 }
1260
1261 /**
1262 * Activate plugin.
1263 */
1264 public function form_maker_activate() {
1265 global $wpdb;
1266 if (!$this->is_free) {
1267 deactivate_plugins("contact-form-maker/contact-form-maker.php");
1268 delete_transient('fm_update_check');
1269 }
1270 $version = get_option("wd_form_maker_version");
1271 $new_version = $this->db_version;
1272 $option_key = ($this->is_free == 2 ? 'fmc_settings' : 'fm_settings');
1273 require_once $this->plugin_dir . "/form_maker_insert.php";
1274 if (!$version) {
1275 if ($wpdb->get_var("SHOW TABLES LIKE '" . $wpdb->prefix . "formmaker'") == $wpdb->prefix . "formmaker") {
1276 deactivate_plugins($this->main_file);
1277 wp_die(__("Oops! Seems like you installed the update over a quite old version of Form Maker. Unfortunately, this version is deprecated.<br />Please contact 10Web support team at support@10web.io. We will take care of this issue as soon as possible.", $this->prefix));
1278 }
1279 else {
1280 add_option("wd_form_maker_version", $new_version, '', 'no');
1281 if ($this->is_free == 2) {
1282 WDCFMInsert::form_maker_insert();
1283 }
1284 else {
1285 WDFMInsert::form_maker_insert();
1286 }
1287 $email_verification_post = array(
1288 'post_title' => 'Email Verification',
1289 'post_content' => '[email_verification]',
1290 'post_status' => 'publish',
1291 'post_author' => 1,
1292 'post_type' => ($this->is_free == 2 ? 'cfmemailverification' : 'fmemailverification'),
1293 );
1294 $mail_verification_post_id = wp_insert_post($email_verification_post);
1295 add_option($option_key, array('public_key' => '', 'private_key' => '', 'csv_delimiter' => ',', 'map_key' => '', 'fm_file_read' => 0, 'ajax_export_per_page' => 1000));
1296 $wpdb->update($wpdb->prefix . "formmaker", array(
1297 'mail_verification_post_id' => $mail_verification_post_id,
1298 ), array('id' => 1), array(
1299 '%d',
1300 ), array('%d'));
1301 }
1302 }
1303 elseif (version_compare($version, $new_version, '<')) {
1304 $version = substr_replace($version, '1.', 0, 2);
1305 require_once $this->plugin_dir . "/form_maker_update.php";
1306 $mail_verification_post_ids = $wpdb->get_results($wpdb->prepare('SELECT mail_verification_post_id FROM ' . $wpdb->prefix . 'formmaker WHERE mail_verification_post_id!="%d"', 0));
1307 if ($mail_verification_post_ids) {
1308 foreach ($mail_verification_post_ids as $mail_verification_post_id) {
1309 $update_email_ver_post_type = array(
1310 'ID' => (int)$mail_verification_post_id->mail_verification_post_id,
1311 'post_type' => ($this->is_free == 2 ? 'cfmemailverification' : 'fmemailverification'),
1312 );
1313 wp_update_post($update_email_ver_post_type);
1314 }
1315 }
1316 if ($this->is_free == 2) {
1317 WDCFMUpdate::form_maker_update($version);
1318 }
1319 else {
1320 WDFMUpdate::form_maker_update($version);
1321 }
1322 update_option("wd_form_maker_version", $new_version);
1323 $fm_settings = get_option($option_key);
1324 if ( $fm_settings === FALSE ) {
1325 $recaptcha_keys = $wpdb->get_row('SELECT `public_key`, `private_key` FROM ' . $wpdb->prefix . 'formmaker WHERE public_key!="" and private_key!=""', ARRAY_A);
1326 $public_key = isset($recaptcha_keys['public_key']) ? $recaptcha_keys['public_key'] : '';
1327 $private_key = isset($recaptcha_keys['private_key']) ? $recaptcha_keys['private_key'] : '';
1328 $option_value = array(
1329 'public_key' => $public_key,
1330 'private_key' => $private_key,
1331 'csv_delimiter' => ',',
1332 'map_key' => '',
1333 'fm_advanced_layout' => 0,
1334 'fm_enable_wp_editor' => 1,
1335 'fm_antispam_referer' => 0,
1336 'fm_antispam_bot_validation' => 0,
1337 'fm_antispam_nonce' => 0,
1338 'fm_block_ip_exceeded_limit' => 0,
1339 'fm_developer_mode' => 0,
1340 'fm_file_read' => 0,
1341 'ajax_export_per_page' => 1000);
1342 add_option($option_key, $option_value);
1343 }
1344 if ( !isset($fm_settings['fm_enable_wp_editor']) ) {
1345 $fm_settings['fm_enable_wp_editor'] = 1;
1346 update_option( $option_key, $fm_settings );
1347 }
1348 if ( !isset($fm_settings['fm_antispam_referer']) ) {
1349 $fm_settings['fm_antispam_referer'] = 0;
1350 update_option( $option_key, $fm_settings );
1351 }
1352 if ( !isset($fm_settings['fm_antispam_bot_validation']) ) {
1353 $fm_settings['fm_antispam_bot_validation'] = 0;
1354 update_option( $option_key, $fm_settings );
1355 }
1356 if ( !isset($fm_settings['fm_antispam_nonce']) ) {
1357 $fm_settings['fm_antispam_nonce'] = 0;
1358 update_option( $option_key, $fm_settings );
1359 }
1360 if ( !isset($fm_settings['fm_block_ip_exceeded_limit']) ) {
1361 $fm_settings['fm_block_ip_exceeded_limit'] = 0;
1362 update_option( $option_key, $fm_settings );
1363 }
1364 if ( !isset($fm_settings['fm_developer_mode']) ) {
1365 $fm_settings['fm_developer_mode'] = 0;
1366 update_option( $option_key, $fm_settings );
1367 }
1368 if ( !isset($fm_settings['fm_file_read']) ) {
1369 $fm_settings['fm_file_read'] = 0;
1370 update_option( $option_key, $fm_settings );
1371 }
1372 }
1373 }
1374
1375 /**
1376 * Form maker overview.
1377 */
1378 public function fm_overview() {
1379 if (is_admin() && !isset($_REQUEST['ajax'])) {
1380 if (!class_exists("TenWebLibNew")) {
1381 $plugin_dir = apply_filters('tenweb_free_users_lib_path', array('version' => '1.1.1', 'path' => $this->plugin_dir));
1382 require_once($plugin_dir['path'] . '/wd/start.php');
1383 }
1384 global $fm_options;
1385 $fm_options = array(
1386 "prefix" => ($this->is_free == 2 ? 'cfm' : 'fm'),
1387 "wd_plugin_id" => ($this->is_free == 2 ? 183 : 31),
1388 "plugin_id" => ($this->is_free == 2 ? 95 : 95),
1389 "plugin_title" => ($this->is_free == 2 ? 'Contact Form Maker' : 'Form Maker'),
1390 "plugin_wordpress_slug" => ($this->is_free == 2 ? 'contact-form-maker' : 'form-maker'),
1391 "plugin_dir" => $this->plugin_dir,
1392 "plugin_main_file" => __FILE__,
1393 "description" => ($this->is_free == 2 ? __('WordPress Contact Form Maker is a simple contact form builder, which allows the user with almost no knowledge of programming to create and edit different type of contact forms.', $this->prefix) : __('Form Maker plugin is a modern and advanced tool for easy and fast creating of a WordPress Form. The backend interface is intuitive and user friendly which allows users far from scripting and programming to create WordPress Forms.', $this->prefix)),
1394 "plugin_features" => array(
1395 0 => array(
1396 "title" => __("Easy to Use", $this->prefix),
1397 "description" => __("This responsive form maker plugin is one of the most easy-to-use form builder solutions available on the market. Simple, yet powerful plugin allows you to quickly and easily build any complex forms.", $this->prefix),
1398 ),
1399 1 => array(
1400 "title" => __("Customizable Fields", $this->prefix),
1401 "description" => __("All the fields of Form Maker plugin are highly customizable, which allows you to change almost every detail in the form and make it look exactly like you want it to be.", $this->prefix),
1402 ),
1403 2 => array(
1404 "title" => __("Submissions", $this->prefix),
1405 "description" => __("You can view the submissions for each form you have. The plugin allows to view submissions statistics, filter submission data and export in csv or xml formats.", $this->prefix),
1406 ),
1407 3 => array(
1408 "title" => __("Multi-Page Forms", $this->prefix),
1409 "description" => __("With the form builder plugin you can create muilti-page forms. Simply use the page break field to separate the pages in your forms.", $this->prefix),
1410 ),
1411 4 => array(
1412 "title" => __("Themes", $this->prefix),
1413 "description" => __("The WordPress Form Maker plugin comes with a wide range of customizable themes. You can choose from a list of existing themes or simply create the one that better fits your brand and website.", $this->prefix),
1414 )
1415 ),
1416 "user_guide" => array(
1417 0 => array(
1418 "main_title" => __("Installing", $this->prefix),
1419 "url" => "https://help.10web.io/hc/en-us/articles/360015435831-Introducing-Form-Maker-Plugin?utm_source=form_maker&utm_medium=free_plugin",
1420 "titles" => array()
1421 ),
1422 1 => array(
1423 "main_title" => __("Creating a new Form", $this->prefix),
1424 "url" => "https://help.10web.io/hc/en-us/articles/360015244232-Creating-a-Form-on-WordPress?utm_source=form_maker&utm_medium=free_plugin",
1425 "titles" => array()
1426 ),
1427 2 => array(
1428 "main_title" => __("Configuring Form Options", $this->prefix),
1429 "url" => "https://help.10web.io/hc/en-us/articles/360015862812-Settings-General-Options?utm_source=form_maker&utm_medium=free_plugin",
1430 "titles" => array()
1431 ),
1432 3 => array(
1433 "main_title" => __("Description of The Form Fields", $this->prefix),
1434 "url" => "https://help.10web.io/hc/en-us/articles/360016081951-Form-Fields-Basic?utm_source=form_maker&utm_medium=free_plugin",
1435 "titles" => array(
1436 array(
1437 "title" => __("Selecting Options from Database", $this->prefix),
1438 "url" => "https://help.10web.io/hc/en-us/articles/360015862632-Selecting-Options-from-Database?utm_source=form_maker&utm_medium=free_plugin",
1439 ),
1440 )
1441 ),
1442 4 => array(
1443 "main_title" => __("Publishing the Created Form", $this->prefix),
1444 "url" => "https://help.10web.io/hc/en-us/articles/360016083211-Additional-Publishing-Options?utm_source=form_maker&utm_medium=free_plugin",
1445 "titles" => array()
1446 ),
1447 5 => array(
1448 "main_title" => __("Blocking IPs", $this->prefix),
1449 "url" => "https://help.10web.io/hc/en-us/articles/360015863292-Managing-Form-Submissions?utm_source=form_maker&utm_medium=free_plugin",
1450 "titles" => array()
1451 ),
1452 6 => array(
1453 "main_title" => __("Managing Submissions", $this->prefix),
1454 "url" => "https://help.10web.io/hc/en-us/articles/360015863292-Managing-Form-Submissions?utm_source=form_maker&utm_medium=free_plugin",
1455 "titles" => array()
1456 ),
1457 7 => array(
1458 "main_title" => __("Publishing Submissions", $this->prefix),
1459 "url" => "https://help.10web.io/hc/en-us/articles/360016083211-Additional-Publishing-Options?utm_source=form_maker&utm_medium=free_plugin",
1460 "titles" => array()
1461 ),
1462 ),
1463 "video_youtube_id" => "tN3_c6MhqFk",
1464 "plugin_wd_url" => "https://10web.io/plugins/wordpress-form-maker/?utm_source=form_maker&utm_medium=free_plugin",
1465 "plugin_wd_demo_link" => "https://demo.10web.io/form-maker?utm_source=form_maker&utm_medium=free_plugin",
1466 "plugin_wd_addons_link" => "https://10web.io/plugins/wordpress-form-maker/?utm_source=form_maker&utm_medium=free_plugin#plugin_extensions",
1467 "plugin_wd_docs_link" => "https://help.10web.io/hc/en-us/sections/360002133951-Form-Maker-Documentation/?utm_source=form_maker&utm_medium=free_plugin",
1468 "after_subscribe" => admin_url('admin.php?page=manage_' . ($this->is_free == 2 ? 'cfm' : 'fm')), // this can be plagin overview page or set up page
1469 "plugin_wizard_link" => '',
1470 "plugin_menu_title" => $this->nicename,
1471 "plugin_menu_icon" => $this->plugin_url . '/images/FormMakerLogo-16.png',
1472 "deactivate" => ($this->is_free ? true : false),
1473 "subscribe" => false,
1474 "custom_post" => 'manage' . $this->menu_postfix,
1475 "menu_position" => null,
1476 "display_overview" => false,
1477 );
1478
1479 ten_web_new_lib_init($fm_options);
1480 }
1481 }
1482
1483 /**
1484 * Add media button to Wp editor.
1485 *
1486 * @param $context
1487 *
1488 * @return string
1489 */
1490 function media_button() {
1491 $fm_nonce = wp_create_nonce('fm_ajax_nonce');
1492 ob_start();
1493 $url = add_query_arg(array('action' => 'FMShortocde' . $this->plugin_postfix, 'task' => 'forms', 'nonce' => $fm_nonce, 'TB_iframe' => '1'), admin_url('admin-ajax.php'));
1494 ?>
1495 <a onclick="tb_click.call(this); fm_set_shortcode_popup_dimensions(400, 140); return false;" href="<?php echo $url; ?>" class="button" title="<?php _e('Insert Form', $this->prefix); ?>">
1496 <span class="wp-media-buttons-icon" style="background: url('<?php echo $this->plugin_url; ?>/images/fm-media-form-button.png') no-repeat scroll left top rgba(0, 0, 0, 0);"></span>
1497 <?php _e('Add Form', $this->prefix); ?>
1498 </a>
1499 <?php
1500 $url = add_query_arg(array('action' => 'FMShortocde' . $this->plugin_postfix, 'task' => 'submissions', 'nonce' => $fm_nonce, 'TB_iframe' => '1'), admin_url('admin-ajax.php'));
1501 ?>
1502 <a onclick="tb_click.call(this); fm_set_shortcode_popup_dimensions(520, 570); return false;" href="<?php echo $url; ?>" class="button" title="<?php _e('Insert submissions', $this->prefix); ?>">
1503 <span class="wp-media-buttons-icon" style="background: url(<?php echo $this->plugin_url; ?>/images/fm-media-submissions-button.png) no-repeat scroll left top rgba(0, 0, 0, 0);"></span>
1504 <?php _e('Add Submissions', $this->prefix); ?>
1505 </a>
1506 <?php
1507 echo ob_get_clean();
1508 }
1509
1510
1511 /**
1512 * Check extensions version compatibility with FM.
1513 *
1514 */
1515 function fm_check_addons_compatibility() {
1516 // Extension last version(version which is compatible with current version of form maker).
1517 $add_ons = array(
1518 'form-maker-calculator' => array('version' => '1.1.2', 'file' => 'fm_calculator.php'),
1519 'form-maker-conditional-emails' => array('version' => '1.1.6', 'file' => 'fm_conditional_emails.php'),
1520 'form-maker-dropbox-integration' => array('version' => '1.2.5', 'file' => 'fm_dropbox_integration.php'),
1521 'form-maker-export-import' => array('version' => '2.0.7', 'file' => 'fm_exp_imp.php'),
1522 'form-maker-gdrive-integration' => array('version' => '1.1.2', 'file' => 'fm_gdrive_integration.php'),
1523 'form-maker-mailchimp' => array('version' => '1.1.6', 'file' => 'fm_mailchimp.php'),
1524 'form-maker-pdf-integration' => array('version' => '1.1.7', 'file' => 'fm_pdf_integration.php'),
1525 'form-maker-post-generation' => array('version' => '1.1.5', 'file' => 'fm_post_generation.php'),
1526 'form-maker-pushover' => array('version' => '1.1.4', 'file' => 'fm_pushover.php'),
1527 'form-maker-reg' => array('version' => '1.2.5', 'file' => 'fm_reg.php'),
1528 'form-maker-save-progress' => array('version' => '1.1.6', 'file' => 'fm_save.php'),
1529 'form-maker-stripe' => array('version' => '1.1.6', 'file' => 'fm_stripe.php'),
1530 'form-maker-webhooks' => array('version' => '1.0.1', 'file' => 'fm_webhooks.php'),
1531 );
1532
1533 $add_ons_notice = array();
1534 include_once(ABSPATH . 'wp-admin/includes/plugin.php');
1535
1536 foreach ( $add_ons as $add_on_key => $add_on_value ) {
1537 $addon_path = plugin_dir_path(dirname(__FILE__)) . $add_on_key . '/' . $add_on_value['file'];
1538 if ( is_plugin_active($add_on_key . '/' . $add_on_value['file']) ) {
1539 $addon = get_plugin_data($addon_path); // array
1540 if ( version_compare($addon['Version'], $add_on_value['version'], '<') ) {
1541 // deactivate_plugins($addon_path);
1542 array_push($add_ons_notice, $addon['Name']);
1543 }
1544 }
1545 }
1546
1547 if ( !empty($add_ons_notice) ) {
1548 $this->fm_addons_compatibility_notice($add_ons_notice);
1549 }
1550 }
1551
1552 /**
1553 * Incompatibility message.
1554 *
1555 * @param $add_ons_notice
1556 */
1557 function fm_addons_compatibility_notice($add_ons_notice) {
1558 $addon_names = implode(', ', $add_ons_notice);
1559 $count = count($add_ons_notice);
1560 $single = __('The current version of %s extension is not compatible with Form Maker. Some functions may not work correctly. Please update the extension to fully use its features.', $this->prefix);
1561 $plural = __('The current version of %s extensions are not compatible with Form Maker. Some functions may not work correctly. Please update the extensions to fully use its features.', $this->prefix);
1562 echo '<div class="error"><p>' . sprintf( _n($single, $plural, $count, $this->prefix), $addon_names ) .'</p></div>';
1563 }
1564
1565 public function add_query_vars_seo($vars) {
1566 $vars[] = 'form_id';
1567 return $vars;
1568 }
1569
1570 /**
1571 * Prevent adding shortcode conflict with some builders.
1572 */
1573 private function before_shortcode_add_builder_editor() {
1574 if ( defined('ELEMENTOR_VERSION') ) {
1575 add_action('elementor/editor/before_enqueue_scripts', array( $this, 'form_maker_admin_ajax' ));
1576 }
1577 if ( class_exists('FLBuilder') ) {
1578 add_action('wp_enqueue_scripts', array( $this, 'form_maker_admin_ajax' ));
1579 }
1580 }
1581
1582 public function webinar_banner() {
1583 // Webinar banner
1584 if ( !class_exists( 'TWFMWebinar' ) ) {
1585 require_once( $this->plugin_dir . '/framework/TWWebinar.php' );
1586 }
1587 new TWFMWebinar(array(
1588 'menu_postfix' => $this->menu_postfix,
1589 'title' => 'Join the Webinar',
1590 'description' => 'How to Create a Fully Functional WP Website with Various Forms in Just an Hour + SPECIAL GIFT FOR WEBINAR ATTENDEES',
1591 'preview_type' => 'youtube',
1592 'preview_url' => 'Ry2hDk3LtPk',
1593 'button_text' => 'SIGN UP',
1594 'button_link' => 'https://my.demio.com/ref/qWIW655LXhVTdRoY',
1595 ));
1596 }
1597 }
1598
1599 /**
1600 * Main instance of WDFM.
1601 *
1602 * @return WDFM The main instance to prevent the need to use globals.
1603 */
1604 if (!function_exists('WDFMInstance')) {
1605 function WDFMInstance( $version ) {
1606 if ( $version == 2 ) {
1607 return WDCFM::instance();
1608 }
1609 return WDFM::instance();
1610 }
1611 }
1612
1613 WDFMInstance(1);
1614
1615 if (!function_exists('WDW_FM_Library')) {
1616 function WDW_FM_Library( $version = 1 ) {
1617 if ( $version == 2 ) {
1618 return WDW_FMC_Library::instance();
1619 }
1620 return WDW_FM_Library::instance();
1621 }
1622 }
1623
1624 /**
1625 * Form maker output.
1626 *
1627 * @param $id
1628 * @param string $type
1629 */
1630 function wd_form_maker($id, $type = 'embedded') {
1631 require_once (WDFMInstance(1)->plugin_dir . '/frontend/controllers/form_maker.php');
1632 $controller = new FMControllerForm_maker();
1633 $form = $controller->execute($id, $type);
1634 echo $form;
1635 }
1636
1637 function fm_add_plugin_meta_links($meta_fields, $file) {
1638 if ( plugin_basename(__FILE__) == $file ) {
1639 $plugin_url = "https://wordpress.org/support/plugin/form-maker";
1640 $prefix = WDFMInstance(1)->prefix;
1641 $meta_fields[] = "<a href='" . $plugin_url . "/#new-post' target='_blank'>" . __('Ask a question', $prefix) . "</a>";
1642 $meta_fields[] = "<a href='" . $plugin_url . "/reviews#new-post' target='_blank' title='" . __('Rate', $prefix) . "'>
1643 <i class='wdi-rate-stars'>"
1644 . "<svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg>"
1645 . "<svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg>"
1646 . "<svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg>"
1647 . "<svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg>"
1648 . "<svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg>"
1649 . "</i></a>";
1650
1651 $stars_color = "#ffb900";
1652
1653 echo "<style>"
1654 . ".wdi-rate-stars{display:inline-block;color:" . $stars_color . ";position:relative;top:3px;}"
1655 . ".wdi-rate-stars svg{fill:" . $stars_color . ";}"
1656 . ".wdi-rate-stars svg:hover{fill:" . $stars_color . "}"
1657 . ".wdi-rate-stars svg:hover ~ svg{fill:none;}"
1658 . "</style>";
1659 }
1660
1661 return $meta_fields;
1662 }
1663
1664 if ( WDFMInstance(1)->is_free ) {
1665 add_filter("plugin_row_meta", 'fm_add_plugin_meta_links', 10, 2);
1666 }
1667