PluginProbe
Form Maker by 10Web – Mobile-Friendly Drag & Drop Contact Form Builder / 1.13.52
Form Maker by 10Web – Mobile-Friendly Drag & Drop Contact Form Builder v1.13.52
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.52, at form-maker.php

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