Completed
Push — master ( 707409...ea219b )
by Stephanie
10:05
created

FrmPointers::intro_tour()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 11
rs 9.4285
cc 3
eloc 7
nc 2
nop 0
1
<?php
2
3
/**
4
 * This class handles the pointers used in the introduction tour.
5
 */
6
class FrmPointers {
7
8
	/**
9
	 * @var object Instance of this class
10
	 */
11
	public static $instance;
12
13
	/**
14
	 * @var array Holds the buttons to be put out
15
	 */
16
	private $button_array;
17
18
	/**
19
	 * @var array Holds the admin pages we have pointers for and the callback that generates the pointers content
20
	 */
21
	private $admin_pages = array(
22
		'' => 'forms_pointer',
23
		'entries'   => 'entries_pointer',
24
		'styles'    => 'styles_pointer',
25
		'import'    => 'import_pointer',
26
		'settings'  => 'settings_pointer',
27
		'addons'    => 'addons_pointer',
28
	);
29
30
	/**
31
	 * Class constructor.
32
	 */
33
	private function __construct() {
34
		if ( current_user_can( 'manage_options' ) ) {
35
36
			if ( ! get_user_meta( get_current_user_id(), 'frm_ignore_tour' ) ) {
1 ignored issue
show
introduced by
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
37
				wp_enqueue_style( 'wp-pointer' );
38
				wp_enqueue_script( 'jquery-ui' );
39
				wp_enqueue_script( 'wp-pointer' );
40
				add_action( 'admin_print_footer_scripts', array( $this, 'intro_tour' ) );
41
			}
42
		}
43
	}
44
45
	/**
46
	 * Get the singleton instance of this class
47
	 *
48
	 * @return object
49
	 */
50
	public static function get_instance() {
51
		if ( ! ( self::$instance instanceof self ) ) {
52
			self::$instance = new self();
53
		}
54
55
		return self::$instance;
56
	}
57
58
	/**
59
	 * Load the introduction tour
60
	 */
61
	public function intro_tour() {
62
		global $pagenow;
63
64
		$page = preg_replace( '/^(formidable[-]?)/', '', filter_input( INPUT_GET, 'page' ) );
65
66
		if ( 'admin.php' === $pagenow && array_key_exists( $page, $this->admin_pages ) ) {
67
			$this->do_page_pointer( $page );
0 ignored issues
show
Bug introduced by
It seems like $page defined by preg_replace('/^(formida...put(INPUT_GET, 'page')) on line 64 can also be of type array<integer,string>; however, FrmPointers::do_page_pointer() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
68
		} else {
69
			$this->start_tour_pointer();
70
		}
71
	}
72
73
	/**
74
	 * Prints the pointer script
75
	 *
76
	 * @param string $selector The CSS selector the pointer is attached to.
77
	 * @param array  $options  The options for the pointer.
78
	 */
79
	public function print_scripts( $selector, $options ) {
80
		// Button1 is the close button, which always exists.
81
		$default_button = array(
82
			'text'     => false,
83
			'function' => '',
84
		);
85
		$button_array_defaults = array(
86
			'button2' => $default_button,
87
			'button3' => $default_button,
88
		);
89
		$this->button_array = wp_parse_args( $this->button_array, $button_array_defaults );
90
		?>
91
		<script type="text/javascript">
92
			//<![CDATA[
93
			(function ($) {
94
				// Don't show the tour on screens with an effective width smaller than 1024px or an effective height smaller than 768px.
95
				if (jQuery(window).width() < 1024 || jQuery(window).availWidth < 1024) {
96
					return;
97
				}
98
99
				var frm_pointer_options = <?php echo json_encode( $options ); ?>, setup;
100
101
				frm_pointer_options = $.extend(frm_pointer_options, {
102
					buttons: function (event, t) {
103
						var button = jQuery('<a href="<?php echo esc_url( $this->get_ignore_url() ); ?>" id="pointer-close" style="margin:0 5px;" class="button-secondary">' + '<?php _e( 'Close', 'formidable' ) ?>' + '</a>');
104
						button.bind('click.pointer', function () {
105
							t.element.pointer('close');
106
						});
107
						return button;
108
					},
109
					close: function () {
110
					}
111
				});
112
113
				setup = function () {
114
					$('<?php echo esc_attr( $selector ); ?>').pointer(frm_pointer_options).pointer('open');
115
					var lastOpenedPointer = jQuery( '.wp-pointer').slice( -1 );
116
					<?php
117
					$this->button2();
118
					$this->button3();
119
					?>
120
				};
121
122
				if (frm_pointer_options.position && frm_pointer_options.position.defer_loading)
123
					$(window).bind('load.wp-pointers', setup);
124
				else
125
					$(document).ready(setup);
126
			})(jQuery);
127
			//]]>
128
		</script>
129
	<?php
130
	}
131
132
	/**
133
	 * Render button 2, if needed
134
	 */
135 View Code Duplication
	private function button2() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
136
		if ( $this->button_array['button2']['text'] ) {
137
			?>
138
			lastOpenedPointer.find( '#pointer-close' ).after('<a id="pointer-primary" class="button-primary">' +
139
				'<?php echo esc_attr( $this->button_array['button2']['text'] ); ?>' + '</a>');
140
			lastOpenedPointer.find('#pointer-primary').click(function () {
141
			<?php echo $this->button_array['button2']['function']; ?>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
142
			});
143
		<?php
144
		}
145
	}
146
147
	/**
148
	 * Render button 3, if needed. This is the previous button in most cases
149
	 */
150 View Code Duplication
	private function button3() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
151
		if ( $this->button_array['button3']['text'] ) {
152
			?>
153
			lastOpenedPointer.find('#pointer-primary').after('<a id="pointer-ternary" style="float: left;" class="button-secondary">' +
154
				'<?php echo esc_attr( $this->button_array['button3']['text'] ); ?>' + '</a>');
155
			lastOpenedPointer.find('#pointer-ternary').click(function () {
156
			<?php echo $this->button_array['button3']['function']; ?>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
157
			});
158
		<?php }
159
	}
160
161
	/**
162
	 * Show a pointer that starts the tour
163
	 */
164
	private function start_tour_pointer() {
165
		$selector = 'li.toplevel_page_formidable';
166
167
		$content  = '<h3>' . __( 'Congratulations!', 'formidable' ) . '</h3>'
168
		            .'<p>' . $this->opening_line() . ' ' . sprintf( __( 'Click &#8220;Start Tour&#8221; to view a quick introduction of this plugin&#8217;s core functionality.' ), 'formidable' ) . '</p>';
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
169
		$opt_arr  = array(
170
			'content'  => $content,
171
			'position' => array( 'edge' => 'top', 'align' => 'center' ),
172
		);
173
174
		$this->button_array['button2']['text']     = __( 'Start Tour', 'formidable' );
175
		$this->button_array['button2']['function'] = sprintf( 'document.location="%s";', admin_url( 'admin.php?page=formidable' ) );
176
177
		$this->print_scripts( $selector, $opt_arr );
178
	}
179
180
	private function opening_line() {
181
		$opening = __( 'You&#8217;ve just installed a new form builder plugin!', 'formidable' );
182
		$affiliate = FrmAppHelper::get_affiliate();
183
		if ( $affiliate == 'mojo' ) {
184
			$opening = 'Your Forms plugin has been installed by MOJO Marketplace for your convenience.';
185
		}
186
		return $opening;
187
	}
188
189
	/**
190
	 * Shows a pointer on the proper pages
191
	 *
192
	 * @param string $page Admin page key.
193
	 */
194
	private function do_page_pointer( $page ) {
195
		$pointer = call_user_func( array( $this, $this->admin_pages[ $page ] ) );
196
197
		$opt_arr = array(
198
			'content'      => $pointer['content'],
199
			'position'     => array(
200
				'edge'  => 'top',
201
				'align' => ( is_rtl() ) ? 'right' : 'left',
202
			),
203
			'pointerWidth' => 450,
204
		);
205
206
		$selector = 'h2';
207
		if ( isset( $pointer['selector'] ) ) {
208
			$selector = $pointer['selector'];
209
		}
210
211
		if ( isset( $pointer['position'] ) ) {
212
			$opt_arr['position'] = $pointer['position'];
213
		}
214
215 View Code Duplication
		if ( isset( $pointer['next_page'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
216
			if ( ! empty( $pointer['next_page'] ) ) {
217
				$pointer['next_page'] = '-' . $pointer['next_page'];
218
			}
219
			$this->button_array['button2'] = array(
220
				'text'     => __( 'Next', 'formidable' ),
221
				'function' => 'window.location="' . esc_url_raw( admin_url( 'admin.php?page=formidable' . $pointer['next_page'] ) ) . '";',
222
			);
223
		}
224 View Code Duplication
		if ( isset( $pointer['prev_page'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
225
			if ( ! empty( $pointer['prev_page'] ) ) {
226
				$pointer['prev_page'] = '-' . $pointer['prev_page'];
227
			}
228
			$this->button_array['button3'] = array(
229
				'text'     => __( 'Previous', 'formidable' ),
230
				'function' => 'window.location="' . esc_url_raw( admin_url( 'admin.php?page=formidable' . $pointer['prev_page'] ) ) . '";',
231
			);
232
		}
233
		$this->print_scripts( $selector, $opt_arr );
234
	}
235
236
	/**
237
	 * Returns the content of the Forms listing page pointer
238
	 *
239
	 * @return array
240
	 */
241
	private function forms_pointer() {
242
		global $current_user;
243
244
		return array(
245
			'content'   => '<h3>' . __( 'Forms', 'formidable' ) . '</h3>'
246
			               . '<p>' . __( 'All your forms will be listed on this page. Create your first form by clicking on the "Add New" button.', 'formidable' ) . '</p>'
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
247
			               . '<p><strong>' . __( 'Subscribe to our Newsletter', 'formidable' ) . '</strong><br/>'
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
248
			               . sprintf( __( 'If you would like to hear about new features and updates for %1$s, subscribe to our newsletter:', 'formidable' ), 'Formidable' ) . '</p>'
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
249
			               . '<form target="_blank" action="//formidablepro.us1.list-manage.com/subscribe/post?u=a4a913790ffb892daacc6f271&amp;id=7e7df15967" method="post" selector="newsletter-form" accept-charset="' . esc_attr( get_bloginfo( 'charset' ) ) . '">'
250
			               . '<p>'
251
			               . '<input style="margin: 5px; color:#666" name="EMAIL" value="' . esc_attr( $current_user->user_email ) . '" selector="newsletter-email" placeholder="' . esc_attr__( 'Email', 'formidable' ) . '"/>'
252
						   . '<input type="hidden" name="group[4505]" value="4" />'
253
			               . '<button type="submit" class="button-primary">' . esc_html__( 'Subscribe', 'formidable' ) . '</button>'
254
			               . '</p>'
255
			               . '</form>',
256
			'next_page' => 'entries',
257
		);
258
	}
259
260
	/**
261
	 * Returns the content of the Entries listing page pointer
262
	 *
263
	 * @return array
264
	 */
265 View Code Duplication
	private function entries_pointer() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
266
		return array(
267
			'content'   => '<h3>' . __( 'Entries', 'formidable' ) . '</h3>'
268
			               . '<p>' . __( 'Each time one of your forms is submitted, an entry is created. You will find every form submission listed here so you will always have a backup if an email fails.', 'formidable' ) . '</p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
269
			'prev_page' => '',
270
			'next_page' => 'styles',
271
			'selector'  => '.wp-list-table',
272
			'position'  => array( 'edge' => 'bottom', 'align' => 'center' ),
273
		);
274
	}
275
276
	/**
277
	 * Returns the content of the Styles page pointer
278
	 *
279
	 * @return array
280
	 */
281 View Code Duplication
	private function styles_pointer() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
282
		return array(
283
			'content'   => '<h3>' . __( 'Styles', 'formidable' ) . '</h3>'
284
			               . '<p>' . __( 'Want to make changes to the way your forms look? Make all the changes you would like right here, and watch the sample form change before your eyes.', 'formidable' ) . '</p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
285
			'prev_page' => 'entries',
286
			'next_page' => 'import',
287
			'selector'  => '.general-style',
288
			'position'  => array( 'edge' => 'left', 'align' => 'right' ),
289
		);
290
	}
291
292
	/**
293
	 * Returns the content of the Import/Export page pointer
294
	 *
295
	 * @return array
296
	 */
297 View Code Duplication
	private function import_pointer() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
298
		return array(
299
			'content'   => '<h3>' . __( 'Import/Export', 'formidable' ) . '</h3>'
300
			               . '<p>' . __( 'Import and export forms and styles when copying from one site to another or sharing with someone else. Your entries can be exported to a CSV as well. The Premium version also includes the option to import entries to your site from a CSV.', 'formidable' ) . '</p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
301
			'prev_page' => 'styles',
302
			'next_page' => 'settings',
303
			'selector'  => '.inside.with_frm_style',
304
			'position'  => array( 'edge' => 'bottom', 'align' => 'top' ),
305
		);
306
	}
307
308
	/**
309
	 * Returns the content of the advanced page pointer
310
	 *
311
	 * @return array
312
	 */
313
	private function settings_pointer() {
314
		return array(
315
			'content'   => '<h3>' . __( 'Global Settings', 'formidable' ) . '</h3>'
316
				. '<p><strong>' . __( 'General', 'formidable' ) . '</strong><br/>'
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
317
				. __( 'Turn stylesheets and scripts off, set which user roles have access to change and create forms, setup your reCaptcha, and set default messages for new forms and fields.', 'formidable' )
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
318
				. '<p><strong>' . __( 'Plugin Licenses', 'formidable' ) . '</strong><br/>'
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
319
				. sprintf( __( 'Once you&#8217;ve purchased %1$s or any addons, you&#8217;ll have to enter a license key to get access to all of their powerful features. A Plugin Licenses tab will appear here for you to enter your license key.', 'formidable' ), 'Formidable Pro' )
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
320
           	    . '</p>',
321
			'prev_page' => 'import',
322
			'next_page' => 'addons',
323
		);
324
	}
325
326
	/**
327
	 * Returns the content of the extensions and licenses page pointer
328
	 *
329
	 * @return array
330
	 */
331
	private function addons_pointer() {
332
		return array(
333
			'content'   => '<h3>' . __( 'Addons', 'formidable' ) . '</h3>'
334
			               . '<p>' . sprintf( __( 'The powerful functions of %1$s can be extended with %2$spremium plugins%3$s. You can read all about the Formidable Premium Plugins %2$shere%3$s.', 'formidable' ), 'Formidable', '<a target="_blank" href="' . esc_url( FrmAppHelper::make_affiliate_url( 'https://formidablepro.com/' ) ) . '">', '</a>' )
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
335
						   . '</p>'
336
			               . '<p><strong>' . __( 'Like this plugin?', 'formidable' ) . '</strong><br/>' . sprintf( __( 'So, we&#8217;ve come to the end of the tour. If you like the plugin, please %srate it 5 stars on WordPress.org%s!', 'formidable' ), '<a target="_blank" href="https://wordpress.org/plugins/formidable/">', '</a>' ) . '</p>'
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
337
			               . '<p>' . sprintf( __( 'Thank you for using our plugin and good luck with your forms!<br/><br/>Best,<br/>Team Formidable - %1$sformidablepro.com%2$s', 'formidable' ), '<a target="_blank" href="' . esc_url( FrmAppHelper::make_affiliate_url( 'https://formidablepro.com/' ) ) . '">', '</a>' ) . '</p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
338
			'prev_page' => 'settings',
339
		);
340
	}
341
342
	/**
343
	 * Extending the current page URL with two params to be able to ignore the tour.
344
	 *
345
	 * @return mixed
346
	 */
347
	private function get_ignore_url() {
348
		$arr_params = array(
349
			'frm_restart_tour' => false,
350
			'frm_ignore_tour'  => '1',
351
			'nonce'            => wp_create_nonce( 'frm-ignore-tour' ),
352
		);
353
354
		return add_query_arg( $arr_params );
355
	}
356
}
357