Object_Sync_Sf_Admin::fields_errors()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 37
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 29
nc 2
nop 3
dl 0
loc 37
rs 9.456
c 0
b 0
f 0
1
<?php
2
/**
3
 * Create default WordPress admin functionality to configure the plugin.
4
 *
5
 * @class   Object_Sync_Sf_Admin
6
 * @package Object_Sync_Salesforce
7
 */
8
9
defined( 'ABSPATH' ) || exit;
10
11
/**
12
 * Object_Sync_Sf_Admin class.
13
 */
14
class Object_Sync_Sf_Admin {
15
16
	/**
17
	 * Current version of the plugin
18
	 *
19
	 * @var string
20
	 */
21
	public $version;
22
23
	/**
24
	 * The main plugin file
25
	 *
26
	 * @var string
27
	 */
28
	public $file;
29
30
	/**
31
	 * Global object of `$wpdb`, the WordPress database
32
	 *
33
	 * @var object
34
	 */
35
	public $wpdb;
36
37
	/**
38
	 * The plugin's slug so we can include it when necessary
39
	 *
40
	 * @var string
41
	 */
42
	public $slug;
43
44
	/**
45
	 * The plugin's prefix when saving options to the database
46
	 *
47
	 * @var string
48
	 */
49
	public $option_prefix;
50
51
	/**
52
	 * Suffix for group name in ActionScheduler
53
	 *
54
	 * @var string
55
	 */
56
	public $action_group_suffix;
57
58
	/**
59
	 * Login credentials for the Salesforce API; comes from wp-config or from the plugin settings
60
	 *
61
	 * @var array
62
	 */
63
	public $login_credentials;
64
65
	/**
66
	 * Array of what classes in the plugin can be scheduled to occur with `wp_cron` events
67
	 *
68
	 * @var array
69
	 */
70
	public $schedulable_classes;
71
72
	/**
73
	 * Object_Sync_Sf_Queue class
74
	 *
75
	 * @var object
76
	 */
77
	public $queue;
78
79
	/**
80
	 * Object_Sync_Sf_Logging class
81
	 *
82
	 * @var object
83
	 */
84
	public $logging;
85
86
	/**
87
	 * Object_Sync_Sf_Mapping class
88
	 *
89
	 * @var object
90
	 */
91
	public $mappings;
92
93
	/**
94
	 * Object_Sync_Sf_WordPress class
95
	 *
96
	 * @var object
97
	 */
98
	public $wordpress;
99
100
	/**
101
	 * Object_Sync_Sf_Salesforce class
102
	 * This contains Salesforce API methods
103
	 *
104
	 * @var array
105
	 */
106
	public $salesforce;
107
108
	/**
109
	 * Object_Sync_Sf_Salesforce_Push class
110
	 *
111
	 * @var object
112
	 */
113
	public $push;
114
115
	/**
116
	 * Object_Sync_Sf_Salesforce_Pull class
117
	 *
118
	 * @var object
119
	 */
120
	public $pull;
121
122
	/**
123
	 * Object_Sync_Sf_WordPress_Transient class
124
	 *
125
	 * @var object
126
	 */
127
	private $sfwp_transients;
128
129
	/**
130
	 * URL fragment for the plugin's settings page
131
	 *
132
	 * @var string
133
	 */
134
	private $admin_settings_url_param;
135
136
	/**
137
	 * Data for admin notices
138
	 *
139
	 * @var array
140
	 */
141
	public $notices_data;
142
143
	/**
144
	 * Salesforce access token
145
	 *
146
	 * @var string
147
	 */
148
	private $access_token;
149
150
	/**
151
	 * Salesforce instance URL
152
	 *
153
	 * @var string
154
	 */
155
	private $instance_url;
156
157
	/**
158
	 * Salesforce refresh token
159
	 *
160
	 * @var string
161
	 */
162
	private $refresh_token;
163
164
	/**
165
	 * Default path for the Salesforce authorize URL
166
	 *
167
	 * @var string
168
	 */
169
	public $default_authorize_url_path;
170
171
	/**
172
	 * Default path for the Salesforce token URL
173
	 *
174
	 * @var string
175
	 */
176
	public $default_token_url_path;
177
178
	/**
179
	 * What version of the Salesforce API should be the default on the settings screen.
180
	 * Users can edit what version is used, but they won't see a correct list of all their available versions until WordPress has
181
	 * been authenticated with Salesforce.
182
	 *
183
	 * @var string
184
	 * @deprecated as of 2.2.0; will be removed in version 3.0. This property will stay until 3.0.0 because it is a public value and it could be accessed by other code.
185
	 */
186
	public $default_api_version;
187
188
	/**
189
	 * Default max number of pull records. Users can edit this.
190
	 *
191
	 * @var int
192
	 */
193
	public $default_pull_limit;
194
195
	/**
196
	 * Default throttle for how often to pull from Salesforce. Users can edit this.
197
	 *
198
	 * @var int
199
	 */
200
	public $default_pull_throttle;
201
202
	/**
203
	 * Default for whether to limit to triggerable items. Users can edit this.
204
	 *
205
	 * @var bool
206
	 */
207
	public $default_triggerable;
208
209
	/**
210
	 * Default for whether to limit to items that can be updated. Users can edit this.
211
	 *
212
	 * @var bool
213
	 */
214
	public $default_updateable;
215
216
	/**
217
	 * Constructor for admin class
218
	 */
219
	public function __construct() {
220
		$this->version             = object_sync_for_salesforce()->version;
221
		$this->file                = object_sync_for_salesforce()->file;
222
		$this->wpdb                = object_sync_for_salesforce()->wpdb;
223
		$this->slug                = object_sync_for_salesforce()->slug;
224
		$this->option_prefix       = object_sync_for_salesforce()->option_prefix;
225
		$this->action_group_suffix = object_sync_for_salesforce()->action_group_suffix;
226
227
		$this->login_credentials   = object_sync_for_salesforce()->login_credentials;
228
		$this->wordpress           = object_sync_for_salesforce()->wordpress;
229
		$this->salesforce          = object_sync_for_salesforce()->salesforce;
230
		$this->mappings            = object_sync_for_salesforce()->mappings;
231
		$this->push                = object_sync_for_salesforce()->push;
232
		$this->pull                = object_sync_for_salesforce()->pull;
233
		$this->logging             = object_sync_for_salesforce()->logging;
234
		$this->schedulable_classes = object_sync_for_salesforce()->schedulable_classes;
235
		$this->queue               = object_sync_for_salesforce()->queue;
236
237
		// set the Salesforce API version.
238
		// as of version 2.2.0, this is set by the plugin and is not configurable in the interface.
239
		// this class variable will be removed in 3.0.0.
240
		$this->default_api_version = $this->login_credentials['rest_api_version'];
0 ignored issues
show
Deprecated Code introduced by
The property Object_Sync_Sf_Admin::$default_api_version has been deprecated: as of 2.2.0; will be removed in version 3.0. This property will stay until 3.0.0 because it is a public value and it could be accessed by other code. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

240
		/** @scrutinizer ignore-deprecated */ $this->default_api_version = $this->login_credentials['rest_api_version'];

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
241
242
		$this->sfwp_transients          = object_sync_for_salesforce()->wordpress->sfwp_transients;
243
		$this->admin_settings_url_param = 'object-sync-salesforce-admin';
244
		$this->notices_data             = $this->notices_data();
245
246
		// default authorize url path.
247
		$this->default_authorize_url_path = '/services/oauth2/authorize';
248
		// default token url path.
249
		$this->default_token_url_path = '/services/oauth2/token';
250
		// default pull record limit.
251
		$this->default_pull_limit = 25;
252
		// default pull throttle for avoiding going over api limits.
253
		$this->default_pull_throttle = 5;
254
		// default setting for triggerable items.
255
		$this->default_triggerable = true;
256
		// default setting for updateable items.
257
		$this->default_updateable = true;
258
259
		$this->add_actions();
260
	}
261
262
	/**
263
	 * Create the action hooks to create the admin pages.
264
	 */
265
	public function add_actions() {
266
267
		// settings link.
268
		add_filter( 'plugin_action_links', array( $this, 'plugin_action_links' ), 10, 5 );
0 ignored issues
show
Bug introduced by
The function add_filter was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

268
		/** @scrutinizer ignore-call */ 
269
  add_filter( 'plugin_action_links', array( $this, 'plugin_action_links' ), 10, 5 );
Loading history...
269
270
		// CSS and Javascript.
271
		add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts_and_styles' ) );
0 ignored issues
show
Bug introduced by
The function add_action was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

271
		/** @scrutinizer ignore-call */ 
272
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts_and_styles' ) );
Loading history...
272
273
		// Settings API forms and notices.
274
		add_action( 'admin_menu', array( $this, 'create_admin_menu' ) );
275
		add_action( 'admin_init', array( $this, 'salesforce_settings_forms' ) );
276
		add_action( 'admin_init', array( $this, 'display_notices' ) );
277
		add_action( 'admin_post_post_fieldmap', array( $this, 'prepare_fieldmap_data' ) );
278
		add_action( 'admin_post_delete_fieldmap', array( $this, 'delete_fieldmap' ) );
279
280
		// Ajax for fieldmap forms.
281
		add_action( 'wp_ajax_get_salesforce_object_description', array( $this, 'get_salesforce_object_description' ), 10, 1 );
282
		add_action( 'wp_ajax_get_salesforce_object_fields', array( $this, 'get_salesforce_object_fields' ), 10, 1 );
283
		add_action( 'wp_ajax_get_wordpress_object_fields', array( $this, 'get_wordpress_object_fields' ), 10, 1 );
284
285
		// Ajax events that can be manually called.
286
		add_action( 'wp_ajax_push_to_salesforce', array( $this, 'push_to_salesforce' ), 10, 3 );
287
		add_action( 'wp_ajax_pull_from_salesforce', array( $this, 'pull_from_salesforce' ), 10, 2 );
288
		add_action( 'wp_ajax_refresh_mapped_data', array( $this, 'refresh_mapped_data' ), 10, 1 );
289
		add_action( 'wp_ajax_clear_sfwp_cache', array( $this, 'clear_sfwp_cache' ) );
290
		add_action( 'wp_ajax_delete_salesforce_api_version', array( $this, 'delete_salesforce_api_version' ) );
291
292
		// we add a Salesforce box on user profiles.
293
		add_action( 'edit_user_profile', array( $this, 'show_salesforce_user_fields' ), 10, 1 );
294
		add_action( 'show_user_profile', array( $this, 'show_salesforce_user_fields' ), 10, 1 );
295
296
		// and we can update Salesforce fields on the user profile box.
297
		add_action( 'personal_options_update', array( $this, 'save_salesforce_user_fields' ), 10, 1 );
298
		add_action( 'edit_user_profile_update', array( $this, 'save_salesforce_user_fields' ), 10, 1 );
299
300
		// when either field for schedule settings changes.
301
		foreach ( $this->schedulable_classes as $key => $value ) {
302
			// if the user doesn't have any action schedule tasks, let's not leave them empty.
303
			add_filter( 'pre_update_option_' . $this->option_prefix . $key . '_schedule_number', array( $this, 'initial_action_schedule' ), 10, 3 );
304
			add_filter( 'pre_update_option_' . $this->option_prefix . $key . '_schedule_unit', array( $this, 'initial_action_schedule' ), 10, 3 );
305
306
			// this is if the user is changing their tasks.
307
			add_filter( 'update_option_' . $this->option_prefix . $key . '_schedule_number', array( $this, 'change_action_schedule' ), 10, 3 );
308
			add_filter( 'update_option_' . $this->option_prefix . $key . '_schedule_unit', array( $this, 'change_action_schedule' ), 10, 3 );
309
		}
310
311
		// when ActionScheduler runs its migration, resave the schedule options.
312
		add_action( 'action_scheduler/migration_complete', array( $this, 'resave_action_schedules' ) );
313
314
		// handle post requests for object maps.
315
		add_action( 'admin_post_delete_object_map', array( $this, 'delete_object_map' ) );
316
		add_action( 'admin_post_post_object_map', array( $this, 'prepare_object_map_data' ) );
317
318
		// import and export plugin data.
319
		add_action( 'admin_post_object_sync_for_salesforce_import', array( $this, 'import_json_file' ) );
320
		add_action( 'admin_post_object_sync_for_salesforce_export', array( $this, 'export_json_file' ) );
321
322
	}
323
324
	/**
325
	 * Display a Settings link on the main Plugins page
326
	 *
327
	 * @param array  $links the array of links for the main plugins page.
328
	 * @param string $file the filename.
329
	 * @return array $links the array of links for the main plugins page
330
	 */
331
	public function plugin_action_links( $links, $file ) {
332
		if ( plugin_basename( $this->file ) === $file ) {
0 ignored issues
show
Bug introduced by
The function plugin_basename was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

332
		if ( /** @scrutinizer ignore-call */ plugin_basename( $this->file ) === $file ) {
Loading history...
333
			$settings = '<a href="' . get_admin_url() . 'options-general.php?page=' . $this->admin_settings_url_param . '">' . __( 'Settings', 'object-sync-for-salesforce' ) . '</a>';
0 ignored issues
show
Bug introduced by
The function get_admin_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

333
			$settings = '<a href="' . /** @scrutinizer ignore-call */ get_admin_url() . 'options-general.php?page=' . $this->admin_settings_url_param . '">' . __( 'Settings', 'object-sync-for-salesforce' ) . '</a>';
Loading history...
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

333
			$settings = '<a href="' . get_admin_url() . 'options-general.php?page=' . $this->admin_settings_url_param . '">' . /** @scrutinizer ignore-call */ __( 'Settings', 'object-sync-for-salesforce' ) . '</a>';
Loading history...
334
			array_unshift( $links, $settings );
335
		}
336
		return $links;
337
	}
338
339
	/**
340
	 * Admin styles. Load the CSS and JavaScript for the plugin's settings
341
	 */
342
	public function admin_scripts_and_styles() {
343
344
		// Developers might not want to bother with select2 or selectwoo, so we allow that to be changeable.
345
		$select_library = apply_filters( $this->option_prefix . 'select_library', 'selectwoo' );
0 ignored issues
show
Bug introduced by
The function apply_filters was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

345
		$select_library = /** @scrutinizer ignore-call */ apply_filters( $this->option_prefix . 'select_library', 'selectwoo' );
Loading history...
346
347
		/*
348
		 * example to modify the select library
349
		 * add_filter( 'object_sync_for_salesforce_select_library', 'select_library', 10, 1 );
350
		 * function select_library( $select_library ) {
351
		 * 	$select_library = 'select2';
352
		 *  // this could also be empty; in that case we would just use default browser select
353
		 * 	return $select_library;
354
		 * }
355
		*/
356
357
		$javascript_dependencies = array( 'jquery' );
358
		$css_dependencies        = array();
359
		if ( '' !== $select_library ) {
360
			wp_enqueue_script( $select_library . 'js', plugins_url( 'assets/js/vendor/' . $select_library . '.min.js', $this->file ), array( 'jquery' ), filemtime( plugin_dir_path( $this->file ) . 'assets/js/vendor/' . $select_library . '.min.js' ), true );
0 ignored issues
show
Bug introduced by
The function plugin_dir_path was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

360
			wp_enqueue_script( $select_library . 'js', plugins_url( 'assets/js/vendor/' . $select_library . '.min.js', $this->file ), array( 'jquery' ), filemtime( /** @scrutinizer ignore-call */ plugin_dir_path( $this->file ) . 'assets/js/vendor/' . $select_library . '.min.js' ), true );
Loading history...
Bug introduced by
The function plugins_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

360
			wp_enqueue_script( $select_library . 'js', /** @scrutinizer ignore-call */ plugins_url( 'assets/js/vendor/' . $select_library . '.min.js', $this->file ), array( 'jquery' ), filemtime( plugin_dir_path( $this->file ) . 'assets/js/vendor/' . $select_library . '.min.js' ), true );
Loading history...
Bug introduced by
The function wp_enqueue_script was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

360
			/** @scrutinizer ignore-call */ 
361
   wp_enqueue_script( $select_library . 'js', plugins_url( 'assets/js/vendor/' . $select_library . '.min.js', $this->file ), array( 'jquery' ), filemtime( plugin_dir_path( $this->file ) . 'assets/js/vendor/' . $select_library . '.min.js' ), true );
Loading history...
361
			$javascript_dependencies[] = $select_library . 'js';
362
			wp_enqueue_style( $select_library . 'css', plugins_url( 'assets/css/vendor/' . $select_library . '.min.css', $this->file ), array(), filemtime( plugin_dir_path( $this->file ) . 'assets/css/vendor/' . $select_library . '.min.css' ), 'all' );
0 ignored issues
show
Bug introduced by
The function wp_enqueue_style was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

362
			/** @scrutinizer ignore-call */ 
363
   wp_enqueue_style( $select_library . 'css', plugins_url( 'assets/css/vendor/' . $select_library . '.min.css', $this->file ), array(), filemtime( plugin_dir_path( $this->file ) . 'assets/css/vendor/' . $select_library . '.min.css' ), 'all' );
Loading history...
363
			$css_dependencies[] = $select_library . 'css';
364
		}
365
366
		wp_enqueue_script( $this->slug . '-admin', plugins_url( 'assets/js/object-sync-for-salesforce-admin.min.js', $this->file ), $javascript_dependencies, filemtime( plugin_dir_path( $this->file ) . 'assets/js/object-sync-for-salesforce-admin.min.js' ), true );
367
		wp_enqueue_style( $this->slug . '-admin', plugins_url( 'assets/css/object-sync-for-salesforce-admin.css', $this->file ), $css_dependencies, filemtime( plugin_dir_path( $this->file ) . 'assets/css/object-sync-for-salesforce-admin.css' ), 'all' );
368
	}
369
370
	/**
371
	 * Initial recurring tasks for ActionScheduler
372
	 *
373
	 * @param string $new_schedule the new, unserialized option value.
374
	 * @param string $old_schedule the old option value.
375
	 * @param string $option_name option name.
376
	 * @return string $new_schedule
377
	 */
378
	public function initial_action_schedule( $new_schedule, $old_schedule, $option_name ) {
379
380
		// get the current schedule name from the task, based on pattern in the foreach.
381
		preg_match( '/' . $this->option_prefix . '(.*)_schedule/', $option_name, $matches );
382
		$schedule_name     = $matches[1];
383
		$action_group_name = $schedule_name . $this->action_group_suffix;
384
385
		// make sure there are no tasks already.
386
		$current_tasks = as_get_scheduled_actions(
387
			array(
388
				'hook'  => $this->schedulable_classes[ $schedule_name ]['initializer'],
389
				'group' => $action_group_name,
390
			),
391
			ARRAY_A
0 ignored issues
show
Bug introduced by
The constant ARRAY_A was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
392
		);
393
394
		// exit if there are already tasks; they'll be saved if the option data changed.
395
		if ( ! empty( $current_tasks ) ) {
396
			return $new_schedule;
397
		}
398
399
		$this->set_action_schedule( $schedule_name, $action_group_name );
400
401
		return $new_schedule;
402
403
	}
404
405
	/**
406
	 * Update recurring tasks for ActionScheduler if options change
407
	 *
408
	 * @param string $old_schedule the old option value.
409
	 * @param string $new_schedule the new, unserialized option value.
410
	 * @param string $option_name option name.
411
	 */
412
	public function change_action_schedule( $old_schedule, $new_schedule, $option_name ) {
413
414
		// this method does not run if the option's data is unchanged.
415
416
		// get the current schedule name from the task, based on pattern in the foreach.
417
		preg_match( '/' . $this->option_prefix . '(.*)_schedule/', $option_name, $matches );
418
		$schedule_name     = $matches[1];
419
		$action_group_name = $schedule_name . $this->action_group_suffix;
420
421
		$this->set_action_schedule( $schedule_name, $action_group_name );
422
423
	}
424
425
	/**
426
	 * Set up recurring tasks for ActionScheduler
427
	 *
428
	 * @param string $schedule_name the name of the schedule.
429
	 * @param string $action_group_name the group's name.
430
	 */
431
	private function set_action_schedule( $schedule_name, $action_group_name ) {
432
		// exit if there is no initializer property on this schedule.
433
		if ( ! isset( $this->schedulable_classes[ $schedule_name ]['initializer'] ) ) {
434
			return;
435
		}
436
437
		// cancel previous task.
438
		$this->queue->cancel(
439
			$this->schedulable_classes[ $schedule_name ]['initializer'],
440
			array(),
441
			$action_group_name
442
		);
443
444
		// create new recurring task for ActionScheduler to check for data to pull from Salesforce.
445
		$this->queue->schedule_recurring(
446
			time(), // plugin seems to expect UTC.
447
			$this->queue->get_frequency( $schedule_name, 'seconds' ),
448
			$this->schedulable_classes[ $schedule_name ]['initializer'],
449
			array(),
450
			$action_group_name
451
		);
452
	}
453
454
	/**
455
	 * When it finishes its migration, resave the scheduled tasks for ActionScheduler.
456
	 */
457
	public function resave_action_schedules() {
458
		// for each schedulable action, go ahead and resave it.
459
		$schedules_updated  = array();
460
		$schedules_restored = array();
461
		foreach ( $this->schedulable_classes as $key => $value ) {
462
			// make sure it has an initializer property; this is used on recurring tasks.
463
			if ( isset( $value['initializer'] ) ) {
464
				// toggle the schedule number setting.
465
				$schedule_option_name  = $this->option_prefix . $key . '_schedule_number';
466
				$previous_option_value = get_option( $schedule_option_name, 0 );
0 ignored issues
show
Bug introduced by
The function get_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

466
				$previous_option_value = /** @scrutinizer ignore-call */ get_option( $schedule_option_name, 0 );
Loading history...
467
				$previous_option_value = filter_var( $previous_option_value, FILTER_SANITIZE_NUMBER_INT );
468
				$new_option_value      = $previous_option_value + 1;
469
				$schedule_updated      = update_option( $schedule_option_name, $new_option_value );
0 ignored issues
show
Bug introduced by
The function update_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

469
				$schedule_updated      = /** @scrutinizer ignore-call */ update_option( $schedule_option_name, $new_option_value );
Loading history...
470
				if ( true === $schedule_updated ) {
471
					$schedules_updated[] = $key;
472
					$schedule_restored   = update_option( $schedule_option_name, $previous_option_value );
473
					if ( true === $schedule_restored ) {
474
						$schedules_restored[] = $key;
475
					}
476
				}
477
			}
478
		}
479
480
		// create a log entry from the updated scheduled tasks.
481
		if ( ! empty( $schedules_updated ) || ! empty( $schedules_restored ) ) {
482
			$status = 'success';
483
		} else {
484
			$status = 'error';
485
		}
486
487
		$body = sprintf( esc_html__( 'These are the scheduled tasks that were updated: ', 'object-sync-for-salesforce' ) . '<ul>' );
0 ignored issues
show
Bug introduced by
The function esc_html__ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

487
		$body = sprintf( /** @scrutinizer ignore-call */ esc_html__( 'These are the scheduled tasks that were updated: ', 'object-sync-for-salesforce' ) . '<ul>' );
Loading history...
488
		foreach ( $schedules_updated as $schedule_updated ) {
489
			$body .= sprintf(
490
				// translators: placeholders are: 1) the schedule name.
491
				'<li>' . esc_html__( 'Schedule name: %1$s.', 'object-sync-for-salesforce' ) . '</li>',
492
				esc_attr( $schedule_updated )
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

492
				/** @scrutinizer ignore-call */ 
493
    esc_attr( $schedule_updated )
Loading history...
493
			);
494
		}
495
		$body .= '</ul>';
496
497
		$body .= sprintf( esc_html__( 'These are the scheduled tasks that have the same frequency as they had pre-migration: ', 'object-sync-for-salesforce' ) . '<ul>' );
498
		foreach ( $schedules_restored as $schedule_restored ) {
499
			$body .= sprintf(
500
				// translators: placeholders are: 1) the schedule name.
501
				'<li>' . esc_html__( 'Schedule name: %1$s.', 'object-sync-for-salesforce' ) . '</li>',
502
				esc_attr( $schedule_restored )
503
			);
504
		}
505
		$body .= '</ul>';
506
507
		$body .= sprintf( esc_html__( 'If any tasks were not updated, or were not able to keep the same frequency they had before, go to the Scheduling tab to update them.', 'object-sync-for-salesforce' ) );
508
		$body .= sprintf(
509
			// translators: %1$s is the schedule settings URL.
510
			wp_kses_post( 'If any tasks were not updated, or were not able to keep the same frequency they had before, go to the <a href="' . admin_url( 'options-general.php?page=object-sync-salesforce-admin&tab=schedule' ) . '">%1$s</a> tab to update them.', 'object-sync-for-salesforce' ),
0 ignored issues
show
Bug introduced by
The function wp_kses_post was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

510
			/** @scrutinizer ignore-call */ 
511
   wp_kses_post( 'If any tasks were not updated, or were not able to keep the same frequency they had before, go to the <a href="' . admin_url( 'options-general.php?page=object-sync-salesforce-admin&tab=schedule' ) . '">%1$s</a> tab to update them.', 'object-sync-for-salesforce' ),
Loading history...
Bug introduced by
The function admin_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

510
			wp_kses_post( 'If any tasks were not updated, or were not able to keep the same frequency they had before, go to the <a href="' . /** @scrutinizer ignore-call */ admin_url( 'options-general.php?page=object-sync-salesforce-admin&tab=schedule' ) . '">%1$s</a> tab to update them.', 'object-sync-for-salesforce' ),
Loading history...
511
			esc_html__( 'Scheduling', 'object-sync-for-salesforce' )
512
		);
513
514
		$this->logging->setup(
515
			sprintf(
516
				// translators: %1$s is the log status, %2$s is the name of a WordPress object. %3$s is the id of that object.
517
				esc_html__( '%1$s ActionScheduler: the ActionScheduler library has completed its migration. See the log entry content for status on each recurring task.', 'object-sync-for-salesforce' ),
518
				ucfirst( esc_attr( $status ) )
519
			),
520
			$body,
521
			0,
522
			0,
523
			$status
524
		);
525
	}
526
527
	/**
528
	 * Create the WordPress admin options page
529
	 */
530
	public function create_admin_menu() {
531
		$title = __( 'Salesforce', 'object-sync-for-salesforce' );
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

531
		$title = /** @scrutinizer ignore-call */ __( 'Salesforce', 'object-sync-for-salesforce' );
Loading history...
532
		add_options_page( $title, $title, 'configure_salesforce', $this->admin_settings_url_param, array( $this, 'show_admin_page' ) );
0 ignored issues
show
Bug introduced by
The function add_options_page was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

532
		/** @scrutinizer ignore-call */ 
533
  add_options_page( $title, $title, 'configure_salesforce', $this->admin_settings_url_param, array( $this, 'show_admin_page' ) );
Loading history...
533
	}
534
535
	/**
536
	 * Render the admin pages in WordPress. This also allows other plugins to add tabs to this plugin's settings screen
537
	 */
538
	public function show_admin_page() {
539
		$get_data = filter_input_array( INPUT_GET, FILTER_SANITIZE_SPECIAL_CHARS );
540
		echo '<div class="wrap">';
541
		echo '<h1>' . esc_html( get_admin_page_title() ) . '</h1>';
0 ignored issues
show
Bug introduced by
The function get_admin_page_title was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

541
		echo '<h1>' . esc_html( /** @scrutinizer ignore-call */ get_admin_page_title() ) . '</h1>';
Loading history...
Bug introduced by
The function esc_html was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

541
		echo '<h1>' . /** @scrutinizer ignore-call */ esc_html( get_admin_page_title() ) . '</h1>';
Loading history...
542
		$allowed = $this->check_wordpress_admin_permissions();
543
		if ( false === $allowed ) {
544
			return;
545
		}
546
		$tabs = array(
547
			'settings'      => __( 'Settings', 'object-sync-for-salesforce' ),
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

547
			'settings'      => /** @scrutinizer ignore-call */ __( 'Settings', 'object-sync-for-salesforce' ),
Loading history...
548
			'authorize'     => __( 'Authorize', 'object-sync-for-salesforce' ),
549
			'fieldmaps'     => __( 'Fieldmaps', 'object-sync-for-salesforce' ),
550
			'schedule'      => __( 'Scheduling', 'object-sync-for-salesforce' ),
551
			'import-export' => __( 'Import &amp; Export', 'object-sync-for-salesforce' ),
552
		); // this creates the tabs for the admin.
553
554
		// optionally make tab(s) for logging and log settings.
555
		$logging_enabled      = get_option( $this->option_prefix . 'enable_logging', false );
0 ignored issues
show
Bug introduced by
The function get_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

555
		$logging_enabled      = /** @scrutinizer ignore-call */ get_option( $this->option_prefix . 'enable_logging', false );
Loading history...
556
		$tabs['log_settings'] = __( 'Log Settings', 'object-sync-for-salesforce' );
557
558
		$mapping_errors       = $this->mappings->get_failed_object_maps();
559
		$mapping_errors_total = isset( $mapping_errors['total'] ) ? $mapping_errors['total'] : 0;
560
		if ( 0 < $mapping_errors_total ) {
561
			$tabs['mapping_errors'] = __( 'Mapping Errors', 'object-sync-for-salesforce' );
562
		}
563
564
		// filter for extending the tabs available on the page
565
		// currently it will go into the default switch case for $tab.
566
		$tabs = apply_filters( $this->option_prefix . 'settings_tabs', $tabs );
0 ignored issues
show
Bug introduced by
The function apply_filters was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

566
		$tabs = /** @scrutinizer ignore-call */ apply_filters( $this->option_prefix . 'settings_tabs', $tabs );
Loading history...
567
568
		$tab = isset( $get_data['tab'] ) ? sanitize_key( $get_data['tab'] ) : 'settings';
0 ignored issues
show
Bug introduced by
The function sanitize_key was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

568
		$tab = isset( $get_data['tab'] ) ? /** @scrutinizer ignore-call */ sanitize_key( $get_data['tab'] ) : 'settings';
Loading history...
569
		$this->tabs( $tabs, $tab );
570
571
		$consumer_key    = $this->login_credentials['consumer_key'];
572
		$consumer_secret = $this->login_credentials['consumer_secret'];
573
		$callback_url    = $this->login_credentials['callback_url'];
574
575
		if ( true !== $this->salesforce['is_authorized'] ) {
576
			$url     = esc_url( $callback_url );
0 ignored issues
show
Bug introduced by
The function esc_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

576
			$url     = /** @scrutinizer ignore-call */ esc_url( $callback_url );
Loading history...
577
			$anchor  = esc_html__( 'Authorize tab', 'object-sync-for-salesforce' );
0 ignored issues
show
Bug introduced by
The function esc_html__ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

577
			$anchor  = /** @scrutinizer ignore-call */ esc_html__( 'Authorize tab', 'object-sync-for-salesforce' );
Loading history...
578
			$message = sprintf( 'Salesforce needs to be authorized to connect to this website. Use the <a href="%s">%s</a> to connect.', $url, $anchor );
579
			require plugin_dir_path( $this->file ) . '/templates/admin/error.php';
0 ignored issues
show
Bug introduced by
The function plugin_dir_path was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

579
			require /** @scrutinizer ignore-call */ plugin_dir_path( $this->file ) . '/templates/admin/error.php';
Loading history...
580
		}
581
582
		if ( 0 === count( $this->mappings->get_fieldmaps() ) ) {
583
			$url     = esc_url( get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=fieldmaps' ) );
0 ignored issues
show
Bug introduced by
The function get_admin_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

583
			$url     = esc_url( /** @scrutinizer ignore-call */ get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=fieldmaps' ) );
Loading history...
584
			$anchor  = esc_html__( 'Fieldmaps tab', 'object-sync-for-salesforce' );
585
			$message = sprintf( 'No fieldmaps exist yet. Use the <a href="%s">%s</a> to map WordPress and Salesforce objects to each other.', $url, $anchor );
586
			require plugin_dir_path( $this->file ) . '/templates/admin/error.php';
587
		}
588
589
		try {
590
			switch ( $tab ) {
591
				case 'authorize':
592
					if ( isset( $get_data['code'] ) ) {
593
						// this string is an oauth token.
594
						$data          = esc_html( wp_unslash( $get_data['code'] ) );
0 ignored issues
show
Bug introduced by
The function wp_unslash was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

594
						$data          = esc_html( /** @scrutinizer ignore-call */ wp_unslash( $get_data['code'] ) );
Loading history...
595
						$is_authorized = $this->salesforce['sfapi']->request_token( $data );
596
						?>
597
						<script>window.location = '<?php echo esc_url_raw( $callback_url ); ?>'</script>
0 ignored issues
show
Bug introduced by
The function esc_url_raw was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

597
						<script>window.location = '<?php echo /** @scrutinizer ignore-call */ esc_url_raw( $callback_url ); ?>'</script>
Loading history...
598
						<?php
599
					} elseif ( true === $this->salesforce['is_authorized'] ) {
600
							require_once plugin_dir_path( $this->file ) . '/templates/admin/authorized.php';
601
							$this->status( $this->salesforce['sfapi'] );
602
					} elseif ( true === is_object( $this->salesforce['sfapi'] ) && isset( $consumer_key ) && isset( $consumer_secret ) ) {
603
						?>
604
						<p><a class="button button-primary" href="<?php echo esc_url( $this->salesforce['sfapi']->get_authorization_code() ); ?>"><?php echo esc_html__( 'Connect to Salesforce', 'object-sync-for-salesforce' ); ?></a></p>
605
						<?php
606
					} else {
607
						$url    = esc_url( get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=settings' ) );
608
						$anchor = esc_html__( 'Settings', 'object-sync-for-salesforce' );
609
						// translators: placeholders are for the settings tab link: 1) the url, and 2) the anchor text.
610
						$message = sprintf( esc_html__( 'Salesforce needs to be authorized to connect to this website but the credentials are missing. Use the <a href="%1$s">%2$s</a> tab to add them.', 'object-sync-for-salesforce' ), $url, $anchor );
611
						require_once plugin_dir_path( $this->file ) . '/templates/admin/error.php';
612
					}
613
					break;
614
				case 'fieldmaps':
615
					if ( isset( $get_data['method'] ) ) {
616
617
						$method      = sanitize_key( $get_data['method'] );
618
						$error_url   = get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=fieldmaps&method=' . $method );
619
						$success_url = get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=fieldmaps' );
620
621
						$disable_mapped_fields = get_option( $this->option_prefix . 'disable_mapped_fields', false );
622
						$disable_mapped_fields = filter_var( $disable_mapped_fields, FILTER_VALIDATE_BOOLEAN );
623
						$fieldmap_class        = 'fieldmap';
624
						if ( true === $disable_mapped_fields ) {
625
							$fieldmap_class .= ' fieldmap-disable-mapped-fields';
626
						}
627
628
						if ( isset( $get_data['transient'] ) ) {
629
							$transient = sanitize_key( $get_data['transient'] );
630
							$posted    = $this->sfwp_transients->get( $transient );
631
						}
632
633
						if ( isset( $posted ) && is_array( $posted ) ) {
634
							$map = $posted;
635
						} elseif ( 'edit' === $method || 'clone' === $method || 'delete' === $method ) {
636
							$map = $this->mappings->get_fieldmaps( isset( $get_data['id'] ) ? sanitize_key( $get_data['id'] ) : '' );
637
						}
638
639
						if ( 'add' === $method || ( isset( $map ) && is_array( $map ) && isset( $map['id'] ) ) ) {
640
							if ( isset( $map ) && is_array( $map ) && isset( $map['id'] ) ) {
641
								$label                               = $map['label'];
642
								$fieldmap_status                     = $map['fieldmap_status'];
643
								$salesforce_object                   = $map['salesforce_object'];
644
								$salesforce_record_types_allowed     = maybe_unserialize( $map['salesforce_record_types_allowed'] );
0 ignored issues
show
Bug introduced by
The function maybe_unserialize was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

644
								$salesforce_record_types_allowed     = /** @scrutinizer ignore-call */ maybe_unserialize( $map['salesforce_record_types_allowed'] );
Loading history...
645
								$salesforce_record_type_default      = $map['salesforce_record_type_default'];
646
								$wordpress_object                    = $map['wordpress_object'];
647
								$pull_trigger_field                  = $map['pull_trigger_field'];
648
								$fieldmap_fields                     = $map['fields'];
649
								$sync_triggers                       = $map['sync_triggers'];
650
								$always_delete_object_maps_on_delete = $map['always_delete_object_maps_on_delete'];
651
								$push_async                          = $map['push_async'];
652
								$push_drafts                         = $map['push_drafts'];
653
								$pull_to_drafts                      = $map['pull_to_drafts'];
654
								$weight                              = $map['weight'];
655
							}
656
							if ( 'add' === $method || 'edit' === $method || 'clone' === $method ) {
657
								require_once plugin_dir_path( $this->file ) . '/templates/admin/fieldmaps-add-edit-clone.php';
658
							} elseif ( 'delete' === $method ) {
659
								require_once plugin_dir_path( $this->file ) . '/templates/admin/fieldmaps-delete.php';
660
							}
661
						} else {
662
							$no_fieldmap_url = get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=fieldmaps&missing_fieldmap=true' );
663
							wp_safe_redirect( $no_fieldmap_url );
0 ignored issues
show
Bug introduced by
The function wp_safe_redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

663
							/** @scrutinizer ignore-call */ 
664
       wp_safe_redirect( $no_fieldmap_url );
Loading history...
664
							exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
665
						}
666
					} else {
667
						$fieldmaps = $this->mappings->get_fieldmaps();
668
						require_once plugin_dir_path( $this->file ) . '/templates/admin/fieldmaps-list.php';
669
					} // End if statement.
670
					break;
671
				case 'logout':
672
					$this->logout();
673
					break;
674
				case 'clear_cache':
675
					$this->clear_cache();
676
					break;
677
				case 'clear_schedule':
678
					if ( isset( $get_data['schedule_name'] ) ) {
679
						$schedule_name = sanitize_key( $get_data['schedule_name'] );
680
					}
681
					$this->clear_schedule( $schedule_name );
682
					break;
683
				case 'settings':
684
					require_once plugin_dir_path( $this->file ) . '/templates/admin/settings.php';
685
					break;
686
				case 'mapping_errors':
687
					if ( isset( $get_data['method'] ) ) {
688
689
						$method      = sanitize_key( $get_data['method'] );
690
						$error_url   = get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=mapping_errors&method=' . $method );
691
						$success_url = get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=mapping_errors' );
692
693
						if ( isset( $get_data['map_transient'] ) ) {
694
							$transient = sanitize_key( $get_data['map_transient'] );
695
							$posted    = $this->sfwp_transients->get( $transient );
696
						}
697
698
						if ( isset( $posted ) && is_array( $posted ) ) {
699
							$map_row = $posted;
700
						} elseif ( 'edit' === $method || 'delete' === $method ) {
701
							$map_row = $this->mappings->get_failed_object_map( isset( $get_data['id'] ) ? sanitize_key( $get_data['id'] ) : '' );
702
						}
703
704
						if ( isset( $map_row ) && is_array( $map_row ) ) {
705
							$salesforce_id    = $map_row['salesforce_id'];
706
							$wordpress_id     = $map_row['wordpress_id'];
707
							$wordpress_object = $map_row['wordpress_object'];
708
						}
709
710
						if ( 'edit' === $method ) {
711
							require_once plugin_dir_path( $this->file ) . '/templates/admin/mapping-errors-edit.php';
712
						} elseif ( 'delete' === $method ) {
713
							require_once plugin_dir_path( $this->file ) . '/templates/admin/mapping-errors-delete.php';
714
						}
715
					} else {
716
717
						if ( isset( $get_data['mapping_error_transient'] ) ) {
718
							$transient = sanitize_key( $get_data['mapping_error_transient'] );
719
							$posted    = $this->sfwp_transients->get( $transient );
720
						}
721
722
						$ids_string = '';
723
						$ids        = array();
724
						if ( isset( $posted['delete'] ) ) {
725
							$ids_string = maybe_serialize( $posted['delete'] );
0 ignored issues
show
Bug introduced by
The function maybe_serialize was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

725
							$ids_string = /** @scrutinizer ignore-call */ maybe_serialize( $posted['delete'] );
Loading history...
726
							$ids        = $posted['delete'];
727
						}
728
729
						$error_url   = get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=mapping_errors&ids=' . $ids_string );
730
						$success_url = get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=mapping_errors' );
731
						require_once plugin_dir_path( $this->file ) . '/templates/admin/mapping-errors.php';
732
					}
733
					break;
734
				case 'import-export':
735
					require_once plugin_dir_path( $this->file ) . '/templates/admin/import-export.php';
736
					break;
737
				default:
738
					$include_settings = apply_filters( $this->option_prefix . 'settings_tab_include_settings', true, $tab );
739
					$content_before   = apply_filters( $this->option_prefix . 'settings_tab_content_before', null, $tab );
740
					$content_after    = apply_filters( $this->option_prefix . 'settings_tab_content_after', null, $tab );
741
					if ( null !== $content_before ) {
742
						echo esc_html( $content_before );
743
					}
744
					if ( true === $include_settings ) {
745
						require_once plugin_dir_path( $this->file ) . '/templates/admin/settings.php';
746
					}
747
					if ( null !== $content_after ) {
748
						echo esc_html( $content_after );
749
					}
750
					break;
751
			} // End switch statement.
752
		} catch ( Object_Sync_Sf_Exception $ex ) {
753
			echo sprintf(
754
				'<p>Error <strong>%1$s</strong>: %2$s</p>',
755
				absint( $ex->getCode() ),
0 ignored issues
show
Bug introduced by
The function absint was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

755
				/** @scrutinizer ignore-call */ 
756
    absint( $ex->getCode() ),
Loading history...
756
				esc_html( $ex->getMessage() )
757
			);
758
		} // End try for menu/page setup.
759
		echo '</div>';
760
	}
761
762
	/**
763
	 * Create default WordPress admin settings form. This runs the Settings page.
764
	 */
765
	public function salesforce_settings_forms() {
766
		$get_data = filter_input_array( INPUT_GET, FILTER_SANITIZE_SPECIAL_CHARS );
767
		$page     = isset( $get_data['tab'] ) ? sanitize_key( $get_data['tab'] ) : 'settings';
0 ignored issues
show
Bug introduced by
The function sanitize_key was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

767
		$page     = isset( $get_data['tab'] ) ? /** @scrutinizer ignore-call */ sanitize_key( $get_data['tab'] ) : 'settings';
Loading history...
768
		$section  = isset( $get_data['tab'] ) ? sanitize_key( $get_data['tab'] ) : 'settings';
769
770
		$input_callback_default   = array( $this, 'display_input_field' );
771
		$input_checkboxes_default = array( $this, 'display_checkboxes' );
772
		$input_select_default     = array( $this, 'display_select' );
773
		$link_default             = array( $this, 'display_link' );
774
775
		$all_field_callbacks = array(
776
			'text'       => $input_callback_default,
777
			'checkboxes' => $input_checkboxes_default,
778
			'select'     => $input_select_default,
779
			'link'       => $link_default,
780
		);
781
782
		$this->fields_settings( 'settings', 'settings', $all_field_callbacks );
783
		$this->fields_fieldmaps( 'fieldmaps', 'objects' );
784
		$this->fields_scheduling( 'schedule', 'schedule', $all_field_callbacks );
785
		$this->fields_log_settings( 'log_settings', 'log_settings', $all_field_callbacks );
786
		$this->fields_errors( 'mapping_errors', 'mapping_errors', $all_field_callbacks );
787
	}
788
789
	/**
790
	 * Fields for the Settings tab
791
	 * This runs add_settings_section once, as well as add_settings_field and register_setting methods for each option
792
	 *
793
	 * @param string $page what page we're on.
794
	 * @param string $section what section of the page.
795
	 * @param array  $callbacks method to call.
796
	 */
797
	private function fields_settings( $page, $section, $callbacks ) {
798
		add_settings_section( $page, ucwords( $page ), null, $page );
0 ignored issues
show
Bug introduced by
The function add_settings_section was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

798
		/** @scrutinizer ignore-call */ 
799
  add_settings_section( $page, ucwords( $page ), null, $page );
Loading history...
799
		$salesforce_settings = array(
800
			'consumer_key'                   => array(
801
				'title'    => __( 'Consumer Key', 'object-sync-for-salesforce' ),
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

801
				'title'    => /** @scrutinizer ignore-call */ __( 'Consumer Key', 'object-sync-for-salesforce' ),
Loading history...
802
				'callback' => $callbacks['text'],
803
				'page'     => $page,
804
				'section'  => $section,
805
				'args'     => array(
806
					'type'     => 'text',
807
					'validate' => 'sanitize_validate_text',
808
					'desc'     => '',
809
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_CONSUMER_KEY',
810
				),
811
812
			),
813
			'consumer_secret'                => array(
814
				'title'    => __( 'Consumer Secret', 'object-sync-for-salesforce' ),
815
				'callback' => $callbacks['text'],
816
				'page'     => $page,
817
				'section'  => $section,
818
				'args'     => array(
819
					'type'     => 'text',
820
					'validate' => 'sanitize_validate_text',
821
					'desc'     => '',
822
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_CONSUMER_SECRET',
823
				),
824
			),
825
			'callback_url'                   => array(
826
				'title'    => __( 'Callback URL', 'object-sync-for-salesforce' ),
827
				'callback' => $callbacks['text'],
828
				'page'     => $page,
829
				'section'  => $section,
830
				'args'     => array(
831
					'type'     => 'url',
832
					'validate' => 'sanitize_validate_text',
833
					'desc'     => sprintf(
834
						// translators: %1$s is the admin URL for the Authorize tab.
835
						__( 'In most cases, you will want to use %1$s for this value.', 'object-sync-for-salesforce' ),
836
						get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=authorize' )
0 ignored issues
show
Bug introduced by
The function get_admin_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

836
						/** @scrutinizer ignore-call */ 
837
      get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=authorize' )
Loading history...
837
					),
838
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_CALLBACK_URL',
839
				),
840
			),
841
			'login_base_url'                 => array(
842
				'title'    => __( 'Login Base URL', 'object-sync-for-salesforce' ),
843
				'callback' => $callbacks['text'],
844
				'page'     => $page,
845
				'section'  => $section,
846
				'args'     => array(
847
					'type'     => 'url',
848
					'validate' => 'sanitize_validate_text',
849
					'desc'     => sprintf(
850
						// translators: 1) production salesforce login, 2) sandbox salesforce login.
851
						__( 'For most Salesforce setups, you should use %1$s for production and %2$s for sandbox. If you try to use an instance name as the URL, you may encounter Salesforce errors.', 'object-sync-for-salesforce' ),
852
						esc_url( 'https://login.salesforce.com' ),
0 ignored issues
show
Bug introduced by
The function esc_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

852
						/** @scrutinizer ignore-call */ 
853
      esc_url( 'https://login.salesforce.com' ),
Loading history...
853
						esc_url( 'https://test.salesforce.com' )
854
					),
855
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_LOGIN_BASE_URL',
856
				),
857
			),
858
			'authorize_url_path'             => array(
859
				'title'    => __( 'Authorize URL Path', 'object-sync-for-salesforce' ),
860
				'callback' => $callbacks['text'],
861
				'page'     => $page,
862
				'section'  => $section,
863
				'args'     => array(
864
					'type'     => 'text',
865
					'validate' => 'sanitize_validate_text',
866
					'desc'     => __( 'For most Salesforce installs, this should not be changed.', 'object-sync-for-salesforce' ),
867
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_AUTHORIZE_URL_PATH',
868
					'default'  => $this->default_authorize_url_path,
869
				),
870
			),
871
			'token_url_path'                 => array(
872
				'title'    => __( 'Token URL Path', 'object-sync-for-salesforce' ),
873
				'callback' => $callbacks['text'],
874
				'page'     => $page,
875
				'section'  => $section,
876
				'args'     => array(
877
					'type'     => 'text',
878
					'validate' => 'sanitize_validate_text',
879
					'desc'     => __( 'For most Salesforce installs, this should not be changed.', 'object-sync-for-salesforce' ),
880
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_TOKEN_URL_PATH',
881
					'default'  => $this->default_token_url_path,
882
				),
883
			),
884
			'object_filters'                 => array(
885
				'title'    => __( 'Limit Salesforce Objects', 'object-sync-for-salesforce' ),
886
				'callback' => $callbacks['checkboxes'],
887
				'page'     => $page,
888
				'section'  => $section,
889
				'args'     => array(
890
					'type'     => 'checkboxes',
891
					'validate' => 'sanitize_validate_text',
892
					'desc'     => __( 'Allows you to limit which Salesforce objects can be mapped', 'object-sync-for-salesforce' ),
893
					'items'    => array(
894
						'triggerable' => array(
895
							'text'    => __( 'Only Triggerable objects', 'object-sync-for-salesforce' ),
896
							'id'      => 'triggerable',
897
							'desc'    => '',
898
							'default' => $this->default_triggerable,
899
						),
900
						'updateable'  => array(
901
							'text'    => __( 'Only Updateable objects', 'object-sync-for-salesforce' ),
902
							'id'      => 'updateable',
903
							'desc'    => '',
904
							'default' => $this->default_updateable,
905
						),
906
					),
907
				),
908
			),
909
			'salesforce_field_display_value' => array(
910
				'title'    => __( 'Salesforce Field Display Value', 'object-sync-for-salesforce' ),
911
				'callback' => $callbacks['select'],
912
				'page'     => $page,
913
				'section'  => $section,
914
				'args'     => array(
915
					'type'     => 'select',
916
					'validate' => 'sanitize_validate_text',
917
					'desc'     => __( 'When choosing Salesforce fields to map, this value determines how the dropdown will identify Salesforce fields.', 'object-sync-for-salesforce' ),
918
					'constant' => '',
919
					'items'    => array(
920
						'field_label' => array(
921
							'text'  => __( 'Field Label', 'object-sync-for-salesforce' ),
922
							'value' => 'field_label',
923
						),
924
						'api_name'    => array(
925
							'text'  => __( 'API Name', 'object-sync-for-salesforce' ),
926
							'value' => 'api_name',
927
						),
928
					),
929
				),
930
			),
931
			'disable_mapped_fields'          => array(
932
				'title'    => __( 'Prevent Duplicate Field Mapping?', 'object-sync-for-salesforce' ),
933
				'callback' => $callbacks['text'],
934
				'page'     => $page,
935
				'section'  => $section,
936
				'args'     => array(
937
					'type'     => 'checkbox',
938
					'validate' => 'sanitize_text_field',
939
					'desc'     => __( 'If checked, any WordPress or Salesforce field that has already been mapped, or that is selected while creating or editing a fieldmap, cannot be mapped again.', 'object-sync-for-salesforce' ),
940
					'constant' => '',
941
				),
942
			),
943
			'pull_query_limit'               => array(
944
				'title'    => __( 'Pull Query Record Limit', 'object-sync-for-salesforce' ),
945
				'callback' => $callbacks['text'],
946
				'page'     => $page,
947
				'section'  => $section,
948
				'args'     => array(
949
					'type'     => 'number',
950
					'validate' => 'absint',
951
					'desc'     => __( 'Limit the number of records that can be pulled from Salesforce in a single query.', 'object-sync-for-salesforce' ),
952
					'constant' => '',
953
					'default'  => $this->default_pull_limit,
954
				),
955
			),
956
			'pull_throttle'                  => array(
957
				'title'    => __( 'Pull Throttle (In Seconds)', 'object-sync-for-salesforce' ),
958
				'callback' => $callbacks['text'],
959
				'page'     => $page,
960
				'section'  => $section,
961
				'args'     => array(
962
					'type'     => 'number',
963
					'validate' => 'sanitize_validate_text',
964
					'desc'     => __( 'Number of seconds to wait between repeated salesforce pulls. Prevents the webserver from becoming overloaded in case of too many cron runs, or webhook usage.', 'object-sync-for-salesforce' ),
965
					'constant' => '',
966
					'default'  => $this->default_pull_throttle,
967
				),
968
			),
969
		);
970
971
		// only show soap settings if the soap extension is enabled on the server.
972
		if ( true === $this->salesforce['soap_available'] ) {
973
			$salesforce_settings['use_soap']       = array(
974
				'title'    => __( 'Enable the Salesforce SOAP API?', 'object-sync-for-salesforce' ),
975
				'callback' => $callbacks['text'],
976
				'page'     => $page,
977
				'section'  => $section,
978
				'class'    => 'object-sync-for-salesforce-enable-soap',
979
				'args'     => array(
980
					'type'     => 'checkbox',
981
					'validate' => 'sanitize_text_field',
982
					'desc'     => __( 'Check this to enable the SOAP API and use it instead of the REST API when the plugin supports it. https://developer.salesforce.com/blogs/tech-pubs/2011/10/salesforce-apis-what-they-are-when-to-use-them.html to compare the two. Note: if you need to detect Salesforce merges in this plugin, you will need to enable SOAP.', 'object-sync-for-salesforce' ),
983
					'constant' => '',
984
				),
985
			);
986
			$salesforce_settings['soap_wsdl_path'] = array(
987
				'title'    => __( 'Path to SOAP WSDL File', 'object-sync-for-salesforce' ),
988
				'callback' => $callbacks['text'],
989
				'page'     => $page,
990
				'section'  => $section,
991
				'class'    => 'object-sync-for-salesforce-soap-wsdl-path',
992
				'args'     => array(
993
					'type'     => 'text',
994
					'validate' => 'sanitize_text_field',
995
					'desc'     => __( 'Optionally add a path to your own WSDL file. If you do not, the plugin will use the default partner.wsdl.xml from the Force.com toolkit.', 'object-sync-for-salesforce' ),
996
					'constant' => '',
997
				),
998
			);
999
		}
1000
1001
		$salesforce_settings['debug_mode']               = array(
1002
			'title'    => __( 'Debug Mode?', 'object-sync-for-salesforce' ),
1003
			'callback' => $callbacks['text'],
1004
			'page'     => $page,
1005
			'section'  => $section,
1006
			'args'     => array(
1007
				'type'     => 'checkbox',
1008
				'validate' => 'sanitize_text_field',
1009
				'desc'     => __( 'Debug mode activates logging for plugin events like Salesforce API requests and WordPress data operations. This can create a lot of log entries; it is not recommended to use it long-term in a production environment.', 'object-sync-for-salesforce' ),
1010
				'constant' => '',
1011
			),
1012
		);
1013
		$salesforce_settings['delete_data_on_uninstall'] = array(
1014
			'title'    => __( 'Delete Plugin Data on Uninstall?', 'object-sync-for-salesforce' ),
1015
			'callback' => $callbacks['text'],
1016
			'page'     => $page,
1017
			'section'  => $section,
1018
			'args'     => array(
1019
				'type'     => 'checkbox',
1020
				'validate' => 'sanitize_text_field',
1021
				'desc'     => __( 'If checked, the plugin will delete the tables and other data it creates when you uninstall it. Unchecking this field can be useful if you need to reactivate the plugin for any reason without losing data.', 'object-sync-for-salesforce' ),
1022
				'constant' => '',
1023
			),
1024
		);
1025
1026
		foreach ( $salesforce_settings as $key => $attributes ) {
1027
			$id       = $this->option_prefix . $key;
1028
			$name     = $this->option_prefix . $key;
1029
			$title    = $attributes['title'];
1030
			$callback = $attributes['callback'];
1031
			$validate = $attributes['args']['validate'];
1032
			$page     = $attributes['page'];
1033
			$section  = $attributes['section'];
1034
			$class    = isset( $attributes['class'] ) ? $attributes['class'] : '';
1035
			$args     = array_merge(
1036
				$attributes['args'],
1037
				array(
1038
					'title'     => $title,
1039
					'id'        => $id,
1040
					'label_for' => $id,
1041
					'name'      => $name,
1042
					'class'     => $class,
1043
				)
1044
			);
1045
1046
			// if there is a constant and it is defined, don't run a validate function.
1047
			if ( isset( $attributes['args']['constant'] ) && defined( $attributes['args']['constant'] ) ) {
1048
				$validate = '';
1049
			}
1050
1051
			add_settings_field( $id, $title, $callback, $page, $section, $args );
0 ignored issues
show
Bug introduced by
The function add_settings_field was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1051
			/** @scrutinizer ignore-call */ 
1052
   add_settings_field( $id, $title, $callback, $page, $section, $args );
Loading history...
1052
			register_setting( $page, $id, array( $this, $validate ) );
0 ignored issues
show
Bug introduced by
The function register_setting was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1052
			/** @scrutinizer ignore-call */ 
1053
   register_setting( $page, $id, array( $this, $validate ) );
Loading history...
1053
		}
1054
	}
1055
1056
	/**
1057
	 * Fields for the Fieldmaps tab
1058
	 * This runs add_settings_section once, as well as add_settings_field and register_setting methods for each option
1059
	 *
1060
	 * @param string $page what page we're on.
1061
	 * @param string $section what section of the page.
1062
	 * @param string $input_callback method to call.
1063
	 */
1064
	private function fields_fieldmaps( $page, $section, $input_callback = '' ) {
1065
		add_settings_section( $page, ucwords( $page ), null, $page );
0 ignored issues
show
Bug introduced by
The function add_settings_section was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1065
		/** @scrutinizer ignore-call */ 
1066
  add_settings_section( $page, ucwords( $page ), null, $page );
Loading history...
1066
	}
1067
1068
	/**
1069
	 * Fields for the Scheduling tab
1070
	 * This runs add_settings_section once, as well as add_settings_field and register_setting methods for each option
1071
	 *
1072
	 * @param string $page what page we're on.
1073
	 * @param string $section what section of the page.
1074
	 * @param array  $callbacks method to call.
1075
	 */
1076
	private function fields_scheduling( $page, $section, $callbacks ) {
1077
1078
		add_settings_section( 'batch', __( 'Batch Settings', 'object-sync-for-salesforce' ), null, $page );
0 ignored issues
show
Bug introduced by
The function add_settings_section was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1078
		/** @scrutinizer ignore-call */ 
1079
  add_settings_section( 'batch', __( 'Batch Settings', 'object-sync-for-salesforce' ), null, $page );
Loading history...
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1078
		add_settings_section( 'batch', /** @scrutinizer ignore-call */ __( 'Batch Settings', 'object-sync-for-salesforce' ), null, $page );
Loading history...
1079
		$section           = 'batch';
1080
		$schedule_settings = array(
1081
			'action_scheduler_batch_size'         => array(
1082
				'title'    => __( 'Batch Size', 'object-sync-for-salesforce' ),
1083
				'callback' => $callbacks['text'],
1084
				'page'     => $page,
1085
				'section'  => $section,
1086
				'args'     => array(
1087
					'type'     => 'number',
1088
					'validate' => 'absint',
1089
					'default'  => 5,
1090
					'desc'     => __( 'Set how many actions (checking for data changes, syncing a record, etc. all count as individual actions) can be run in a batch. Start with a low number here, like 5, if you are unsure.', 'object-sync-for-salesforce' ),
1091
					'constant' => '',
1092
				),
1093
1094
			),
1095
			'action_scheduler_concurrent_batches' => array(
1096
				'title'    => __( 'Concurrent Batches', 'object-sync-for-salesforce' ),
1097
				'callback' => $callbacks['text'],
1098
				'page'     => $page,
1099
				'section'  => $section,
1100
				'args'     => array(
1101
					'type'     => 'number',
1102
					'validate' => 'absint',
1103
					'default'  => 3,
1104
					'desc'     => __( 'Set how many batches of actions can be run at once. Start with a low number here, like 3, if you are unsure.', 'object-sync-for-salesforce' ),
1105
					'constant' => '',
1106
				),
1107
			),
1108
		);
1109
1110
		foreach ( $this->schedulable_classes as $key => $value ) {
1111
			add_settings_section( $key, $value['label'], null, $page );
1112
			if ( isset( $value['initializer'] ) ) {
1113
				$schedule_settings[ $key . '_schedule_number' ] = array(
1114
					'title'    => __( 'Run Schedule Every', 'object-sync-for-salesforce' ),
1115
					'callback' => $callbacks['text'],
1116
					'page'     => $page,
1117
					'section'  => $key,
1118
					'args'     => array(
1119
						'type'     => 'number',
1120
						'validate' => 'absint',
1121
						'desc'     => '',
1122
						'constant' => '',
1123
					),
1124
				);
1125
				$schedule_settings[ $key . '_schedule_unit' ]   = array(
1126
					'title'    => __( 'Time Unit', 'object-sync-for-salesforce' ),
1127
					'callback' => $callbacks['select'],
1128
					'page'     => $page,
1129
					'section'  => $key,
1130
					'args'     => array(
1131
						'type'     => 'select',
1132
						'validate' => 'sanitize_validate_text',
1133
						'desc'     => '',
1134
						'items'    => array(
1135
							'minutes' => array(
1136
								'text'  => __( 'Minutes', 'object-sync-for-salesforce' ),
1137
								'value' => 'minutes',
1138
							),
1139
							'hours'   => array(
1140
								'text'  => __( 'Hours', 'object-sync-for-salesforce' ),
1141
								'value' => 'hours',
1142
							),
1143
							'days'    => array(
1144
								'text'  => __( 'Days', 'object-sync-for-salesforce' ),
1145
								'value' => 'days',
1146
							),
1147
						),
1148
					),
1149
				);
1150
			}
1151
			$schedule_settings[ $key . '_clear_button' ] = array(
1152
				// translators: $this->get_schedule_count is an integer showing how many items are in the current queue.
1153
				'title'    => sprintf( 'This Queue Has ' . _n( '%s Item', '%s Items', $this->get_schedule_count( $key ), 'object-sync-for-salesforce' ), $this->get_schedule_count( $key ) ),
0 ignored issues
show
Bug introduced by
The function _n was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1153
				'title'    => sprintf( 'This Queue Has ' . /** @scrutinizer ignore-call */ _n( '%s Item', '%s Items', $this->get_schedule_count( $key ), 'object-sync-for-salesforce' ), $this->get_schedule_count( $key ) ),
Loading history...
1154
				'callback' => $callbacks['link'],
1155
				'page'     => $page,
1156
				'section'  => $key,
1157
				'args'     => array(
1158
					'label'      => __( 'Clear this queue', 'object-sync-for-salesforce' ),
1159
					'desc'       => '',
1160
					'url'        => esc_url( '?page=' . $this->admin_settings_url_param . '&amp;tab=clear_schedule&amp;schedule_name=' . $key ),
0 ignored issues
show
Bug introduced by
The function esc_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1160
					'url'        => /** @scrutinizer ignore-call */ esc_url( '?page=' . $this->admin_settings_url_param . '&amp;tab=clear_schedule&amp;schedule_name=' . $key ),
Loading history...
1161
					'link_class' => 'button button-secondary',
1162
				),
1163
			);
1164
			foreach ( $schedule_settings as $key => $attributes ) {
1165
				$id       = $this->option_prefix . $key;
1166
				$name     = $this->option_prefix . $key;
1167
				$title    = $attributes['title'];
1168
				$callback = $attributes['callback'];
1169
				$page     = $attributes['page'];
1170
				$section  = $attributes['section'];
1171
				$args     = array_merge(
1172
					$attributes['args'],
1173
					array(
1174
						'title'     => $title,
1175
						'id'        => $id,
1176
						'label_for' => $id,
1177
						'name'      => $name,
1178
					)
1179
				);
1180
				add_settings_field( $id, $title, $callback, $page, $section, $args );
0 ignored issues
show
Bug introduced by
The function add_settings_field was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1180
				/** @scrutinizer ignore-call */ 
1181
    add_settings_field( $id, $title, $callback, $page, $section, $args );
Loading history...
1181
				register_setting( $page, $id );
0 ignored issues
show
Bug introduced by
The function register_setting was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1181
				/** @scrutinizer ignore-call */ 
1182
    register_setting( $page, $id );
Loading history...
1182
			}
1183
		} // End foreach statement.
1184
	}
1185
1186
	/**
1187
	 * Fields for the Log Settings tab
1188
	 * This runs add_settings_section once, as well as add_settings_field and register_setting methods for each option
1189
	 *
1190
	 * @param string $page what page we're on.
1191
	 * @param string $section what section of the page.
1192
	 * @param array  $callbacks method to call.
1193
	 */
1194
	private function fields_log_settings( $page, $section, $callbacks ) {
1195
		add_settings_section( $page, ucwords( str_replace( '_', ' ', $page ) ), null, $page );
0 ignored issues
show
Bug introduced by
The function add_settings_section was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1195
		/** @scrutinizer ignore-call */ 
1196
  add_settings_section( $page, ucwords( str_replace( '_', ' ', $page ) ), null, $page );
Loading history...
1196
		$log_settings = array(
1197
			'enable_logging'        => array(
1198
				'title'    => __( 'Enable Logging?', 'object-sync-for-salesforce' ),
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1198
				'title'    => /** @scrutinizer ignore-call */ __( 'Enable Logging?', 'object-sync-for-salesforce' ),
Loading history...
1199
				'callback' => $callbacks['text'],
1200
				'page'     => $page,
1201
				'section'  => $section,
1202
				'args'     => array(
1203
					'type'     => 'checkbox',
1204
					'validate' => 'absint',
1205
					'desc'     => __( 'This determines whether to create plugin log events in standard operation. If Debug Mode is enabled in the plugin settings, logging will occur regardless of this setting.', 'object-sync-for-salesforce' ),
1206
					'constant' => '',
1207
				),
1208
			),
1209
			'statuses_to_log'       => array(
1210
				'title'    => __( 'Statuses to Log', 'object-sync-for-salesforce' ),
1211
				'callback' => $callbacks['checkboxes'],
1212
				'page'     => $page,
1213
				'section'  => $section,
1214
				'args'     => array(
1215
					'type'     => 'checkboxes',
1216
					'validate' => 'sanitize_validate_text',
1217
					'desc'     => '',
1218
					'items'    => array(
1219
						'error'   => array(
1220
							'text' => __( 'Error', 'object-sync-for-salesforce' ),
1221
							'id'   => 'error',
1222
							'desc' => '',
1223
						),
1224
						'success' => array(
1225
							'text' => __( 'Success', 'object-sync-for-salesforce' ),
1226
							'id'   => 'success',
1227
							'desc' => '',
1228
						),
1229
						'notice'  => array(
1230
							'text' => __( 'Notice', 'object-sync-for-salesforce' ),
1231
							'id'   => 'notice',
1232
							'desc' => '',
1233
						),
1234
					),
1235
				),
1236
			),
1237
			'prune_logs'            => array(
1238
				'title'    => __( 'Automatically Delete Old Log Entries?', 'object-sync-for-salesforce' ),
1239
				'callback' => $callbacks['text'],
1240
				'page'     => $page,
1241
				'section'  => $section,
1242
				'args'     => array(
1243
					'type'     => 'checkbox',
1244
					'validate' => 'absint',
1245
					'desc'     => '',
1246
					'constant' => '',
1247
				),
1248
			),
1249
			'logs_how_old'          => array(
1250
				'title'    => __( 'Age to Delete Log Entries', 'object-sync-for-salesforce' ),
1251
				'callback' => $callbacks['text'],
1252
				'page'     => $page,
1253
				'section'  => $section,
1254
				'args'     => array(
1255
					'type'     => 'text',
1256
					'validate' => 'sanitize_validate_text',
1257
					'desc'     => __( 'If automatic deleting is enabled, it will affect logs this old.', 'object-sync-for-salesforce' ),
1258
					'default'  => '2 weeks',
1259
					'constant' => '',
1260
				),
1261
			),
1262
			'logs_how_often_number' => array(
1263
				'title'    => __( 'Check For Old Logs Every', 'object-sync-for-salesforce' ),
1264
				'callback' => $callbacks['text'],
1265
				'page'     => $page,
1266
				'section'  => $section,
1267
				'args'     => array(
1268
					'type'     => 'number',
1269
					'validate' => 'absint',
1270
					'desc'     => '',
1271
					'default'  => '1',
1272
					'constant' => '',
1273
				),
1274
			),
1275
			'logs_how_often_unit'   => array(
1276
				'title'    => __( 'Time Unit', 'object-sync-for-salesforce' ),
1277
				'callback' => $callbacks['select'],
1278
				'page'     => $page,
1279
				'section'  => $section,
1280
				'args'     => array(
1281
					'type'     => 'select',
1282
					'validate' => 'sanitize_validate_text',
1283
					'desc'     => __( 'These two fields are how often the site will check for logs to delete.', 'object-sync-for-salesforce' ),
1284
					'items'    => array(
1285
						'minutes' => array(
1286
							'text'  => __( 'Minutes', 'object-sync-for-salesforce' ),
1287
							'value' => 'minutes',
1288
						),
1289
						'hours'   => array(
1290
							'text'  => __( 'Hours', 'object-sync-for-salesforce' ),
1291
							'value' => 'hours',
1292
						),
1293
						'days'    => array(
1294
							'text'  => __( 'Days', 'object-sync-for-salesforce' ),
1295
							'value' => 'days',
1296
						),
1297
					),
1298
				),
1299
			),
1300
			'logs_how_many_number'  => array(
1301
				'title'    => __( 'Clear This Many Log Entries', 'object-sync-for-salesforce' ),
1302
				'callback' => $callbacks['text'],
1303
				'page'     => $page,
1304
				'section'  => $section,
1305
				'args'     => array(
1306
					'type'     => 'number',
1307
					'validate' => 'absint',
1308
					'desc'     => __( 'This number is how many log entries the plugin will try to clear at a time. If you do not enter a number, the default is 100.', 'object-sync-for-salesforce' ),
1309
					'default'  => '100',
1310
					'constant' => '',
1311
				),
1312
			),
1313
			'triggers_to_log'       => array(
1314
				'title'    => __( 'Triggers to Log', 'object-sync-for-salesforce' ),
1315
				'callback' => $callbacks['checkboxes'],
1316
				'page'     => $page,
1317
				'section'  => $section,
1318
				'args'     => array(
1319
					'type'     => 'checkboxes',
1320
					'validate' => 'sanitize_validate_text',
1321
					'desc'     => __( 'These are the triggers to log. When the plugin is in debug mode (see the settings tab), all triggers will be considered to be triggers to log, even if they are not checked here.', 'object-sync-for-salesforce' ),
1322
					'items'    => array(
1323
						$this->mappings->sync_wordpress_create => array(
1324
							'text' => __( 'WordPress Create', 'object-sync-for-salesforce' ),
1325
							'id'   => 'wordpress_create',
1326
							'desc' => '',
1327
						),
1328
						$this->mappings->sync_wordpress_update => array(
1329
							'text' => __( 'WordPress Update', 'object-sync-for-salesforce' ),
1330
							'id'   => 'wordpress_update',
1331
							'desc' => '',
1332
						),
1333
						$this->mappings->sync_wordpress_delete => array(
1334
							'text' => __( 'WordPress Delete', 'object-sync-for-salesforce' ),
1335
							'id'   => 'wordpress_delete',
1336
							'desc' => '',
1337
						),
1338
						$this->mappings->sync_sf_create => array(
1339
							'text' => __( 'Salesforce Create', 'object-sync-for-salesforce' ),
1340
							'id'   => 'sf_create',
1341
							'desc' => '',
1342
						),
1343
						$this->mappings->sync_sf_update => array(
1344
							'text' => __( 'Salesforce Update', 'object-sync-for-salesforce' ),
1345
							'id'   => 'sf_update',
1346
							'desc' => '',
1347
						),
1348
						$this->mappings->sync_sf_delete => array(
1349
							'text' => __( 'Salesforce Delete', 'object-sync-for-salesforce' ),
1350
							'id'   => 'sf_delete',
1351
							'desc' => '',
1352
						),
1353
					),
1354
				),
1355
			),
1356
		);
1357
		foreach ( $log_settings as $key => $attributes ) {
1358
			$id       = $this->option_prefix . $key;
1359
			$name     = $this->option_prefix . $key;
1360
			$title    = $attributes['title'];
1361
			$callback = $attributes['callback'];
1362
			$page     = $attributes['page'];
1363
			$section  = $attributes['section'];
1364
			$args     = array_merge(
1365
				$attributes['args'],
1366
				array(
1367
					'title'     => $title,
1368
					'id'        => $id,
1369
					'label_for' => $id,
1370
					'name'      => $name,
1371
				)
1372
			);
1373
			add_settings_field( $id, $title, $callback, $page, $section, $args );
0 ignored issues
show
Bug introduced by
The function add_settings_field was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1373
			/** @scrutinizer ignore-call */ 
1374
   add_settings_field( $id, $title, $callback, $page, $section, $args );
Loading history...
1374
			register_setting( $page, $id );
0 ignored issues
show
Bug introduced by
The function register_setting was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1374
			/** @scrutinizer ignore-call */ 
1375
   register_setting( $page, $id );
Loading history...
1375
		}
1376
	}
1377
1378
	/**
1379
	 * Fields for the Mapping Errors tab
1380
	 * This runs add_settings_section once, as well as add_settings_field and register_setting methods for each option
1381
	 *
1382
	 * @param string $page what page we're on.
1383
	 * @param string $section what section of the page.
1384
	 * @param array  $callbacks method to call.
1385
	 */
1386
	private function fields_errors( $page, $section, $callbacks ) {
1387
1388
		add_settings_section( $section, __( 'Mapping Error Settings', 'object-sync-for-salesforce' ), null, $page );
0 ignored issues
show
Bug introduced by
The function add_settings_section was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1388
		/** @scrutinizer ignore-call */ 
1389
  add_settings_section( $section, __( 'Mapping Error Settings', 'object-sync-for-salesforce' ), null, $page );
Loading history...
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1388
		add_settings_section( $section, /** @scrutinizer ignore-call */ __( 'Mapping Error Settings', 'object-sync-for-salesforce' ), null, $page );
Loading history...
1389
		$error_settings = array(
1390
			'errors_per_page' => array(
1391
				'title'    => __( 'Errors per page', 'object-sync-for-salesforce' ),
1392
				'callback' => $callbacks['text'],
1393
				'page'     => $page,
1394
				'section'  => $section,
1395
				'args'     => array(
1396
					'type'     => 'number',
1397
					'validate' => 'absint',
1398
					'default'  => 50,
1399
					'desc'     => __( 'Set how many mapping errors to show on a single page.', 'object-sync-for-salesforce' ),
1400
					'constant' => '',
1401
				),
1402
			),
1403
		);
1404
1405
		foreach ( $error_settings as $key => $attributes ) {
1406
			$id       = $this->option_prefix . $key;
1407
			$name     = $this->option_prefix . $key;
1408
			$title    = $attributes['title'];
1409
			$callback = $attributes['callback'];
1410
			$page     = $attributes['page'];
1411
			$section  = $attributes['section'];
1412
			$args     = array_merge(
1413
				$attributes['args'],
1414
				array(
1415
					'title'     => $title,
1416
					'id'        => $id,
1417
					'label_for' => $id,
1418
					'name'      => $name,
1419
				)
1420
			);
1421
			add_settings_field( $id, $title, $callback, $page, $section, $args );
0 ignored issues
show
Bug introduced by
The function add_settings_field was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1421
			/** @scrutinizer ignore-call */ 
1422
   add_settings_field( $id, $title, $callback, $page, $section, $args );
Loading history...
1422
			register_setting( $page, $id );
0 ignored issues
show
Bug introduced by
The function register_setting was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1422
			/** @scrutinizer ignore-call */ 
1423
   register_setting( $page, $id );
Loading history...
1423
		} // End foreach() method.
1424
	}
1425
1426
	/**
1427
	 * Create and return the data for notices.
1428
	 *
1429
	 * @return array $notices is the array of notices.
1430
	 */
1431
	public function notices_data() {
1432
		$notices = array(
1433
			'permission'              => array(
1434
				'condition'   => ( false === $this->check_wordpress_admin_permissions() ),
1435
				'message'     => __( "Your account does not have permission to edit the Object Sync for Salesforce plugin's settings.", 'object-sync-for-salesforce' ),
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1435
				'message'     => /** @scrutinizer ignore-call */ __( "Your account does not have permission to edit the Object Sync for Salesforce plugin's settings.", 'object-sync-for-salesforce' ),
Loading history...
1436
				'type'        => 'error',
1437
				'dismissible' => false,
1438
			),
1439
			'not_secure'              => array(
1440
				'condition'   => ( false === $this->check_wordpress_ssl() && false === $this->check_wordpress_ssl_support() ),
1441
				'message'     => esc_html__( 'At least the admin area of your website must use HTTPS to connect with Salesforce. WordPress reports that your site environment does not, and cannot, use HTTPS. You may need to work with your hosting company to make the switch before you can use this plugin.', 'object-sync-for-salesforce' ),
0 ignored issues
show
Bug introduced by
The function esc_html__ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1441
				'message'     => /** @scrutinizer ignore-call */ esc_html__( 'At least the admin area of your website must use HTTPS to connect with Salesforce. WordPress reports that your site environment does not, and cannot, use HTTPS. You may need to work with your hosting company to make the switch before you can use this plugin.', 'object-sync-for-salesforce' ),
Loading history...
1442
				'type'        => 'error',
1443
				'dismissible' => false,
1444
			),
1445
			'secure_supported'        => array(
1446
				'condition'   => ( false === $this->check_wordpress_ssl() && true === $this->check_wordpress_ssl_support() ),
1447
				'message'     => sprintf(
1448
					// translators: 1) is the site health URL, and 2) is the text for the site health page title.
1449
					__( 'Your website is not currently using HTTPS, but your environment does support it. Visit your website\'s <a href="%1$s">%2$s</a> for more information. If you have just migrated to HTTPS, WordPress may take some time to update this detection.', 'object-sync-for-salesforce' ),
1450
					esc_url( admin_url( 'site-health.php' ) ),
0 ignored issues
show
Bug introduced by
The function esc_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1450
					/** @scrutinizer ignore-call */ 
1451
     esc_url( admin_url( 'site-health.php' ) ),
Loading history...
Bug introduced by
The function admin_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1450
					esc_url( /** @scrutinizer ignore-call */ admin_url( 'site-health.php' ) ),
Loading history...
1451
					esc_html__( 'Site Health screen', 'object-sync-for-salesforce' )
1452
				),
1453
				'type'        => 'error',
1454
				'dismissible' => false,
1455
			),
1456
			'deprecated_api_version'  => array(
1457
				'condition'   => ( isset( $this->login_credentials['using_deprecated_option'] ) && true === $this->login_credentials['using_deprecated_option'] ),
1458
				'message'     => sprintf(
1459
					// translators: 1) is the version number of the Salesforce REST API, 2) is the option key for where the deprecated version is stored, 3) is the prefixed options table name, 4) is the link to delete the option, 5) is the default API version to use, and 6) is the name of the wp-config value.
1460
					esc_html__( 'Object Sync for Salesforce is using version %1$s of the Salesforce REST API, which is configured from a previous version. This value is no longer configurable in the plugin settings, and in version 3.0.0, previously saved values will be removed. You can delete the %2$s field from the %3$s table on your own, use %4$s, set it to %5$s so the plugin can delete it, or wait until that release. If the %6$s value is in your wp-config.php file instead, you should delete it from there as well.', 'object-sync-for-salesforce' ),
1461
					esc_attr( $this->login_credentials['rest_api_version'] ),
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1461
					/** @scrutinizer ignore-call */ 
1462
     esc_attr( $this->login_credentials['rest_api_version'] ),
Loading history...
1462
					'<code>' . esc_attr( $this->option_prefix . 'api_version' ) . '</code>',
1463
					'<code>' . esc_attr( $this->wpdb->prefix . 'options' ) . '</code>',
1464
					'<a href="#" id="salesforce-delete-rest-api-version">this link that will attempt to delete it</a>',
1465
					'<code>' . esc_attr( OBJECT_SYNC_SF_DEFAULT_API_VERSION ) . '</code>',
1466
					'<code>' . esc_attr( 'OBJECT_SYNC_SF_DEFAULT_API_VERSION' ) . '</code>'
1467
				),
1468
				'type'        => 'error',
1469
				'dismissible' => true,
1470
			),
1471
			'fieldmap'                => array(
1472
				'condition'   => isset( $get_data['transient'] ),
1473
				'message'     => esc_html__( 'Errors kept this fieldmap from being saved.', 'object-sync-for-salesforce' ),
1474
				'type'        => 'error',
1475
				'dismissible' => true,
1476
			),
1477
			'fieldmap_missing'        => array(
1478
				'condition'   => isset( $get_data['missing_fieldmap'] ),
1479
				'message'     => __( 'There is no fieldmap with the supplied ID. Instead, the list of all available fieldmaps is displayed.', 'object-sync-for-salesforce' ),
1480
				'type'        => 'error',
1481
				'dismissible' => true,
1482
			),
1483
			'object_map'              => array(
1484
				'condition'   => isset( $get_data['map_transient'] ),
1485
				'message'     => esc_html__( 'Errors kept this object map from being saved.', 'object-sync-for-salesforce' ),
1486
				'type'        => 'error',
1487
				'dismissible' => true,
1488
			),
1489
			'data_saved'              => array(
1490
				'condition'   => isset( $get_data['data_saved'] ) && 'true' === $get_data['data_saved'],
1491
				'message'     => esc_html__( 'This data was successfully saved.', 'object-sync-for-salesforce' ),
1492
				'type'        => 'success',
1493
				'dismissible' => true,
1494
			),
1495
			'data_save_partial'       => array(
1496
				'condition'   => isset( $get_data['data_saved'] ) && 'partial' === $get_data['data_saved'],
1497
				'message'     => __( 'This data was partially successfully saved. This means some of the data was unable to save. If you have enabled logging or debug mode in the plugin settings, there should be a log entry with further details.', 'object-sync-for-salesforce' ),
1498
				'type'        => 'error',
1499
				'dismissible' => true,
1500
			),
1501
			'data_save_error'         => array(
1502
				'condition'   => isset( $get_data['data_saved'] ) && 'false' === $get_data['data_saved'],
1503
				'message'     => esc_html__( 'This data was not successfully saved. Try again.', 'object-sync-for-salesforce' ),
1504
				'type'        => 'error',
1505
				'dismissible' => true,
1506
			),
1507
			'mapping_error_transient' => array(
1508
				'condition'   => isset( $get_data['mapping_error_transient'] ),
1509
				'message'     => esc_html__( 'Errors kept these mapping errors from being deleted.', 'object-sync-for-salesforce' ),
1510
				'type'        => 'error',
1511
				'dismissible' => true,
1512
			),
1513
		);
1514
		return $notices;
1515
	}
1516
1517
	/**
1518
	 * Create the notices, settings, and conditions by which admin notices should appear
1519
	 */
1520
	public function display_notices() {
1521
1522
		// before a notice is displayed, we should make sure we are on a page related to this plugin.
1523
		if ( ! isset( $_GET['page'] ) || $this->admin_settings_url_param !== $_GET['page'] ) {
1524
			return;
1525
		}
1526
1527
		$get_data = filter_input_array( INPUT_GET, FILTER_SANITIZE_SPECIAL_CHARS );
1528
		$notices  = $this->notices_data();
1529
1530
		foreach ( $notices as $key => $value ) {
1531
1532
			$condition = (bool) $value['condition'];
1533
			$message   = $value['message'];
1534
1535
			if ( isset( $value['dismissible'] ) ) {
1536
				$dismissible = $value['dismissible'];
1537
			} else {
1538
				$dismissible = false;
1539
			}
1540
1541
			if ( isset( $value['type'] ) ) {
1542
				$type = $value['type'];
1543
			} else {
1544
				$type = '';
1545
			}
1546
1547
			if ( ! isset( $value['template'] ) ) {
1548
				$template = '';
1549
			}
1550
1551
			if ( $condition ) {
1552
				new Object_Sync_Sf_Admin_Notice( $condition, $message, $dismissible, $type, $template );
1553
			}
1554
		}
1555
1556
	}
1557
1558
	/**
1559
	 * Get all the Salesforce object settings for fieldmapping
1560
	 * This takes either the $_POST array via ajax, or can be directly called with a $data array
1561
	 *
1562
	 * @param array $data must contain a Salesforce object, can optionally contain a type.
1563
	 * @return array $object_settings
1564
	 */
1565
	public function get_salesforce_object_description( $data = array() ) {
1566
		$ajax = false;
1567
		if ( empty( $data ) ) {
1568
			$data = filter_input_array( INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS );
1569
			$ajax = true;
1570
		}
1571
1572
		$object_description = array();
1573
1574
		if ( ! empty( $data['salesforce_object'] ) ) {
1575
			$object = $this->salesforce['sfapi']->object_describe( esc_attr( $data['salesforce_object'] ) );
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1575
			$object = $this->salesforce['sfapi']->object_describe( /** @scrutinizer ignore-call */ esc_attr( $data['salesforce_object'] ) );
Loading history...
1576
1577
			$object_fields        = array();
1578
			$include_record_types = array();
1579
1580
			// these can come from ajax.
1581
			$include = isset( $data['include'] ) ? (array) $data['include'] : array();
1582
			$include = array_map( 'esc_attr', $include );
1583
1584
			if ( in_array( 'fields', $include, true ) || empty( $include ) ) {
1585
				$type = isset( $data['field_type'] ) ? esc_attr( $data['field_type'] ) : ''; // can come from ajax.
1586
1587
				// here, we should respect the decision of whether to show the API name or the label.
1588
				$display_value = get_option( $this->option_prefix . 'salesforce_field_display_value', 'field_label' );
0 ignored issues
show
Bug introduced by
The function get_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1588
				$display_value = /** @scrutinizer ignore-call */ get_option( $this->option_prefix . 'salesforce_field_display_value', 'field_label' );
Loading history...
1589
				if ( 'api_name' === $display_value ) {
1590
					$visible_label_field = 'name';
1591
				} else {
1592
					$visible_label_field = 'label';
1593
				}
1594
				$attributes = array( 'name', $visible_label_field );
1595
1596
				foreach ( $object['data']['fields'] as $key => $value ) {
1597
					if ( '' === $type || $type === $value['type'] ) {
1598
						$object_fields[ $key ] = $value;
1599
						if ( isset( $attributes ) ) {
1600
							$object_fields[ $key ] = array_intersect_key( $value, array_flip( $attributes ) );
1601
						}
1602
					}
1603
				}
1604
				$object_description['fields'] = $object_fields;
1605
			}
1606
1607
			if ( in_array( 'recordTypeInfos', $include, true ) ) {
1608
				if ( isset( $object['data']['recordTypeInfos'] ) && count( $object['data']['recordTypeInfos'] ) > 1 ) {
1609
					foreach ( $object['data']['recordTypeInfos'] as $type ) {
1610
						$object_record_types[ $type['recordTypeId'] ] = $type['name'];
1611
					}
1612
					$object_description['recordTypeInfos'] = $object_record_types;
1613
				}
1614
			}
1615
		}
1616
1617
		if ( true === $ajax ) {
1618
			wp_send_json_success( $object_description );
0 ignored issues
show
Bug introduced by
The function wp_send_json_success was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1618
			/** @scrutinizer ignore-call */ 
1619
   wp_send_json_success( $object_description );
Loading history...
1619
		} else {
1620
			return $object_description;
1621
		}
1622
	}
1623
1624
	/**
1625
	 * Get all the Salesforce fields settings for fieldmapping
1626
	 * This takes either the $_POST array via ajax, or can be directly called with a $data array
1627
	 *
1628
	 * @param array $data must contain a Salesforce object unless it is Ajax, can optionally contain a type.
1629
	 * @return array $object_fields
1630
	 */
1631
	public function get_salesforce_object_fields( $data = array() ) {
1632
		$ajax      = false;
1633
		$post_data = filter_input_array( INPUT_POST, FILTER_UNSAFE_RAW );
1634
		if ( empty( $data ) ) {
1635
			$salesforce_object = isset( $post_data['salesforce_object'] ) ? sanitize_text_field( wp_unslash( $post_data['salesforce_object'] ) ) : '';
0 ignored issues
show
Bug introduced by
The function wp_unslash was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1635
			$salesforce_object = isset( $post_data['salesforce_object'] ) ? sanitize_text_field( /** @scrutinizer ignore-call */ wp_unslash( $post_data['salesforce_object'] ) ) : '';
Loading history...
Bug introduced by
The function sanitize_text_field was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1635
			$salesforce_object = isset( $post_data['salesforce_object'] ) ? /** @scrutinizer ignore-call */ sanitize_text_field( wp_unslash( $post_data['salesforce_object'] ) ) : '';
Loading history...
1636
			$ajax              = true;
1637
			// here, we should respect the decision of whether to show the API name or the label.
1638
			$display_value = get_option( $this->option_prefix . 'salesforce_field_display_value', 'field_label' );
0 ignored issues
show
Bug introduced by
The function get_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1638
			$display_value = /** @scrutinizer ignore-call */ get_option( $this->option_prefix . 'salesforce_field_display_value', 'field_label' );
Loading history...
1639
			if ( 'api_name' === $display_value ) {
1640
				$visible_label_field = 'name';
1641
			} else {
1642
				$visible_label_field = 'label';
1643
			}
1644
			$attributes = array( 'name', $visible_label_field );
1645
		} else {
1646
			$salesforce_object = isset( $data['salesforce_object'] ) ? sanitize_text_field( wp_unslash( $data['salesforce_object'] ) ) : '';
1647
		}
1648
		$object_fields = array();
1649
		if ( ! empty( $salesforce_object ) ) {
1650
			$object               = $this->salesforce['sfapi']->object_describe( esc_attr( $salesforce_object ) );
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1650
			$object               = $this->salesforce['sfapi']->object_describe( /** @scrutinizer ignore-call */ esc_attr( $salesforce_object ) );
Loading history...
1651
			$object_fields        = array();
1652
			$type                 = isset( $data['type'] ) ? esc_attr( $data['type'] ) : '';
1653
			$include_record_types = isset( $data['include_record_types'] ) ? esc_attr( $data['include_record_types'] ) : false;
1654
			foreach ( $object['data']['fields'] as $key => $value ) {
1655
				if ( '' === $type || $type === $value['type'] ) {
1656
					$object_fields[ $key ] = $value;
1657
					if ( isset( $attributes ) ) {
1658
						$object_fields[ $key ] = array_intersect_key( $value, array_flip( $attributes ) );
1659
					}
1660
				}
1661
			}
1662
			if ( true === $include_record_types ) {
1663
				$object_record_types = array();
1664
				if ( isset( $object['data']['recordTypeInfos'] ) && count( $object['data']['recordTypeInfos'] ) > 1 ) {
1665
					foreach ( $object['data']['recordTypeInfos'] as $type ) {
1666
						$object_record_types[ $type['recordTypeId'] ] = $type['name'];
1667
					}
1668
				}
1669
			}
1670
		}
1671
1672
		if ( true === $ajax ) {
1673
			$ajax_response = array(
1674
				'fields' => $object_fields,
1675
			);
1676
			wp_send_json_success( $ajax_response );
0 ignored issues
show
Bug introduced by
The function wp_send_json_success was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1676
			/** @scrutinizer ignore-call */ 
1677
   wp_send_json_success( $ajax_response );
Loading history...
1677
		} else {
1678
			return $object_fields;
1679
		}
1680
1681
	}
1682
1683
	/**
1684
	 * Get WordPress object fields for fieldmapping
1685
	 * This takes either the $_POST array via ajax, or can be directly called with a $wordpress_object field
1686
	 *
1687
	 * @param string $wordpress_object is the name of the WordPress object.
1688
	 * @return array $object_fields
1689
	 */
1690
	public function get_wordpress_object_fields( $wordpress_object = '' ) {
1691
		$ajax      = false;
1692
		$post_data = filter_input_array( INPUT_POST, FILTER_UNSAFE_RAW );
1693
		if ( empty( $wordpress_object ) ) {
1694
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? sanitize_text_field( wp_unslash( $post_data['wordpress_object'] ) ) : '';
0 ignored issues
show
Bug introduced by
The function sanitize_text_field was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1694
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? /** @scrutinizer ignore-call */ sanitize_text_field( wp_unslash( $post_data['wordpress_object'] ) ) : '';
Loading history...
Bug introduced by
The function wp_unslash was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1694
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? sanitize_text_field( /** @scrutinizer ignore-call */ wp_unslash( $post_data['wordpress_object'] ) ) : '';
Loading history...
1695
			$ajax             = true;
1696
		}
1697
1698
		$object_fields = $this->wordpress->get_wordpress_object_fields( $wordpress_object );
1699
1700
		if ( true === $ajax ) {
1701
			$ajax_response = array(
1702
				'fields' => $object_fields,
1703
			);
1704
			wp_send_json_success( $ajax_response );
0 ignored issues
show
Bug introduced by
The function wp_send_json_success was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1704
			/** @scrutinizer ignore-call */ 
1705
   wp_send_json_success( $ajax_response );
Loading history...
1705
		} else {
1706
			return $object_fields;
1707
		}
1708
	}
1709
1710
	/**
1711
	 * Manually push the WordPress object to Salesforce
1712
	 * This takes either the $_POST array via ajax, or can be directly called with $wordpress_object and $wordpress_id fields
1713
	 *
1714
	 * @param string $wordpress_object is the name of the WordPress object.
1715
	 * @param int    $wordpress_id is the ID of the WordPress record.
1716
	 * @param bool   $force_return Force the method to return json instead of outputting it.
1717
	 */
1718
	public function push_to_salesforce( $wordpress_object = '', $wordpress_id = '', $force_return = false ) {
1719
		$post_data = filter_input_array( INPUT_POST, FILTER_UNSAFE_RAW );
1720
		if ( empty( $wordpress_object ) && empty( $wordpress_id ) ) {
1721
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? sanitize_text_field( wp_unslash( $post_data['wordpress_object'] ) ) : '';
0 ignored issues
show
Bug introduced by
The function sanitize_text_field was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1721
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? /** @scrutinizer ignore-call */ sanitize_text_field( wp_unslash( $post_data['wordpress_object'] ) ) : '';
Loading history...
Bug introduced by
The function wp_unslash was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1721
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? sanitize_text_field( /** @scrutinizer ignore-call */ wp_unslash( $post_data['wordpress_object'] ) ) : '';
Loading history...
1722
			$wordpress_id     = isset( $post_data['wordpress_id'] ) ? absint( $post_data['wordpress_id'] ) : '';
0 ignored issues
show
Bug introduced by
The function absint was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1722
			$wordpress_id     = isset( $post_data['wordpress_id'] ) ? /** @scrutinizer ignore-call */ absint( $post_data['wordpress_id'] ) : '';
Loading history...
1723
		}
1724
1725
		// clarify what that variable is in this context.
1726
		$object_type = $wordpress_object;
1727
1728
		// When objects are already mapped, there is a Salesforce id as well. Otherwise, it's blank.
1729
		$salesforce_id = isset( $post_data['salesforce_id'] ) ? sanitize_text_field( $post_data['salesforce_id'] ) : '';
1730
		if ( '' === $salesforce_id ) {
1731
			$method = 'POST';
1732
		} else {
1733
			$method = 'PUT';
1734
		}
1735
1736
		$result = $this->push->manual_push( $object_type, $wordpress_id, $method );
1737
1738
		if ( false === $force_return && ! empty( $post_data['wordpress_object'] ) && ! empty( $post_data['wordpress_id'] ) ) {
1739
			wp_send_json_success( $result );
0 ignored issues
show
Bug introduced by
The function wp_send_json_success was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1739
			/** @scrutinizer ignore-call */ 
1740
   wp_send_json_success( $result );
Loading history...
1740
		} else {
1741
			return $result;
1742
		}
1743
1744
	}
1745
1746
	/**
1747
	 * Manually pull the Salesforce object into WordPress
1748
	 * This takes either the $_POST array via ajax, or can be directly called with $salesforce_id fields
1749
	 *
1750
	 * @param string $salesforce_id is the ID of the Salesforce record.
1751
	 * @param string $wordpress_object is the name of the WordPress object.
1752
	 */
1753
	public function pull_from_salesforce( $salesforce_id = '', $wordpress_object = '' ) {
1754
		$post_data = filter_input_array( INPUT_POST, FILTER_UNSAFE_RAW );
1755
		if ( empty( $wordpress_object ) && empty( $salesforce_id ) ) {
1756
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? sanitize_text_field( wp_unslash( $post_data['wordpress_object'] ) ) : '';
0 ignored issues
show
Bug introduced by
The function sanitize_text_field was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1756
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? /** @scrutinizer ignore-call */ sanitize_text_field( wp_unslash( $post_data['wordpress_object'] ) ) : '';
Loading history...
Bug introduced by
The function wp_unslash was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1756
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? sanitize_text_field( /** @scrutinizer ignore-call */ wp_unslash( $post_data['wordpress_object'] ) ) : '';
Loading history...
1757
			$salesforce_id    = isset( $post_data['salesforce_id'] ) ? sanitize_text_field( wp_unslash( $post_data['salesforce_id'] ) ) : '';
1758
		}
1759
		$type   = $this->salesforce['sfapi']->get_sobject_type( $salesforce_id );
1760
		$result = $this->pull->manual_pull( $type, $salesforce_id, $wordpress_object ); // we want the wp object to make sure we get the right fieldmap.
1761
		if ( ! empty( $post_data ) ) {
1762
			wp_send_json_success( $result );
0 ignored issues
show
Bug introduced by
The function wp_send_json_success was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1762
			/** @scrutinizer ignore-call */ 
1763
   wp_send_json_success( $result );
Loading history...
1763
		} else {
1764
			return $result;
1765
		}
1766
	}
1767
1768
	/**
1769
	 * Manually pull the Salesforce object into WordPress
1770
	 * This takes an id for a mapping object row
1771
	 *
1772
	 * @param int $mapping_id is the ID of the mapping object record.
1773
	 */
1774
	public function refresh_mapped_data( $mapping_id = '' ) {
1775
		$post_data = filter_input_array( INPUT_POST, FILTER_UNSAFE_RAW );
1776
		if ( empty( $mapping_id ) ) {
1777
			$mapping_id = isset( $post_data['mapping_id'] ) ? absint( $post_data['mapping_id'] ) : '';
0 ignored issues
show
Bug introduced by
The function absint was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1777
			$mapping_id = isset( $post_data['mapping_id'] ) ? /** @scrutinizer ignore-call */ absint( $post_data['mapping_id'] ) : '';
Loading history...
1778
		}
1779
		$result = $this->mappings->get_all_object_maps(
1780
			array(
1781
				'id' => $mapping_id,
1782
			)
1783
		);
1784
1785
		$object_map = array();
1786
1787
		// result is an array of arrays, not just one array.
1788
		if ( 1 === count( $result ) ) {
1789
			$object_map = $result[0];
1790
		}
1791
1792
		if ( ! empty( $post_data ) ) {
1793
			wp_send_json_success( $object_map );
0 ignored issues
show
Bug introduced by
The function wp_send_json_success was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1793
			/** @scrutinizer ignore-call */ 
1794
   wp_send_json_success( $object_map );
Loading history...
1794
		} else {
1795
			return $object_map;
1796
		}
1797
	}
1798
1799
	/**
1800
	 * Prepare fieldmap data and redirect after processing
1801
	 * This runs when the create or update forms are submitted
1802
	 * It is public because it depends on an admin hook
1803
	 * It then calls the Object_Sync_Sf_Mapping class and sends prepared data over to it, then redirects to the correct page
1804
	 * This method does include error handling, by loading the submission in a transient if there is an error, and then deleting it upon success
1805
	 */
1806
	public function prepare_fieldmap_data() {
1807
		$error     = false;
1808
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS );
1809
		$cachekey  = wp_json_encode( $post_data );
0 ignored issues
show
Bug introduced by
The function wp_json_encode was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1809
		$cachekey  = /** @scrutinizer ignore-call */ wp_json_encode( $post_data );
Loading history...
1810
		if ( false !== $cachekey ) {
1811
			$cachekey = md5( $cachekey );
1812
		}
1813
1814
		if ( ! isset( $post_data['label'] ) || ! isset( $post_data['salesforce_object'] ) || ! isset( $post_data['wordpress_object'] ) ) {
1815
			$error = true;
1816
		}
1817
		if ( true === $error ) {
1818
			$this->sfwp_transients->set( $cachekey, $post_data, $this->wordpress->options['cache_expiration'] );
1819
			if ( '' !== $cachekey ) {
1820
				$url = esc_url_raw( $post_data['redirect_url_error'] ) . '&transient=' . $cachekey;
0 ignored issues
show
Bug introduced by
The function esc_url_raw was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1820
				$url = /** @scrutinizer ignore-call */ esc_url_raw( $post_data['redirect_url_error'] ) . '&transient=' . $cachekey;
Loading history...
1821
			}
1822
		} else { // there are no errors
1823
			// send the row to the fieldmap class
1824
			// if it is add or clone, use the create method.
1825
			$method            = esc_attr( $post_data['method'] );
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1825
			$method            = /** @scrutinizer ignore-call */ esc_attr( $post_data['method'] );
Loading history...
1826
			$salesforce_fields = $this->get_salesforce_object_fields(
1827
				array(
1828
					'salesforce_object' => $post_data['salesforce_object'],
1829
				)
1830
			);
1831
			$wordpress_fields  = $this->get_wordpress_object_fields( $post_data['wordpress_object'] );
1832
			if ( 'add' === $method || 'clone' === $method ) {
1833
				$result = $this->mappings->create_fieldmap( $post_data, $wordpress_fields, $salesforce_fields );
1834
			} elseif ( 'edit' === $method ) { // if it is edit, use the update method.
1835
				$id     = esc_attr( $post_data['id'] );
1836
				$result = $this->mappings->update_fieldmap( $post_data, $wordpress_fields, $salesforce_fields, $id );
1837
			}
1838
			if ( false === $result ) { // if the database didn't save, it's still an error.
1839
				$this->sfwp_transients->set( $cachekey, $post_data, $this->wordpress->options['cache_expiration'] );
1840
				if ( '' !== $cachekey ) {
1841
					$url = esc_url_raw( $post_data['redirect_url_error'] ) . '&transient=' . $cachekey;
1842
				}
1843
			} else {
1844
				// if the user has saved a fieldmap, clear the currently running query value if there is one.
1845
				if ( '' !== get_option( $this->option_prefix . 'currently_pulling_query_' . $post_data['salesforce_object'], '' ) ) {
0 ignored issues
show
Bug introduced by
The function get_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1845
				if ( '' !== /** @scrutinizer ignore-call */ get_option( $this->option_prefix . 'currently_pulling_query_' . $post_data['salesforce_object'], '' ) ) {
Loading history...
1846
					$this->pull->clear_current_type_query( $post_data['salesforce_object'] );
1847
				}
1848
				if ( isset( $post_data['transient'] ) ) { // there was previously an error saved. can delete it now.
1849
					$this->sfwp_transients->delete( esc_attr( $post_data['map_transient'] ) );
1850
				}
1851
				// then send the user to the list of fieldmaps.
1852
				$url = esc_url_raw( $post_data['redirect_url_success'] );
1853
			}
1854
		}
1855
		wp_safe_redirect( $url );
0 ignored issues
show
Bug introduced by
The function wp_safe_redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1855
		/** @scrutinizer ignore-call */ 
1856
  wp_safe_redirect( $url );
Loading history...
1856
		exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1857
	}
1858
1859
	/**
1860
	 * Delete fieldmap data and redirect after processing
1861
	 * This runs when the delete link is clicked, after the user confirms
1862
	 * It is public because it depends on an admin hook
1863
	 * It then calls the Object_Sync_Sf_Mapping class and the delete method
1864
	 */
1865
	public function delete_fieldmap() {
1866
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS );
1867
		if ( $post_data['id'] ) {
1868
			$result = $this->mappings->delete_fieldmap( $post_data['id'] );
1869
			if ( true === $result ) {
1870
				$url = esc_url_raw( $post_data['redirect_url_success'] );
0 ignored issues
show
Bug introduced by
The function esc_url_raw was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1870
				$url = /** @scrutinizer ignore-call */ esc_url_raw( $post_data['redirect_url_success'] );
Loading history...
1871
			} else {
1872
				$url = esc_url_raw( $post_data['redirect_url_error'] . '&id=' . $post_data['id'] );
1873
			}
1874
			wp_safe_redirect( $url );
0 ignored issues
show
Bug introduced by
The function wp_safe_redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1874
			/** @scrutinizer ignore-call */ 
1875
   wp_safe_redirect( $url );
Loading history...
1875
			exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1876
		}
1877
	}
1878
1879
	/**
1880
	 * Prepare object data and redirect after processing
1881
	 * This runs when the update form is submitted
1882
	 * It is public because it depends on an admin hook
1883
	 * It then calls the Object_Sync_Sf_Mapping class and sends prepared data over to it, then redirects to the correct page
1884
	 * This method does include error handling, by loading the submission in a transient if there is an error, and then deleting it upon success
1885
	 */
1886
	public function prepare_object_map_data() {
1887
		$error     = false;
1888
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS );
1889
		$cachekey  = wp_json_encode( $post_data );
0 ignored issues
show
Bug introduced by
The function wp_json_encode was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1889
		$cachekey  = /** @scrutinizer ignore-call */ wp_json_encode( $post_data );
Loading history...
1890
		if ( false !== $cachekey ) {
1891
			$cachekey = md5( $cachekey );
1892
		}
1893
1894
		if ( ! isset( $post_data['wordpress_id'] ) || ! isset( $post_data['salesforce_id'] ) ) {
1895
			$error = true;
1896
		}
1897
		if ( true === $error ) {
1898
			$this->sfwp_transients->set( $cachekey, $post_data, $this->wordpress->options['cache_expiration'] );
1899
			if ( '' !== $cachekey ) {
1900
				$url = esc_url_raw( $post_data['redirect_url_error'] ) . '&map_transient=' . $cachekey;
0 ignored issues
show
Bug introduced by
The function esc_url_raw was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1900
				$url = /** @scrutinizer ignore-call */ esc_url_raw( $post_data['redirect_url_error'] ) . '&map_transient=' . $cachekey;
Loading history...
1901
			}
1902
		} else { // there are no errors
1903
			// send the row to the object map class.
1904
			$method = esc_attr( $post_data['method'] );
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1904
			$method = /** @scrutinizer ignore-call */ esc_attr( $post_data['method'] );
Loading history...
1905
			if ( 'edit' === $method ) { // if it is edit, use the update method.
1906
				$id     = esc_attr( $post_data['id'] );
1907
				$result = $this->mappings->update_object_map( $post_data, $id );
1908
			}
1909
			if ( false === $result ) { // if the database didn't save, it's still an error.
1910
				$this->sfwp_transients->set( $cachekey, $post_data, $this->wordpress->options['cache_expiration'] );
1911
				if ( '' !== $cachekey ) {
1912
					$url = esc_url_raw( $post_data['redirect_url_error'] ) . '&map_transient=' . $cachekey;
1913
				}
1914
			} else {
1915
				if ( isset( $post_data['map_transient'] ) ) { // there was previously an error saved. can delete it now.
1916
					$this->sfwp_transients->delete( esc_attr( $post_data['map_transient'] ) );
1917
				}
1918
				// then send the user to the success redirect url.
1919
				$url = esc_url_raw( $post_data['redirect_url_success'] );
1920
			}
1921
		}
1922
		wp_safe_redirect( $url );
0 ignored issues
show
Bug introduced by
The function wp_safe_redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1922
		/** @scrutinizer ignore-call */ 
1923
  wp_safe_redirect( $url );
Loading history...
1923
		exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1924
	}
1925
1926
	/**
1927
	 * Delete object map data and redirect after processing
1928
	 * This runs when the delete link is clicked on an error row, after the user confirms
1929
	 * It is public because it depends on an admin hook
1930
	 * It then calls the Object_Sync_Sf_Mapping class and the delete method
1931
	 */
1932
	public function delete_object_map() {
1933
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS );
1934
		if ( isset( $post_data['id'] ) ) {
1935
			$result = $this->mappings->delete_object_map( $post_data['id'] );
1936
			if ( true === $result ) {
1937
				$url = esc_url_raw( $post_data['redirect_url_success'] );
0 ignored issues
show
Bug introduced by
The function esc_url_raw was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1937
				$url = /** @scrutinizer ignore-call */ esc_url_raw( $post_data['redirect_url_success'] );
Loading history...
1938
			} else {
1939
				$url = esc_url_raw( $post_data['redirect_url_error'] . '&id=' . $post_data['id'] );
1940
			}
1941
			wp_safe_redirect( $url );
0 ignored issues
show
Bug introduced by
The function wp_safe_redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1941
			/** @scrutinizer ignore-call */ 
1942
   wp_safe_redirect( $url );
Loading history...
1942
			exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1943
		} elseif ( $post_data['delete'] ) {
1944
			$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS );
1945
			$cachekey  = wp_json_encode( $post_data );
0 ignored issues
show
Bug introduced by
The function wp_json_encode was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1945
			$cachekey  = /** @scrutinizer ignore-call */ wp_json_encode( $post_data );
Loading history...
1946
			if ( false !== $cachekey ) {
1947
				$cachekey = md5( $cachekey );
1948
			}
1949
			$error = false;
1950
			if ( ! isset( $post_data['delete'] ) ) {
1951
				$error = true;
1952
			}
1953
			if ( true === $error ) {
1954
				$this->sfwp_transients->set( $cachekey, $post_data, $this->wordpress->options['cache_expiration'] );
1955
				if ( '' !== $cachekey ) {
1956
					$url = esc_url_raw( $post_data['redirect_url_error'] ) . '&mapping_error_transient=' . $cachekey;
1957
				}
1958
			} else { // there are no errors.
1959
				$result = $this->mappings->delete_object_map( array_keys( $post_data['delete'] ) );
1960
				if ( true === $result ) {
1961
					$url = esc_url_raw( $post_data['redirect_url_success'] );
1962
				}
1963
1964
				if ( false === $result ) { // if the database didn't save, it's still an error.
1965
					$this->sfwp_transients->set( $cachekey, $post_data, $this->wordpress->options['cache_expiration'] );
1966
					if ( '' !== $cachekey ) {
1967
						$url = esc_url_raw( $post_data['redirect_url_error'] ) . '&mapping_error_transient=' . $cachekey;
1968
					}
1969
				} else {
1970
					if ( isset( $post_data['mapping_error_transient'] ) ) { // there was previously an error saved. can delete it now.
1971
						$this->sfwp_transients->delete( esc_attr( $post_data['mapping_error_transient'] ) );
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1971
						$this->sfwp_transients->delete( /** @scrutinizer ignore-call */ esc_attr( $post_data['mapping_error_transient'] ) );
Loading history...
1972
					}
1973
					// then send the user to the list of fieldmaps.
1974
					$url = esc_url_raw( $post_data['redirect_url_success'] );
1975
				}
1976
			}
1977
			wp_safe_redirect( $url );
1978
			exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1979
		}
1980
	}
1981
1982
	/**
1983
	 * Import a json file and use it for plugin data
1984
	 */
1985
	public function import_json_file() {
1986
1987
		if ( ! wp_verify_nonce( $_POST['object_sync_for_salesforce_nonce_import'], 'object_sync_for_salesforce_nonce_import' ) ) {
0 ignored issues
show
Bug introduced by
The function wp_verify_nonce was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1987
		if ( ! /** @scrutinizer ignore-call */ wp_verify_nonce( $_POST['object_sync_for_salesforce_nonce_import'], 'object_sync_for_salesforce_nonce_import' ) ) {
Loading history...
1988
			return;
1989
		}
1990
		if ( ! current_user_can( 'manage_options' ) ) {
0 ignored issues
show
Bug introduced by
The function current_user_can was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1990
		if ( ! /** @scrutinizer ignore-call */ current_user_can( 'manage_options' ) ) {
Loading history...
1991
			return;
1992
		}
1993
		$path      = $_FILES['import_file']['name'];
1994
		$extension = pathinfo( $path, PATHINFO_EXTENSION );
1995
		if ( 'json' !== $extension ) {
1996
			wp_die( esc_html__( 'Please upload a valid .json file', 'object-sync-for-salesforce' ) );
0 ignored issues
show
Bug introduced by
The function wp_die was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1996
			/** @scrutinizer ignore-call */ 
1997
   wp_die( esc_html__( 'Please upload a valid .json file', 'object-sync-for-salesforce' ) );
Loading history...
Bug introduced by
The function esc_html__ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1996
			wp_die( /** @scrutinizer ignore-call */ esc_html__( 'Please upload a valid .json file', 'object-sync-for-salesforce' ) );
Loading history...
1997
		}
1998
1999
		$import_file = $_FILES['import_file']['tmp_name'];
2000
		if ( empty( $import_file ) ) {
2001
			wp_die( esc_html__( 'Please upload a file to import', 'object-sync-for-salesforce' ) );
2002
		}
2003
2004
		// Retrieve the data from the file and convert the json object to an array.
2005
		$data = (array) json_decode( file_get_contents( $import_file ), true ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
2006
2007
		$overwrite = isset( $_POST['overwrite'] ) ? esc_attr( $_POST['overwrite'] ) : '';
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2007
		$overwrite = isset( $_POST['overwrite'] ) ? /** @scrutinizer ignore-call */ esc_attr( $_POST['overwrite'] ) : '';
Loading history...
2008
		if ( true === filter_var( $overwrite, FILTER_VALIDATE_BOOLEAN ) ) {
2009
			if ( isset( $data['fieldmaps'] ) ) {
2010
				$fieldmaps = $this->mappings->get_fieldmaps();
2011
				foreach ( $fieldmaps as $fieldmap ) {
2012
					$id     = $fieldmap['id'];
2013
					$delete = $this->mappings->delete_fieldmap( $id );
2014
				}
2015
			}
2016
			if ( isset( $data['object_maps'] ) ) {
2017
				$object_maps = $this->mappings->get_all_object_maps();
2018
				foreach ( $object_maps as $object_map ) {
2019
					$id     = $object_map['id'];
2020
					$delete = $this->mappings->delete_object_map( $id );
2021
				}
2022
			}
2023
			if ( isset( $data['plugin_settings'] ) ) {
2024
				foreach ( $data['plugin_settings'] as $key => $value ) {
2025
					delete_option( $value['option_name'] );
0 ignored issues
show
Bug introduced by
The function delete_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2025
					/** @scrutinizer ignore-call */ 
2026
     delete_option( $value['option_name'] );
Loading history...
2026
				}
2027
			}
2028
		}
2029
2030
		// if the option says to, set all the imported fieldmaps to inactive.
2031
		$import_fieldmaps_inactive = isset( $_POST['import_fieldmaps_inactive'] ) ? esc_attr( $_POST['import_fieldmaps_inactive'] ) : '';
2032
		if ( true === filter_var( $import_fieldmaps_inactive, FILTER_VALIDATE_BOOLEAN ) ) {
2033
			if ( isset( $data['fieldmaps'] ) ) {
2034
				foreach ( $data['fieldmaps'] as $key => $fieldmap ) {
2035
					$data['fieldmaps'][ $key ]['fieldmap_status'] = 'inactive';
2036
				}
2037
			}
2038
		}
2039
2040
		$success = true;
2041
2042
		if ( isset( $data['fieldmaps'] ) ) {
2043
			$successful_fieldmaps = array();
2044
			$error_fieldmaps      = array();
2045
			foreach ( $data['fieldmaps'] as $fieldmap ) {
2046
				unset( $fieldmap['id'] );
2047
				$create = $this->mappings->create_fieldmap( $fieldmap );
2048
				if ( false === $create ) {
2049
					$success = false;
2050
				}
2051
				if ( false === $create ) {
2052
					$error_fieldmaps[] = $fieldmap;
2053
				} else {
2054
					$successful_fieldmaps[] = $create;
2055
				}
2056
			}
2057
		}
2058
2059
		if ( isset( $data['object_maps'] ) ) {
2060
			$successful_object_maps = array();
2061
			$error_object_maps      = array();
2062
			foreach ( $data['object_maps'] as $object_map ) {
2063
				unset( $object_map['id'] );
2064
				if ( isset( $object_map['object_type'] ) ) {
2065
					$sf_sync_trigger = $this->mappings->sync_sf_create;
2066
					$create          = $this->pull->salesforce_pull_process_records( $object_map['object_type'], $object_map['salesforce_id'], $sf_sync_trigger );
2067
				} else {
2068
					$create = $this->mappings->create_object_map( $object_map );
2069
				}
2070
				if ( false === $create ) {
2071
					$error_object_maps[] = $object_map;
2072
				} else {
2073
					$successful_object_maps[] = $create;
2074
				}
2075
			}
2076
		}
2077
2078
		if ( isset( $data['plugin_settings'] ) ) {
2079
			foreach ( $data['plugin_settings'] as $key => $value ) {
2080
				update_option( $value['option_name'], maybe_unserialize( $value['option_value'] ), $value['autoload'] );
0 ignored issues
show
Bug introduced by
The function update_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2080
				/** @scrutinizer ignore-call */ 
2081
    update_option( $value['option_name'], maybe_unserialize( $value['option_value'] ), $value['autoload'] );
Loading history...
Bug introduced by
The function maybe_unserialize was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2080
				update_option( $value['option_name'], /** @scrutinizer ignore-call */ maybe_unserialize( $value['option_value'] ), $value['autoload'] );
Loading history...
2081
			}
2082
		}
2083
2084
		if ( ! empty( $error_fieldmaps ) && ! empty( $error_object_maps ) ) {
2085
			$status = 'error';
2086
			$body   = sprintf( esc_html__( 'These are the import items that were not able to save: ', 'object-sync-for-salesforce' ) . '<ul>' );
2087
			foreach ( $error_fieldmaps as $fieldmap ) {
2088
				$body .= sprintf(
2089
					// translators: placeholders are: 1) the fieldmap row ID, 2) the Salesforce object type, 3) the WordPress object type.
2090
					'<li>' . esc_html__( 'Fieldmap id (if it exists): %1$s. Salesforce object type: %2$s. WordPress object type: %3$s', 'object-sync-for-salesforce' ) . '</li>',
2091
					isset( $fieldmap['id'] ) ? absint( $fieldmap['id'] ) : '',
0 ignored issues
show
Bug introduced by
The function absint was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2091
					isset( $fieldmap['id'] ) ? /** @scrutinizer ignore-call */ absint( $fieldmap['id'] ) : '',
Loading history...
2092
					esc_attr( $fieldmap['salesforce_object'] ),
2093
					esc_attr( $fieldmap['wordpress_object'] )
2094
				);
2095
			}
2096
			foreach ( $error_object_maps as $mapping_object ) {
2097
				$body .= sprintf(
2098
					// translators: placeholders are: 1) the mapping object row ID, 2) the ID of the Salesforce object, 3) the WordPress object type.
2099
					'<li>' . esc_html__( 'Mapping object id (if it exists): %1$s. Salesforce Id: %2$s. WordPress object type: %3$s', 'object-sync-for-salesforce' ) . '</li>',
2100
					isset( $mapping_object['id'] ) ? absint( $mapping_object['id'] ) : '',
2101
					esc_attr( $mapping_object['salesforce_id'] ),
2102
					esc_attr( $mapping_object['wordpress_object'] )
2103
				);
2104
			}
2105
			$body .= sprintf( '</ul>' );
2106
2107
			$this->logging->setup(
2108
				sprintf(
2109
					// translators: %1$s is the log status.
2110
					esc_html__( '%1$s on import: some of the rows were unable to save. Read this post for details.', 'object-sync-for-salesforce' ),
2111
					ucfirst( esc_attr( $status ) )
2112
				),
2113
				$body,
2114
				0,
2115
				0,
2116
				$status
2117
			);
2118
		}
2119
2120
		if ( empty( $error_fieldmaps ) && empty( $error_object_maps ) && ( ! empty( $successful_fieldmaps ) || ! empty( $successful_object_maps ) ) ) {
2121
			$this->clear_cache( false );
2122
			wp_safe_redirect( get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=import-export&data_saved=true' ) );
0 ignored issues
show
Bug introduced by
The function get_admin_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2122
			wp_safe_redirect( /** @scrutinizer ignore-call */ get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=import-export&data_saved=true' ) );
Loading history...
Bug introduced by
The function wp_safe_redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2122
			/** @scrutinizer ignore-call */ 
2123
   wp_safe_redirect( get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=import-export&data_saved=true' ) );
Loading history...
2123
			exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
2124
		} elseif ( ! empty( $error_fieldmaps ) && ! empty( $successful_fieldmaps ) ) {
2125
			$this->clear_cache( false );
2126
			wp_safe_redirect( get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=import-export&data_saved=partial' ) );
2127
		} elseif ( ! empty( $error_object_maps ) && ! empty( $successful_object_maps ) ) {
2128
			$this->clear_cache( false );
2129
			wp_safe_redirect( get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=import-export&data_saved=partial' ) );
2130
		} else {
2131
			wp_safe_redirect( get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=import-export&data_saved=false' ) );
2132
			exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
2133
		}
2134
2135
	}
2136
2137
	/**
2138
	 * Create a json file for exporting
2139
	 */
2140
	public function export_json_file() {
2141
2142
		if ( ! wp_verify_nonce( $_POST['object_sync_for_salesforce_nonce_export'], 'object_sync_for_salesforce_nonce_export' ) ) {
0 ignored issues
show
Bug introduced by
The function wp_verify_nonce was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2142
		if ( ! /** @scrutinizer ignore-call */ wp_verify_nonce( $_POST['object_sync_for_salesforce_nonce_export'], 'object_sync_for_salesforce_nonce_export' ) ) {
Loading history...
2143
			return;
2144
		}
2145
		if ( ! current_user_can( 'manage_options' ) ) {
0 ignored issues
show
Bug introduced by
The function current_user_can was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2145
		if ( ! /** @scrutinizer ignore-call */ current_user_can( 'manage_options' ) ) {
Loading history...
2146
			return;
2147
		}
2148
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS );
2149
		$export    = array();
2150
		if ( in_array( 'fieldmaps', $post_data['export'], true ) ) {
2151
			$export['fieldmaps'] = $this->mappings->get_fieldmaps();
2152
		}
2153
		if ( in_array( 'object_maps', $post_data['export'], true ) ) {
2154
			$export['object_maps'] = $this->mappings->get_all_object_maps();
2155
		}
2156
		if ( in_array( 'plugin_settings', $post_data['export'], true ) ) {
2157
			$wpdb                      = $this->wpdb;
2158
			$export_results            = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->base_prefix}options` WHERE option_name LIKE %s;", $wpdb->esc_like( $this->option_prefix ) . '%' ), ARRAY_A );
0 ignored issues
show
Bug introduced by
The constant ARRAY_A was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2159
			$export['plugin_settings'] = $export_results;
2160
		}
2161
		nocache_headers();
0 ignored issues
show
Bug introduced by
The function nocache_headers was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2161
		/** @scrutinizer ignore-call */ 
2162
  nocache_headers();
Loading history...
2162
		header( 'Content-Type: application/json; charset=utf-8' );
2163
		header( 'Content-Disposition: attachment; filename=object-sync-for-salesforce-data-export-' . gmdate( 'm-d-Y' ) . '.json' );
2164
		header( 'Expires: 0' );
2165
		echo wp_json_encode( $export );
0 ignored issues
show
Bug introduced by
The function wp_json_encode was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2165
		echo /** @scrutinizer ignore-call */ wp_json_encode( $export );
Loading history...
2166
		exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
2167
	}
2168
2169
	/**
2170
	 * Default display for <input> fields
2171
	 *
2172
	 * @param array $args is the arguments to create the field.
2173
	 */
2174
	public function display_input_field( $args ) {
2175
		$type    = $args['type'];
2176
		$id      = $args['label_for'];
2177
		$name    = $args['name'];
2178
		$desc    = $args['desc'];
2179
		$checked = '';
2180
2181
		$class = 'regular-text';
2182
2183
		if ( 'checkbox' === $type ) {
2184
			$class = 'checkbox';
2185
		}
2186
2187
		if ( isset( $args['class'] ) ) {
2188
			$class = $args['class'];
2189
		}
2190
2191
		if ( ! isset( $args['constant'] ) || ! defined( $args['constant'] ) ) {
2192
			$value = esc_attr( get_option( $id, '' ) );
0 ignored issues
show
Bug introduced by
The function get_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2192
			$value = esc_attr( /** @scrutinizer ignore-call */ get_option( $id, '' ) );
Loading history...
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2192
			$value = /** @scrutinizer ignore-call */ esc_attr( get_option( $id, '' ) );
Loading history...
2193
			if ( 'checkbox' === $type ) {
2194
				$value = filter_var( get_option( $id, false ), FILTER_VALIDATE_BOOLEAN );
2195
				if ( true === $value ) {
2196
					$checked = 'checked ';
2197
				}
2198
				$value = 1;
2199
			}
2200
			if ( '' === $value && isset( $args['default'] ) && '' !== $args['default'] ) {
2201
				$value = $args['default'];
2202
			}
2203
2204
			echo sprintf(
2205
				'<input type="%1$s" value="%2$s" name="%3$s" id="%4$s" class="%5$s"%6$s>',
2206
				esc_attr( $type ),
2207
				esc_attr( $value ),
2208
				esc_attr( $name ),
2209
				esc_attr( $id ),
2210
				sanitize_html_class( $class . esc_html( ' code' ) ),
0 ignored issues
show
Bug introduced by
The function sanitize_html_class was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2210
				/** @scrutinizer ignore-call */ 
2211
    sanitize_html_class( $class . esc_html( ' code' ) ),
Loading history...
Bug introduced by
The function esc_html was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2210
				sanitize_html_class( $class . /** @scrutinizer ignore-call */ esc_html( ' code' ) ),
Loading history...
2211
				esc_html( $checked )
2212
			);
2213
			if ( '' !== $desc ) {
2214
				echo sprintf(
2215
					'<p class="description">%1$s</p>',
2216
					esc_html( $desc )
2217
				);
2218
			}
2219
		} else {
2220
			echo sprintf(
2221
				'<p><code>%1$s</code></p>',
2222
				esc_html__( 'Defined in wp-config.php', 'object-sync-for-salesforce' )
0 ignored issues
show
Bug introduced by
The function esc_html__ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2222
				/** @scrutinizer ignore-call */ 
2223
    esc_html__( 'Defined in wp-config.php', 'object-sync-for-salesforce' )
Loading history...
2223
			);
2224
		}
2225
	}
2226
2227
	/**
2228
	 * Display for multiple checkboxes
2229
	 * Above method can handle a single checkbox as it is
2230
	 *
2231
	 * @param array $args is the arguments to create the checkboxes.
2232
	 */
2233
	public function display_checkboxes( $args ) {
2234
		$type       = 'checkbox';
2235
		$name       = $args['name'];
2236
		$options    = get_option( $name, array() );
0 ignored issues
show
Bug introduced by
The function get_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2236
		$options    = /** @scrutinizer ignore-call */ get_option( $name, array() );
Loading history...
2237
		$group_desc = $args['desc'];
2238
		foreach ( $args['items'] as $key => $value ) {
2239
			$text    = $value['text'];
2240
			$id      = $value['id'];
2241
			$desc    = $value['desc'];
2242
			$checked = '';
2243
			if ( is_array( $options ) && in_array( (string) $key, $options, true ) ) {
2244
				$checked = 'checked';
2245
			} elseif ( is_array( $options ) && empty( $options ) ) {
2246
				if ( isset( $value['default'] ) && true === $value['default'] ) {
2247
					$checked = 'checked';
2248
				}
2249
			}
2250
			echo sprintf(
2251
				'<div class="checkbox"><label><input type="%1$s" value="%2$s" name="%3$s[]" id="%4$s"%5$s>%6$s</label></div>',
2252
				esc_attr( $type ),
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2252
				/** @scrutinizer ignore-call */ 
2253
    esc_attr( $type ),
Loading history...
2253
				esc_attr( $key ),
2254
				esc_attr( $name ),
2255
				esc_attr( $id ),
2256
				esc_html( $checked ),
0 ignored issues
show
Bug introduced by
The function esc_html was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2256
				/** @scrutinizer ignore-call */ 
2257
    esc_html( $checked ),
Loading history...
2257
				esc_html( $text )
2258
			);
2259
			if ( '' !== $desc ) {
2260
				echo sprintf(
2261
					'<p class="description">%1$s</p>',
2262
					esc_html( $desc )
2263
				);
2264
			}
2265
		}
2266
		if ( '' !== $group_desc ) {
2267
			echo sprintf(
2268
				'<p class="description">%1$s</p>',
2269
				esc_html( $group_desc )
2270
			);
2271
		}
2272
	}
2273
2274
	/**
2275
	 * Display for a dropdown
2276
	 *
2277
	 * @param array $args is the arguments needed to create the dropdown.
2278
	 */
2279
	public function display_select( $args ) {
2280
		$type = $args['type'];
2281
		$id   = $args['label_for'];
2282
		$name = $args['name'];
2283
		$desc = $args['desc'];
2284
		if ( ! isset( $args['constant'] ) || ! defined( $args['constant'] ) ) {
2285
			$current_value = get_option( $name );
0 ignored issues
show
Bug introduced by
The function get_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2285
			$current_value = /** @scrutinizer ignore-call */ get_option( $name );
Loading history...
2286
2287
			echo sprintf(
2288
				'<div class="select"><select id="%1$s" name="%2$s"><option value="">- ' . esc_html__( 'Select one', 'object-sync-for-salesforce' ) . ' -</option>',
0 ignored issues
show
Bug introduced by
The function esc_html__ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2288
				'<div class="select"><select id="%1$s" name="%2$s"><option value="">- ' . /** @scrutinizer ignore-call */ esc_html__( 'Select one', 'object-sync-for-salesforce' ) . ' -</option>',
Loading history...
2289
				esc_attr( $id ),
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2289
				/** @scrutinizer ignore-call */ 
2290
    esc_attr( $id ),
Loading history...
2290
				esc_attr( $name )
2291
			);
2292
2293
			foreach ( $args['items'] as $key => $value ) {
2294
				$text     = $value['text'];
2295
				$value    = $value['value'];
2296
				$selected = '';
2297
				if ( $key === $current_value || $value === $current_value ) {
2298
					$selected = ' selected';
2299
				}
2300
2301
				echo sprintf(
2302
					'<option value="%1$s"%2$s>%3$s</option>',
2303
					esc_attr( $value ),
2304
					esc_attr( $selected ),
2305
					esc_html( $text )
0 ignored issues
show
Bug introduced by
The function esc_html was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2305
					/** @scrutinizer ignore-call */ 
2306
     esc_html( $text )
Loading history...
2306
				);
2307
2308
			}
2309
			echo '</select>';
2310
			if ( '' !== $desc ) {
2311
				echo sprintf(
2312
					'<p class="description">%1$s</p>',
2313
					esc_html( $desc )
2314
				);
2315
			}
2316
			echo '</div>';
2317
		} else {
2318
			echo sprintf(
2319
				'<p><code>%1$s</code></p>',
2320
				esc_html__( 'Defined in wp-config.php', 'object-sync-for-salesforce' )
2321
			);
2322
		}
2323
	}
2324
2325
	/**
2326
	 * Default display for <a href> links
2327
	 *
2328
	 * @param array $args is the arguments to make the link.
2329
	 */
2330
	public function display_link( $args ) {
2331
		$label = $args['label'];
2332
		$desc  = $args['desc'];
2333
		$url   = $args['url'];
2334
		if ( isset( $args['link_class'] ) ) {
2335
			echo sprintf(
2336
				'<p><a class="%1$s" href="%2$s">%3$s</a></p>',
2337
				esc_attr( $args['link_class'] ),
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2337
				/** @scrutinizer ignore-call */ 
2338
    esc_attr( $args['link_class'] ),
Loading history...
2338
				esc_url( $url ),
0 ignored issues
show
Bug introduced by
The function esc_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2338
				/** @scrutinizer ignore-call */ 
2339
    esc_url( $url ),
Loading history...
2339
				esc_html( $label )
0 ignored issues
show
Bug introduced by
The function esc_html was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2339
				/** @scrutinizer ignore-call */ 
2340
    esc_html( $label )
Loading history...
2340
			);
2341
		} else {
2342
			echo sprintf(
2343
				'<p><a href="%1$s">%2$s</a></p>',
2344
				esc_url( $url ),
2345
				esc_html( $label )
2346
			);
2347
		}
2348
2349
		if ( '' !== $desc ) {
2350
			echo sprintf(
2351
				'<p class="description">%1$s</p>',
2352
				esc_html( $desc )
2353
			);
2354
		}
2355
2356
	}
2357
2358
	/**
2359
	 * Allow for a standard sanitize/validate method. We could use more specific ones if need be, but this one provides a baseline.
2360
	 *
2361
	 * @param string $option is the option value.
2362
	 * @return string $option is the sanitized option value.
2363
	 */
2364
	public function sanitize_validate_text( $option ) {
2365
		if ( is_array( $option ) ) {
0 ignored issues
show
introduced by
The condition is_array($option) is always false.
Loading history...
2366
			$options = array();
2367
			foreach ( $option as $key => $value ) {
2368
				$options[ $key ] = sanitize_text_field( $value );
0 ignored issues
show
Bug introduced by
The function sanitize_text_field was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2368
				$options[ $key ] = /** @scrutinizer ignore-call */ sanitize_text_field( $value );
Loading history...
2369
			}
2370
			return $options;
2371
		}
2372
		$option = sanitize_text_field( $option );
2373
		return $option;
2374
	}
2375
2376
	/**
2377
	 * Run a demo of Salesforce API call on the authenticate tab after WordPress has authenticated with it
2378
	 *
2379
	 * @param object $sfapi this is the Salesforce API object.
2380
	 */
2381
	private function status( $sfapi ) {
2382
2383
		$contacts = $sfapi->query( 'SELECT Name, Id from Contact LIMIT 100' );
2384
2385
		if ( 200 !== $contacts['code'] ) {
2386
			$contacts_apicall_summary = esc_html__( 'The plugin was unable to load a sample of Contacts from Salesforce. This may mean that there are connection issues, or that the authorization has expired.', 'object-sync-for-salesforce' );
0 ignored issues
show
Bug introduced by
The function esc_html__ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2386
			$contacts_apicall_summary = /** @scrutinizer ignore-call */ esc_html__( 'The plugin was unable to load a sample of Contacts from Salesforce. This may mean that there are connection issues, or that the authorization has expired.', 'object-sync-for-salesforce' );
Loading history...
2387
		} else {
2388
2389
			// format this array into html so users can see the contacts.
2390
			if ( true === $contacts['cached'] ) {
2391
				$contacts_is_cached = esc_html__( 'They are cached, and', 'object-sync-for-salesforce' );
2392
			} else {
2393
				$contacts_is_cached = esc_html__( 'They are not cached, but', 'object-sync-for-salesforce' );
2394
			}
2395
2396
			if ( true === $contacts['from_cache'] ) {
2397
				$contacts_from_cache = esc_html__( 'they were loaded from the cache', 'object-sync-for-salesforce' );
2398
			} else {
2399
				$contacts_from_cache = esc_html__( 'they were not loaded from the cache', 'object-sync-for-salesforce' );
2400
			}
2401
2402
			if ( true === $contacts['is_redo'] ) {
2403
				$contacts_refreshed_token = esc_html__( 'This request did require refreshing the Salesforce token', 'object-sync-for-salesforce' );
2404
			} else {
2405
				$contacts_refreshed_token = esc_html__( 'This request did not require refreshing the Salesforce token', 'object-sync-for-salesforce' );
2406
			}
2407
2408
			// display contact summary if there are any contacts.
2409
			if ( 0 < absint( $contacts['data']['totalSize'] ) ) {
0 ignored issues
show
Bug introduced by
The function absint was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2409
			if ( 0 < /** @scrutinizer ignore-call */ absint( $contacts['data']['totalSize'] ) ) {
Loading history...
2410
				$contacts_apicall_summary = sprintf(
2411
					// translators: 1) $contacts['data']['totalSize'] is the number of items loaded, 2) $contacts['data']['records'][0]['attributes']['type'] is the name of the Salesforce object, 3) $contacts_is_cached is the "They are/are not cached, and/but" line, 4) $contacts_from_cache is the "they were/were not loaded from the cache" line, 5) is the "this request did/did not require refreshing the Salesforce token" line.
2412
					esc_html__( 'Salesforce successfully returned %1$s %2$s records. %3$s %4$s. %5$s.', 'object-sync-for-salesforce' ),
2413
					absint( $contacts['data']['totalSize'] ),
2414
					esc_html( $contacts['data']['records'][0]['attributes']['type'] ),
0 ignored issues
show
Bug introduced by
The function esc_html was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2414
					/** @scrutinizer ignore-call */ 
2415
     esc_html( $contacts['data']['records'][0]['attributes']['type'] ),
Loading history...
2415
					$contacts_is_cached,
2416
					$contacts_from_cache,
2417
					$contacts_refreshed_token
2418
				);
2419
			} else {
2420
				$contacts_apicall_summary = '';
2421
			}
2422
		}
2423
2424
		require_once plugin_dir_path( $this->file ) . '/templates/admin/status.php';
0 ignored issues
show
Bug introduced by
The function plugin_dir_path was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2424
		require_once /** @scrutinizer ignore-call */ plugin_dir_path( $this->file ) . '/templates/admin/status.php';
Loading history...
2425
2426
	}
2427
2428
	/**
2429
	 * Deauthorize WordPress from Salesforce.
2430
	 * This deletes the tokens from the database; it does not currently do anything in Salesforce
2431
	 * For this plugin at this time, that is the decision we are making: don't do any kind of authorization stuff inside Salesforce
2432
	 */
2433
	private function logout() {
2434
		$delete_access_token = delete_option( $this->option_prefix . 'access_token' );
0 ignored issues
show
Bug introduced by
The function delete_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2434
		$delete_access_token = /** @scrutinizer ignore-call */ delete_option( $this->option_prefix . 'access_token' );
Loading history...
2435
		if ( true === $delete_access_token ) {
2436
			$this->access_token = '';
2437
		}
2438
		$delete_instance_url = delete_option( $this->option_prefix . 'instance_url' );
2439
		if ( true === $delete_instance_url ) {
2440
			$this->instance_url = '';
2441
		}
2442
		$delete_refresh_token = delete_option( $this->option_prefix . 'refresh_token' );
2443
		if ( true === $delete_refresh_token ) {
2444
			$this->refresh_token = '';
2445
		}
2446
		echo sprintf(
2447
			'<p>You have been logged out. You can use the <a href="%1$s">%2$s</a> tab to log in again.</p>',
2448
			esc_url( get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=authorize' ) ),
0 ignored issues
show
Bug introduced by
The function esc_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2448
			/** @scrutinizer ignore-call */ 
2449
   esc_url( get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=authorize' ) ),
Loading history...
Bug introduced by
The function get_admin_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2448
			esc_url( /** @scrutinizer ignore-call */ get_admin_url( null, 'options-general.php?page=' . $this->admin_settings_url_param . '&tab=authorize' ) ),
Loading history...
2449
			esc_html__( 'Authorize', 'object-sync-for-salesforce' )
0 ignored issues
show
Bug introduced by
The function esc_html__ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2449
			/** @scrutinizer ignore-call */ 
2450
   esc_html__( 'Authorize', 'object-sync-for-salesforce' )
Loading history...
2450
		);
2451
	}
2452
2453
	/**
2454
	 * Ajax call to clear the plugin cache.
2455
	 */
2456
	public function clear_sfwp_cache() {
2457
		$result   = $this->clear_cache( true );
2458
		$response = array(
2459
			'message' => $result['message'],
2460
			'success' => $result['success'],
2461
		);
2462
		wp_send_json_success( $response );
0 ignored issues
show
Bug introduced by
The function wp_send_json_success was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2462
		/** @scrutinizer ignore-call */ 
2463
  wp_send_json_success( $response );
Loading history...
2463
	}
2464
2465
	/**
2466
	 * Ajax call to delete the object_sync_for_salesforce_api_version value from wp_options
2467
	 *
2468
	 * @deprecated and will be removed in 3.0.0.
2469
	 */
2470
	public function delete_salesforce_api_version() {
2471
		$deprecated_option_key = $this->option_prefix . 'api_version';
2472
		$result                = delete_option( $deprecated_option_key );
0 ignored issues
show
Bug introduced by
The function delete_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2472
		$result                = /** @scrutinizer ignore-call */ delete_option( $deprecated_option_key );
Loading history...
2473
		if ( true === $result ) {
2474
			$message = sprintf(
2475
				// translators: the parameter is the option key where the API version was stored.
2476
				esc_html__( 'The %1$s value was successfully deleted.', 'object-sync-for-salesforce' ),
0 ignored issues
show
Bug introduced by
The function esc_html__ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2476
				/** @scrutinizer ignore-call */ 
2477
    esc_html__( 'The %1$s value was successfully deleted.', 'object-sync-for-salesforce' ),
Loading history...
2477
				'<code>' . $deprecated_option_key . '</code>'
2478
			);
2479
		} else {
2480
			$message = sprintf(
2481
				// translators: the parameter is the option key where the API version was stored.
2482
				esc_html__( 'There was an error in deleting the %1$s value. This may mean you have stored the value in a wp-config.php file instaed of in the options table. If this is not the case, you may want to reload the page and try again.', 'object-sync-for-salesforce' ),
2483
				'<code>' . $deprecated_option_key . '</code>'
2484
			);
2485
		}
2486
		$response = array(
2487
			'message' => $message,
2488
			'success' => $result,
2489
		);
2490
		wp_send_json_success( $response );
0 ignored issues
show
Bug introduced by
The function wp_send_json_success was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2490
		/** @scrutinizer ignore-call */ 
2491
  wp_send_json_success( $response );
Loading history...
2491
	}
2492
2493
	/**
2494
	 * Clear the plugin's cache.
2495
	 * This uses the flush method contained in the WordPress cache to clear all of this plugin's cached data.
2496
	 *
2497
	 * @param bool $ajax Whether this is an Ajax request or not.
2498
	 * @return array
2499
	 */
2500
	private function clear_cache( $ajax = false ) {
2501
		$result  = $this->wordpress->sfwp_transients->flush();
2502
		$success = $result['success'];
2503
		if ( 0 < $result['count'] ) {
2504
			if ( true === $success ) {
2505
				$message = __( 'The plugin cache has been cleared.', 'object-sync-for-salesforce' );
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2505
				$message = /** @scrutinizer ignore-call */ __( 'The plugin cache has been cleared.', 'object-sync-for-salesforce' );
Loading history...
2506
			} else {
2507
				$message = __( 'There was an error clearing the plugin cache. Try refreshing this page.', 'object-sync-for-salesforce' );
2508
			}
2509
		} else {
2510
			$success = true;
2511
			$message = __( 'The cache was not cleared because it is empty. You can try again later.', 'object-sync-for-salesforce' );
2512
		}
2513
		if ( false === $ajax ) {
2514
			echo '<p>' . esc_html( $message ) . '</p>';
0 ignored issues
show
Bug introduced by
The function esc_html was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2514
			echo '<p>' . /** @scrutinizer ignore-call */ esc_html( $message ) . '</p>';
Loading history...
2515
		} else {
2516
			return array(
2517
				'message' => esc_html( $message ),
2518
				'success' => $success,
2519
			);
2520
		}
2521
	}
2522
2523
	/**
2524
	 * Check WordPress Admin permissions
2525
	 * Check if the current user is allowed to access the Salesforce plugin options
2526
	 */
2527
	private function check_wordpress_admin_permissions() {
2528
2529
		// one programmatic way to give this capability to additional user roles is the
2530
		// object_sync_for_salesforce_roles_configure_salesforce hook
2531
		// it runs on activation of this plugin, and will assign the below capability to any role
2532
		// coming from the hook.
2533
2534
		// alternatively, other roles can get this capability in whatever other way you like
2535
		// point is: to administer this plugin, you need this capability.
2536
2537
		if ( ! current_user_can( 'configure_salesforce' ) ) {
0 ignored issues
show
Bug introduced by
The function current_user_can was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2537
		if ( ! /** @scrutinizer ignore-call */ current_user_can( 'configure_salesforce' ) ) {
Loading history...
2538
			return false;
2539
		} else {
2540
			return true;
2541
		}
2542
2543
	}
2544
2545
	/**
2546
	 * Check WordPress SSL status.
2547
	 * HTTPS is required to connect to Salesforce.
2548
	 *
2549
	 * @return bool $secure_admin
2550
	 */
2551
	private function check_wordpress_ssl() {
2552
2553
		// the wp_is_using_https() function was added in WordPress 5.7.
2554
		if ( ! function_exists( 'wp_is_using_https' ) ) {
2555
			return true;
2556
		}
2557
2558
		// the whole site is already using SSL.
2559
		if ( true === wp_is_using_https() ) {
2560
			return true;
2561
		}
2562
2563
		$secure_admin = false;
2564
2565
		// the admin is already forced to use SSL.
2566
		if ( true === FORCE_SSL_ADMIN ) {
0 ignored issues
show
Bug introduced by
The constant FORCE_SSL_ADMIN was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2567
			$secure_admin = true;
2568
		}
2569
2570
		// the server reports that the current URL is using HTTPS.
2571
		if ( isset( $_SERVER['HTTPS'] ) && 'on' === $_SERVER['HTTPS'] ) {
2572
			$secure_admin = true;
2573
		}
2574
2575
		return $secure_admin;
2576
	}
2577
2578
	/**
2579
	 * Check WordPress SSL support.
2580
	 * This allows us to show a different message if SSL is supported, but is not in use.
2581
	 *
2582
	 * @return bool $https_supported
2583
	 */
2584
	private function check_wordpress_ssl_support() {
2585
2586
		// the wp_is_https_supported() function was added in WordPress 5.7.
2587
		if ( ! function_exists( 'wp_is_https_supported' ) ) {
2588
			return true;
2589
		}
2590
2591
		if ( true === wp_is_https_supported() ) {
2592
			return true;
2593
		}
2594
2595
		$https_supported = false;
2596
		return $https_supported;
2597
2598
	}
2599
2600
	/**
2601
	 * Show what we know about this user's relationship to a Salesforce object, if any
2602
	 *
2603
	 * @param object $user this is the user object from WordPress.
2604
	 */
2605
	public function show_salesforce_user_fields( $user ) {
2606
		$get_data = filter_input_array( INPUT_GET, FILTER_SANITIZE_SPECIAL_CHARS );
2607
		if ( true === $this->check_wordpress_admin_permissions() ) {
2608
			$mappings = $this->mappings->load_all_by_wordpress( 'user', $user->ID );
2609
			$fieldmap = $this->mappings->get_fieldmaps(
2610
				null, // id field must be null for multiples.
2611
				array(
2612
					'wordpress_object' => 'user',
2613
				)
2614
			);
2615
			if ( count( $mappings ) > 0 ) {
2616
				foreach ( $mappings as $mapping ) {
2617
					if ( isset( $mapping['id'] ) && ! isset( $get_data['edit_salesforce_mapping'] ) && ! isset( $get_data['delete_salesforce_mapping'] ) ) {
2618
						require_once plugin_dir_path( $this->file ) . '/templates/admin/user-profile-salesforce.php';
0 ignored issues
show
Bug introduced by
The function plugin_dir_path was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2618
						require_once /** @scrutinizer ignore-call */ plugin_dir_path( $this->file ) . '/templates/admin/user-profile-salesforce.php';
Loading history...
2619
					} elseif ( ! empty( $fieldmap ) ) { // is the user mapped to something already?
2620
						if ( isset( $get_data['edit_salesforce_mapping'] ) && true === filter_var( $get_data['edit_salesforce_mapping'], FILTER_VALIDATE_BOOLEAN ) ) {
2621
							require_once plugin_dir_path( $this->file ) . '/templates/admin/user-profile-salesforce-change.php';
2622
						} elseif ( isset( $get_data['delete_salesforce_mapping'] ) && true === filter_var( $get_data['delete_salesforce_mapping'], FILTER_VALIDATE_BOOLEAN ) ) {
2623
							require_once plugin_dir_path( $this->file ) . '/templates/admin/user-profile-salesforce-delete.php';
2624
						} else {
2625
							require_once plugin_dir_path( $this->file ) . '/templates/admin/user-profile-salesforce-map.php';
2626
						}
2627
					}
2628
				}
2629
			} else {
2630
				require_once plugin_dir_path( $this->file ) . '/templates/admin/user-profile-salesforce-map.php';
2631
			}
2632
		}
2633
	}
2634
2635
	/**
2636
	 * If the user profile has been mapped to Salesforce, do it
2637
	 *
2638
	 * @param int $user_id the ID of the WordPress user.
2639
	 */
2640
	public function save_salesforce_user_fields( $user_id ) {
2641
		$post_data = filter_input_array( INPUT_POST, FILTER_UNSAFE_RAW );
2642
		if ( isset( $post_data['salesforce_update_mapped_user'] ) && true === filter_var( $post_data['salesforce_update_mapped_user'], FILTER_VALIDATE_BOOLEAN ) ) {
2643
			$mapping_objects = $this->mappings->get_all_object_maps(
2644
				array(
2645
					'wordpress_id'     => $user_id,
2646
					'wordpress_object' => 'user',
2647
				)
2648
			);
2649
			foreach ( $mapping_objects as $mapping_object ) {
2650
				$mapping_object['salesforce_id'] = $post_data['salesforce_id'];
2651
				$result                          = $this->mappings->update_object_map( $mapping_object, $mapping_object['id'] );
2652
			}
2653
		} elseif ( isset( $post_data['salesforce_create_mapped_user'] ) && true === filter_var( $post_data['salesforce_create_mapped_user'], FILTER_VALIDATE_BOOLEAN ) ) {
2654
			// if a Salesforce ID was entered.
2655
			if ( isset( $post_data['salesforce_id'] ) && ! empty( $post_data['salesforce_id'] ) ) {
2656
				$mapping_object = $this->create_object_map( $user_id, 'user', $post_data['salesforce_id'] );
2657
			} elseif ( isset( $post_data['push_new_user_to_salesforce'] ) ) {
2658
				// otherwise, create a new record in Salesforce.
2659
				$result = $this->push_to_salesforce( 'user', $user_id );
2660
			}
2661
		} elseif ( isset( $post_data['salesforce_delete_mapped_user'] ) && true === filter_var( $post_data['salesforce_delete_mapped_user'], FILTER_VALIDATE_BOOLEAN ) ) {
2662
			// if a Salesforce ID was entered.
2663
			if ( isset( $post_data['mapping_id'] ) && ! empty( $post_data['mapping_id'] ) ) {
2664
				$delete = $this->mappings->delete_object_map( $post_data['mapping_id'] );
2665
			}
2666
		}
2667
	}
2668
2669
	/**
2670
	 * Render tabs for settings pages in admin
2671
	 *
2672
	 * @param array  $tabs is the tabs for the settings menu.
2673
	 * @param string $tab is a single tab.
2674
	 */
2675
	private function tabs( $tabs, $tab = '' ) {
2676
2677
		$get_data        = filter_input_array( INPUT_GET, FILTER_SANITIZE_SPECIAL_CHARS );
2678
		$consumer_key    = $this->login_credentials['consumer_key'];
2679
		$consumer_secret = $this->login_credentials['consumer_secret'];
2680
		$callback_url    = $this->login_credentials['callback_url'];
2681
2682
		$current_tab = $tab;
2683
		echo '<h2 class="nav-tab-wrapper">';
2684
		foreach ( $tabs as $tab_key => $tab_caption ) {
2685
			$active = $current_tab === $tab_key ? ' nav-tab-active' : '';
2686
2687
			if ( true === $this->salesforce['is_authorized'] ) {
2688
				echo sprintf(
2689
					'<a class="nav-tab%1$s" href="%2$s">%3$s</a>',
2690
					esc_attr( $active ),
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2690
					/** @scrutinizer ignore-call */ 
2691
     esc_attr( $active ),
Loading history...
2691
					esc_url( '?page=' . $this->admin_settings_url_param . '&tab=' . $tab_key ),
0 ignored issues
show
Bug introduced by
The function esc_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2691
					/** @scrutinizer ignore-call */ 
2692
     esc_url( '?page=' . $this->admin_settings_url_param . '&tab=' . $tab_key ),
Loading history...
2692
					esc_html( $tab_caption )
0 ignored issues
show
Bug introduced by
The function esc_html was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2692
					/** @scrutinizer ignore-call */ 
2693
     esc_html( $tab_caption )
Loading history...
2693
				);
2694
			} elseif ( 'settings' === $tab_key || ( 'authorize' === $tab_key && isset( $consumer_key ) && isset( $consumer_secret ) && ! empty( $consumer_key ) && ! empty( $consumer_secret ) ) ) {
2695
				echo sprintf(
2696
					'<a class="nav-tab%1$s" href="%2$s">%3$s</a>',
2697
					esc_attr( $active ),
2698
					esc_url( '?page=' . $this->admin_settings_url_param . '&tab=' . $tab_key ),
2699
					esc_html( $tab_caption )
2700
				);
2701
			}
2702
		}
2703
		echo '</h2>';
2704
2705
		if ( isset( $get_data['tab'] ) ) {
2706
			$tab = sanitize_key( $get_data['tab'] );
0 ignored issues
show
Bug introduced by
The function sanitize_key was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2706
			$tab = /** @scrutinizer ignore-call */ sanitize_key( $get_data['tab'] );
Loading history...
2707
		} else {
2708
			$tab = '';
2709
		}
2710
	}
2711
2712
	/**
2713
	 * Clear schedule
2714
	 * This clears the schedule if the user clicks the button
2715
	 *
2716
	 * @param string $schedule_name is the name of the schedule being cleared.
2717
	 */
2718
	private function clear_schedule( $schedule_name = '' ) {
2719
		if ( '' !== $schedule_name ) {
2720
			$this->queue->cancel( $schedule_name );
2721
			// translators: $schedule_name is the name of the current queue. Defaults: salesforce_pull, salesforce_push, salesforce.
2722
			echo sprintf( esc_html__( 'You have cleared the %s schedule.', 'object-sync-for-salesforce' ), esc_html( $schedule_name ) );
0 ignored issues
show
Bug introduced by
The function esc_html__ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2722
			echo sprintf( /** @scrutinizer ignore-call */ esc_html__( 'You have cleared the %s schedule.', 'object-sync-for-salesforce' ), esc_html( $schedule_name ) );
Loading history...
Bug introduced by
The function esc_html was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2722
			echo sprintf( esc_html__( 'You have cleared the %s schedule.', 'object-sync-for-salesforce' ), /** @scrutinizer ignore-call */ esc_html( $schedule_name ) );
Loading history...
2723
		} else {
2724
			echo esc_html__( 'You need to specify the name of the schedule you want to clear.', 'object-sync-for-salesforce' );
2725
		}
2726
	}
2727
2728
	/**
2729
	 * Get count of schedule items
2730
	 *
2731
	 * @param string $schedule_name is the name of the schedule.
2732
	 * @return int $count
2733
	 */
2734
	private function get_schedule_count( $schedule_name = '' ) {
2735
		if ( '' !== $schedule_name ) {
2736
			$count       = count(
2737
				$this->queue->search(
2738
					array(
2739
						'group'  => $schedule_name,
2740
						'status' => ActionScheduler_Store::STATUS_PENDING,
2741
					),
2742
					'ARRAY_A'
2743
				)
2744
			);
2745
			$group_count = count(
2746
				$this->queue->search(
2747
					array(
2748
						'group'  => $schedule_name . $this->action_group_suffix,
2749
						'status' => ActionScheduler_Store::STATUS_PENDING,
2750
					),
2751
					'ARRAY_A'
2752
				)
2753
			);
2754
			return $count + $group_count;
2755
		} else {
2756
			return 0;
2757
		}
2758
	}
2759
2760
	/**
2761
	 * Create an object map between a WordPress object and a Salesforce object
2762
	 *
2763
	 * @param int    $wordpress_id Unique identifier for the WordPress object.
2764
	 * @param string $wordpress_object What kind of object is it.
2765
	 * @param string $salesforce_id Unique identifier for the Salesforce object.
2766
	 * @param string $action Did we push or pull.
2767
	 * @return int   $wpdb->insert_id This is the database row for the map object
2768
	 */
2769
	private function create_object_map( $wordpress_id, $wordpress_object, $salesforce_id, $action = '' ) {
2770
		// Create object map and save it.
2771
		$mapping_object = $this->mappings->create_object_map(
2772
			array(
2773
				'wordpress_id'      => $wordpress_id, // wordpress unique id.
2774
				'salesforce_id'     => $salesforce_id, // salesforce unique id. we don't care what kind of object it is at this point.
2775
				'wordpress_object'  => $wordpress_object, // keep track of what kind of wp object this is.
2776
				'last_sync'         => current_time( 'mysql' ),
0 ignored issues
show
Bug introduced by
The function current_time was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2776
				'last_sync'         => /** @scrutinizer ignore-call */ current_time( 'mysql' ),
Loading history...
2777
				'last_sync_action'  => $action,
2778
				'last_sync_status'  => $this->mappings->status_success,
2779
				'last_sync_message' => __( 'Mapping object updated via function: ', 'object-sync-for-salesforce' ) . __FUNCTION__,
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2779
				'last_sync_message' => /** @scrutinizer ignore-call */ __( 'Mapping object updated via function: ', 'object-sync-for-salesforce' ) . __FUNCTION__,
Loading history...
2780
			)
2781
		);
2782
2783
		return $mapping_object;
2784
2785
	}
2786
2787
}
2788