Test Failed
Pull Request — master (#238)
by Jonathan
02:43
created

Object_Sync_Sf_Admin   F

Complexity

Total Complexity 289

Size/Duplication

Total Lines 2189
Duplicated Lines 7.45 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 289
lcom 1
cbo 1
dl 163
loc 2189
rs 0.8
c 0
b 0
f 0

43 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 37 2
A add_actions() 0 37 2
A initial_action_schedule() 0 26 2
A change_action_schedule() 0 12 1
A set_action_schedule() 0 22 2
A create_admin_menu() 0 4 1
F show_admin_page() 35 211 52
A salesforce_settings_forms() 0 22 3
B fields_settings() 0 244 6
A fields_fieldmaps() 0 3 1
B fields_scheduling() 19 109 4
B fields_log_settings() 19 175 2
C notices() 0 76 10
C get_salesforce_object_description() 13 45 15
B get_salesforce_object_fields() 13 25 11
A get_wordpress_object_fields() 4 16 4
B get_wp_sf_object_fields() 6 22 6
B push_to_salesforce() 4 27 9
A pull_from_salesforce() 4 14 6
A refresh_mapped_data() 0 16 4
C prepare_fieldmap_data() 12 45 12
A delete_fieldmap() 5 13 3
B prepare_object_map_data() 12 36 9
B delete_object_map() 17 46 11
F import_json_file() 0 95 25
B export_json_file() 0 26 6
B display_input_field() 0 44 10
B display_checkboxes() 0 31 9
B display_select() 0 41 7
A version_options() 0 14 5
A display_link() 0 24 3
A sanitize_validate_text() 0 11 3
B status() 0 56 6
A logout() 0 9 1
A clear_sfwp_cache() 0 8 1
A clear_cache() 0 17 3
A check_wordpress_admin_permissions() 0 17 2
B show_salesforce_user_fields() 0 23 8
B save_salesforce_user_fields() 0 22 8
B tabs() 0 27 9
A clear_schedule() 0 9 2
A get_schedule_count() 0 21 2
A create_object_map() 0 17 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Object_Sync_Sf_Admin often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Object_Sync_Sf_Admin, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Class file for the Object_Sync_Sf_Admin class.
4
 *
5
 * @file
6
 */
7
8
if ( ! class_exists( 'Object_Sync_Salesforce' ) ) {
9
	die();
10
}
11
12
/**
13
 * Create default WordPress admin functionality to configure the plugin.
14
 */
15
class Object_Sync_Sf_Admin {
16
17
	protected $wpdb;
18
	protected $version;
19
	protected $login_credentials;
20
	protected $slug;
21
	protected $salesforce;
22
	protected $wordpress;
23
	protected $mappings;
24
	protected $push;
25
	protected $pull;
26
	protected $schedulable_classes;
27
	protected $queue;
28
	protected $option_prefix;
29
30
	/**
31
	* @var string
32
	* Default path for the Salesforce authorize URL
33
	*/
34
	public $default_authorize_url_path;
35
36
	/**
37
	* @var string
38
	* Default path for the Salesforce token URL
39
	*/
40
	public $default_token_url_path;
41
42
	/**
43
	* @var string
44
	* What version of the Salesforce API should be the default on the settings screen.
45
	* Users can edit this, but they won't see a correct list of all their available versions until WordPress has
46
	* been authenticated with Salesforce.
47
	*/
48
	public $default_api_version;
49
50
	/**
51
	* @var int
52
	* Default max number of pull records
53
	* Users can edit this
54
	*/
55
	public $default_pull_limit;
56
57
	/**
58
	* @var int
59
	* Default pull throttle for how often Salesforce can pull
60
	* Users can edit this
61
	*/
62
	public $default_pull_throttle;
63
64
	/**
65
	* @var bool
66
	* Default for whether to limit to triggerable items
67
	* Users can edit this
68
	*/
69
	public $default_triggerable;
70
71
	/**
72
	* @var bool
73
	* Default for whether to limit to updateable items
74
	* Users can edit this
75
	*/
76
	public $default_updateable;
77
78
	/**
79
	* @var string
80
	* Suffix for action group name
81
	*/
82
	public $action_group_suffix;
83
84
	/**
85
	* Constructor which sets up admin pages
86
	*
87
	* @param object $wpdb
88
	* @param string $version
89
	* @param array $login_credentials
90
	* @param string $slug
91
	* @param object $wordpress
92
	* @param object $salesforce
93
	* @param object $mappings
94
	* @param object $push
95
	* @param object $pull
96
	* @param object $logging
97
	* @param array $schedulable_classes
98
	* @param object $queue
99
	* @throws \Exception
100
	*/
101
	public function __construct( $wpdb, $version, $login_credentials, $slug, $wordpress, $salesforce, $mappings, $push, $pull, $logging, $schedulable_classes, $queue = '', $option_prefix = '' ) {
102
		$this->wpdb                = $wpdb;
103
		$this->version             = $version;
104
		$this->login_credentials   = $login_credentials;
105
		$this->slug                = $slug;
106
		$this->option_prefix       = isset( $option_prefix ) ? $option_prefix : 'object_sync_for_salesforce_';
107
		$this->wordpress           = $wordpress;
108
		$this->salesforce          = $salesforce;
109
		$this->mappings            = $mappings;
110
		$this->push                = $push;
111
		$this->pull                = $pull;
112
		$this->logging             = $logging;
113
		$this->schedulable_classes = $schedulable_classes;
114
		$this->queue               = $queue;
115
116
		$this->sfwp_transients = $this->wordpress->sfwp_transients;
117
118
		// default authorize url path
119
		$this->default_authorize_url_path = '/services/oauth2/authorize';
120
		// default token url path
121
		$this->default_token_url_path = '/services/oauth2/token';
122
		// what Salesforce API version to start the settings with. This is only used in the settings form
123
		$this->default_api_version = '44.0';
124
		// default pull record limit
125
		$this->default_pull_limit = 25;
126
		// default pull throttle for avoiding going over api limits
127
		$this->default_pull_throttle = 5;
128
		// default setting for triggerable items
129
		$this->default_triggerable = true;
130
		// default setting for updateable items
131
		$this->default_updateable = true;
132
		// suffix for action groups
133
		$this->action_group_suffix = '_check_records';
134
135
		$this->add_actions();
136
137
	}
138
139
	/**
140
	* Create the action hooks to create the admin page(s)
141
	*
142
	*/
143
	public function add_actions() {
144
		add_action( 'admin_init', array( $this, 'salesforce_settings_forms' ) );
145
		add_action( 'admin_init', array( $this, 'notices' ) );
146
		add_action( 'admin_post_post_fieldmap', array( $this, 'prepare_fieldmap_data' ) );
147
148
		add_action( 'admin_post_delete_fieldmap', array( $this, 'delete_fieldmap' ) );
149
		add_action( 'wp_ajax_get_salesforce_object_description', array( $this, 'get_salesforce_object_description' ) );
150
		add_action( 'wp_ajax_get_wordpress_object_description', array( $this, 'get_wordpress_object_fields' ) );
151
		add_action( 'wp_ajax_get_wp_sf_object_fields', array( $this, 'get_wp_sf_object_fields' ) );
152
		add_action( 'wp_ajax_push_to_salesforce', array( $this, 'push_to_salesforce' ) );
153
		add_action( 'wp_ajax_pull_from_salesforce', array( $this, 'pull_from_salesforce' ) );
154
		add_action( 'wp_ajax_refresh_mapped_data', array( $this, 'refresh_mapped_data' ) );
155
		add_action( 'wp_ajax_clear_sfwp_cache', array( $this, 'clear_sfwp_cache' ) );
156
157
		add_action( 'edit_user_profile', array( $this, 'show_salesforce_user_fields' ) );
158
		add_action( 'personal_options_update', array( $this, 'save_salesforce_user_fields' ) );
159
		add_action( 'edit_user_profile_update', array( $this, 'save_salesforce_user_fields' ) );
160
161
		// when either field for schedule settings changes
162
		foreach ( $this->schedulable_classes as $key => $value ) {
163
			// if the user doesn't have any action schedule tasks, let's not leave them empty
164
			add_filter( 'pre_update_option_' . $this->option_prefix . $key . '_schedule_number', array( $this, 'initial_action_schedule' ), 10, 3 );
165
			add_filter( 'pre_update_option_' . $this->option_prefix . $key . '_schedule_unit', array( $this, 'initial_action_schedule' ), 10, 3 );
166
167
			// this is if the user is changing their tasks
168
			add_filter( 'update_option_' . $this->option_prefix . $key . '_schedule_number', array( $this, 'change_action_schedule' ), 10, 3 );
169
			add_filter( 'update_option_' . $this->option_prefix . $key . '_schedule_unit', array( $this, 'change_action_schedule' ), 10, 3 );
170
		}
171
172
		add_action( 'admin_post_delete_object_map', array( $this, 'delete_object_map' ) );
173
		add_action( 'admin_post_post_object_map', array( $this, 'prepare_object_map_data' ) );
174
175
		// import and export plugin data
176
		add_action( 'admin_post_object_sync_for_salesforce_import', array( $this, 'import_json_file' ) );
177
		add_action( 'admin_post_object_sync_for_salesforce_export', array( $this, 'export_json_file' ) );
178
179
	}
180
181
	/**
182
	* Set up recurring tasks if there are none
183
	*
184
	* @param string $new_schedule
185
	* @param string $old_schedule
186
	* @param string $option_name
187
	* @return string $new_schedule
188
	*
189
	*/
190
	public function initial_action_schedule( $new_schedule, $old_schedule, $option_name ) {
191
192
		// get the current schedule name from the task, based on pattern in the foreach
193
		preg_match( '/' . $this->option_prefix . '(.*)_schedule/', $option_name, $matches );
194
		$schedule_name     = $matches[1];
195
		$action_group_name = $schedule_name . $this->action_group_suffix;
196
197
		// make sure there are no tasks already
198
		$current_tasks = as_get_scheduled_actions(
199
			array(
200
				'hook'  => $this->schedulable_classes[ $schedule_name ]['initializer'],
201
				'group' => $action_group_name,
202
			),
203
			ARRAY_A
204
		);
205
206
		// exit if there are already tasks; they'll be saved if the option data changed
207
		if ( ! empty( $current_tasks ) ) {
208
			return $new_schedule;
209
		}
210
211
		$this->set_action_schedule( $schedule_name, $action_group_name );
212
213
		return $new_schedule;
214
215
	}
216
217
	/**
218
	* Change recurring tasks if options change
219
	*
220
	* @param string $old_schedule
221
	* @param string $new_schedule
222
	* @param string $option_name
223
	*
224
	*/
225
	public function change_action_schedule( $old_schedule, $new_schedule, $option_name ) {
226
227
		// this method does not run if the option's data is unchanged
228
229
		// get the current schedule name from the task, based on pattern in the foreach
230
		preg_match( '/' . $this->option_prefix . '(.*)_schedule/', $option_name, $matches );
231
		$schedule_name     = $matches[1];
232
		$action_group_name = $schedule_name . $this->action_group_suffix;
233
234
		$this->set_action_schedule( $schedule_name, $action_group_name );
235
236
	}
237
238
	/**
239
	* Set up recurring tasks
240
	*
241
	* @param string $schedule_name
242
	* @param string $action_group_name
243
	*
244
	*/
245
	private function set_action_schedule( $schedule_name, $action_group_name ) {
246
		// exit if there is no initializer property on this schedule
247
		if ( ! isset( $this->schedulable_classes[ $schedule_name ]['initializer'] ) ) {
248
			return;
249
		}
250
251
		// cancel previous task
252
		$this->queue->cancel(
253
			$this->schedulable_classes[ $schedule_name ]['initializer'],
254
			array(),
255
			$action_group_name
256
		);
257
258
		// create new recurring task for action-scheduler to check for data to pull from salesforce
259
		$this->queue->schedule_recurring(
260
			current_time( 'timestamp', true ), // plugin seems to expect UTC
261
			$this->queue->get_frequency( $schedule_name, 'seconds' ),
262
			$this->schedulable_classes[ $schedule_name ]['initializer'],
263
			array(),
264
			$action_group_name
265
		);
266
	}
267
268
	/**
269
	* Create WordPress admin options page
270
	*
271
	*/
272
	public function create_admin_menu() {
273
		$title = __( 'Salesforce', 'object-sync-for-salesforce' );
274
		add_options_page( $title, $title, 'configure_salesforce', 'object-sync-salesforce-admin', array( $this, 'show_admin_page' ) );
275
	}
276
277
	/**
278
	* Render full admin pages in WordPress
279
	* This allows other plugins to add tabs to the Salesforce settings screen
280
	*
281
	* todo: better front end: html, organization of html into templates, css, js
282
	*
283
	*/
284
	public function show_admin_page() {
285
		$get_data = filter_input_array( INPUT_GET, FILTER_SANITIZE_STRING );
286
		echo '<div class="wrap">';
287
		echo '<h1>' . esc_html( get_admin_page_title() ) . '</h1>';
288
		$allowed = $this->check_wordpress_admin_permissions();
289
		if ( false === $allowed ) {
290
			return;
291
		}
292
		$tabs = array(
293
			'settings'      => __( 'Settings', 'object-sync-for-salesforce' ),
294
			'authorize'     => __( 'Authorize', 'object-sync-for-salesforce' ),
295
			'fieldmaps'     => __( 'Fieldmaps', 'object-sync-for-salesforce' ),
296
			'schedule'      => __( 'Scheduling', 'object-sync-for-salesforce' ),
297
			'import-export' => __( 'Import &amp; Export', 'object-sync-for-salesforce' ),
298
		); // this creates the tabs for the admin
299
300
		// optionally make tab(s) for logging and log settings
301
		$logging_enabled      = get_option( $this->option_prefix . 'enable_logging', false );
302
		$tabs['log_settings'] = __( 'Log Settings', 'object-sync-for-salesforce' );
303
304
		$mapping_errors = $this->mappings->get_failed_object_maps();
305
		if ( ! empty( $mapping_errors ) ) {
306
			$tabs['mapping_errors'] = __( 'Mapping Errors', 'object-sync-for-salesforce' );
307
		}
308
309
		// filter for extending the tabs available on the page
310
		// currently it will go into the default switch case for $tab
311
		$tabs = apply_filters( $this->option_prefix . 'settings_tabs', $tabs );
312
313
		$tab = isset( $get_data['tab'] ) ? sanitize_key( $get_data['tab'] ) : 'settings';
314
		$this->tabs( $tabs, $tab );
315
316
		$consumer_key    = $this->login_credentials['consumer_key'];
317
		$consumer_secret = $this->login_credentials['consumer_secret'];
318
		$callback_url    = $this->login_credentials['callback_url'];
319
320
		if ( true !== $this->salesforce['is_authorized'] ) {
321
			$url     = esc_url( $callback_url );
322
			$anchor  = esc_html__( 'Authorize tab', 'object-sync-for-salesforce' );
323
			$message = sprintf( 'Salesforce needs to be authorized to connect to this website. Use the <a href="%s">%s</a> to connect.', $url, $anchor );
324
			require( plugin_dir_path( __FILE__ ) . '/../templates/admin/error.php' );
325
		}
326
327 View Code Duplication
		if ( 0 === count( $this->mappings->get_fieldmaps() ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
328
			$url     = esc_url( get_admin_url( null, 'options-general.php?page=object-sync-salesforce-admin&tab=fieldmaps' ) );
329
			$anchor  = esc_html__( 'Fieldmaps tab', 'object-sync-for-salesforce' );
330
			$message = sprintf( 'No fieldmaps exist yet. Use the <a href="%s">%s</a> to map WordPress and Salesforce objects to each other.', $url, $anchor );
331
			require( plugin_dir_path( __FILE__ ) . '/../templates/admin/error.php' );
332
		}
333
334
		try {
335
			switch ( $tab ) {
336
				case 'authorize':
337
					if ( isset( $get_data['code'] ) ) {
338
						// this string is an oauth token
339
						$data          = esc_html( wp_unslash( $get_data['code'] ) );
340
						$is_authorized = $this->salesforce['sfapi']->request_token( $data );
0 ignored issues
show
Unused Code introduced by
$is_authorized is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
341
						?>
342
						<script>window.location = '<?php echo esc_url_raw( $callback_url ); ?>'</script>
343
						<?php
344
					} elseif ( true === $this->salesforce['is_authorized'] ) {
345
							require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/authorized.php' );
346
							$this->status( $this->salesforce['sfapi'] );
347
					} elseif ( true === is_object( $this->salesforce['sfapi'] ) && isset( $consumer_key ) && isset( $consumer_secret ) ) {
348
						?>
349
						<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>
350
						<?php
351 View Code Duplication
					} else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
352
						$url    = esc_url( get_admin_url( null, 'options-general.php?page=object-sync-salesforce-admin&tab=settings' ) );
353
						$anchor = esc_html__( 'Settings', 'object-sync-for-salesforce' );
354
						// translators: placeholders are for the settings tab link: 1) the url, and 2) the anchor text
355
						$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-salesforce' ), $url, $anchor );
0 ignored issues
show
Unused Code introduced by
$message is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
356
						require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/error.php' );
357
					}
358
					break;
359
				case 'fieldmaps':
360
					if ( isset( $get_data['method'] ) ) {
361
362
						$method      = sanitize_key( $get_data['method'] );
363
						$error_url   = get_admin_url( null, 'options-general.php?page=object-sync-salesforce-admin&tab=fieldmaps&method=' . $method );
0 ignored issues
show
Unused Code introduced by
$error_url is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
364
						$success_url = get_admin_url( null, 'options-general.php?page=object-sync-salesforce-admin&tab=fieldmaps' );
0 ignored issues
show
Unused Code introduced by
$success_url is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
365
366 View Code Duplication
						if ( isset( $get_data['transient'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
367
							$transient = sanitize_key( $get_data['transient'] );
368
							$posted    = $this->sfwp_transients->get( $transient );
369
						}
370
371 View Code Duplication
						if ( isset( $posted ) && is_array( $posted ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
372
							$map = $posted;
373
						} elseif ( 'edit' === $method || 'clone' === $method || 'delete' === $method ) {
374
							$map = $this->mappings->get_fieldmaps( isset( $get_data['id'] ) ? sanitize_key( $get_data['id'] ) : '' );
375
						}
376
377
						if ( isset( $map ) && is_array( $map ) ) {
378
							$label                           = $map['label'];
0 ignored issues
show
Unused Code introduced by
$label is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
379
							$salesforce_object               = $map['salesforce_object'];
0 ignored issues
show
Unused Code introduced by
$salesforce_object is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
380
							$salesforce_record_types_allowed = maybe_unserialize( $map['salesforce_record_types_allowed'] );
0 ignored issues
show
Unused Code introduced by
$salesforce_record_types_allowed is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
381
							$salesforce_record_type_default  = $map['salesforce_record_type_default'];
0 ignored issues
show
Unused Code introduced by
$salesforce_record_type_default is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
382
							$wordpress_object                = $map['wordpress_object'];
0 ignored issues
show
Unused Code introduced by
$wordpress_object is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
383
							$pull_trigger_field              = $map['pull_trigger_field'];
0 ignored issues
show
Unused Code introduced by
$pull_trigger_field is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
384
							$fieldmap_fields                 = $map['fields'];
0 ignored issues
show
Unused Code introduced by
$fieldmap_fields is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
385
							$sync_triggers                   = $map['sync_triggers'];
0 ignored issues
show
Unused Code introduced by
$sync_triggers is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
386
							$push_async                      = $map['push_async'];
0 ignored issues
show
Unused Code introduced by
$push_async is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
387
							$push_drafts                     = $map['push_drafts'];
0 ignored issues
show
Unused Code introduced by
$push_drafts is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
388
							$pull_to_drafts                  = $map['pull_to_drafts'];
0 ignored issues
show
Unused Code introduced by
$pull_to_drafts is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
389
							$weight                          = $map['weight'];
0 ignored issues
show
Unused Code introduced by
$weight is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
390
						}
391
392
						if ( 'add' === $method || 'edit' === $method || 'clone' === $method ) {
393
							require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/fieldmaps-add-edit-clone.php' );
394
						} elseif ( 'delete' === $method ) {
395
							require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/fieldmaps-delete.php' );
396
						}
397
					} else {
398
						$fieldmaps = $this->mappings->get_fieldmaps();
0 ignored issues
show
Unused Code introduced by
$fieldmaps is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
399
						require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/fieldmaps-list.php' );
400
					} // End if().
401
					break;
402
				case 'logout':
403
					$this->logout();
404
					break;
405
				case 'clear_cache':
406
					$this->clear_cache();
407
					break;
408
				case 'clear_schedule':
409
					if ( isset( $get_data['schedule_name'] ) ) {
410
						$schedule_name = sanitize_key( $get_data['schedule_name'] );
411
					}
412
					$this->clear_schedule( $schedule_name );
413
					break;
414
				case 'settings':
415
					require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/settings.php' );
416
					break;
417
				case 'mapping_errors':
418
					if ( isset( $get_data['method'] ) ) {
419
420
						$method      = sanitize_key( $get_data['method'] );
421
						$error_url   = get_admin_url( null, 'options-general.php?page=object-sync-salesforce-admin&tab=mapping_errors&method=' . $method );
0 ignored issues
show
Unused Code introduced by
$error_url is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
422
						$success_url = get_admin_url( null, 'options-general.php?page=object-sync-salesforce-admin&tab=mapping_errors' );
0 ignored issues
show
Unused Code introduced by
$success_url is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
423
424 View Code Duplication
						if ( isset( $get_data['map_transient'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
425
							$transient = sanitize_key( $get_data['map_transient'] );
426
							$posted    = $this->sfwp_transients->get( $transient );
427
						}
428
429 View Code Duplication
						if ( isset( $posted ) && is_array( $posted ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
430
							$map_row = $posted;
431
						} elseif ( 'edit' === $method || 'delete' === $method ) {
432
							$map_row = $this->mappings->get_failed_object_map( isset( $get_data['id'] ) ? sanitize_key( $get_data['id'] ) : '' );
433
						}
434
435
						if ( isset( $map_row ) && is_array( $map_row ) ) {
436
							$salesforce_id = $map_row['salesforce_id'];
0 ignored issues
show
Unused Code introduced by
$salesforce_id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
437
							$wordpress_id  = $map_row['wordpress_id'];
0 ignored issues
show
Unused Code introduced by
$wordpress_id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
438
						}
439
440
						if ( 'edit' === $method ) {
441
							require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/mapping-errors-edit.php' );
442
						} elseif ( 'delete' === $method ) {
443
							require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/mapping-errors-delete.php' );
444
						}
445
					} else {
446
447 View Code Duplication
						if ( isset( $get_data['mapping_error_transient'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
448
							$transient = sanitize_key( $get_data['mapping_error_transient'] );
449
							$posted    = $this->sfwp_transients->get( $transient );
450
						}
451
452
						$ids_string = '';
453
						$ids        = array();
0 ignored issues
show
Unused Code introduced by
$ids is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
454
						if ( isset( $posted['delete'] ) ) {
455
							$ids_string = maybe_serialize( $posted['delete'] );
456
							$ids        = $posted['delete'];
0 ignored issues
show
Unused Code introduced by
$ids is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
457
						}
458
459
						$error_url   = get_admin_url( null, 'options-general.php?page=object-sync-salesforce-admin&tab=mapping_errors&ids=' . $ids_string );
0 ignored issues
show
Unused Code introduced by
$error_url is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
460
						$success_url = get_admin_url( null, 'options-general.php?page=object-sync-salesforce-admin&tab=mapping_errors' );
0 ignored issues
show
Unused Code introduced by
$success_url is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
461
						require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/mapping-errors.php' );
462
					}
463
					break;
464
				case 'import-export':
465
					require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/import-export.php' );
466
					break;
467
				default:
468
					$include_settings = apply_filters( $this->option_prefix . 'settings_tab_include_settings', true, $tab );
469
					$content_before   = apply_filters( $this->option_prefix . 'settings_tab_content_before', null, $tab );
470
					$content_after    = apply_filters( $this->option_prefix . 'settings_tab_content_after', null, $tab );
471
					if ( null !== $content_before ) {
472
						echo esc_html( $content_before );
473
					}
474
					if ( true === $include_settings ) {
475
						require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/settings.php' );
476
					}
477
					if ( null !== $content_after ) {
478
						echo esc_html( $content_after );
479
					}
480
					break;
481
			} // End switch().
482
		} catch ( SalesforceApiException $ex ) {
0 ignored issues
show
Bug introduced by
The class SalesforceApiException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
483
			echo sprintf( '<p>Error <strong>%1$s</strong>: %2$s</p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
484
				absint( $ex->getCode() ),
485
				esc_html( $ex->getMessage() )
486
			);
487
		} catch ( Exception $ex ) {
488
			echo sprintf( '<p>Error <strong>%1$s</strong>: %2$s</p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
489
				absint( $ex->getCode() ),
490
				esc_html( $ex->getMessage() )
491
			);
492
		} // End try().
493
		echo '</div>';
494
	}
495
496
	/**
497
	* Create default WordPress admin settings form for salesforce
498
	* This is for the Settings page/tab
499
	*
500
	*/
501
	public function salesforce_settings_forms() {
502
		$get_data = filter_input_array( INPUT_GET, FILTER_SANITIZE_STRING );
503
		$page     = isset( $get_data['tab'] ) ? sanitize_key( $get_data['tab'] ) : 'settings';
0 ignored issues
show
Unused Code introduced by
$page is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
504
		$section  = isset( $get_data['tab'] ) ? sanitize_key( $get_data['tab'] ) : 'settings';
0 ignored issues
show
Unused Code introduced by
$section is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
505
506
		$input_callback_default   = array( $this, 'display_input_field' );
507
		$input_checkboxes_default = array( $this, 'display_checkboxes' );
508
		$input_select_default     = array( $this, 'display_select' );
509
		$link_default             = array( $this, 'display_link' );
510
511
		$all_field_callbacks = array(
512
			'text'       => $input_callback_default,
513
			'checkboxes' => $input_checkboxes_default,
514
			'select'     => $input_select_default,
515
			'link'       => $link_default,
516
		);
517
518
		$this->fields_settings( 'settings', 'settings', $all_field_callbacks );
519
		$this->fields_fieldmaps( 'fieldmaps', 'objects' );
520
		$this->fields_scheduling( 'schedule', 'schedule', $all_field_callbacks );
521
		$this->fields_log_settings( 'log_settings', 'log_settings', $all_field_callbacks );
522
	}
523
524
	/**
525
	* Fields for the Settings tab
526
	* This runs add_settings_section once, as well as add_settings_field and register_setting methods for each option
527
	*
528
	* @param string $page
529
	* @param string $section
530
	* @param string $input_callback
0 ignored issues
show
Bug introduced by
There is no parameter named $input_callback. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
531
	*/
532
	private function fields_settings( $page, $section, $callbacks ) {
533
		add_settings_section( $page, ucwords( $page ), null, $page );
534
		$salesforce_settings = array(
535
			'consumer_key'                   => array(
536
				'title'    => __( 'Consumer Key', 'object-sync-for-salesforce' ),
537
				'callback' => $callbacks['text'],
538
				'page'     => $page,
539
				'section'  => $section,
540
				'args'     => array(
541
					'type'     => 'text',
542
					'validate' => 'sanitize_validate_text',
543
					'desc'     => '',
544
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_CONSUMER_KEY',
545
				),
546
547
			),
548
			'consumer_secret'                => array(
549
				'title'    => __( 'Consumer Secret', 'object-sync-for-salesforce' ),
550
				'callback' => $callbacks['text'],
551
				'page'     => $page,
552
				'section'  => $section,
553
				'args'     => array(
554
					'type'     => 'text',
555
					'validate' => 'sanitize_validate_text',
556
					'desc'     => '',
557
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_CONSUMER_SECRET',
558
				),
559
			),
560
			'callback_url'                   => array(
561
				'title'    => __( 'Callback URL', 'object-sync-for-salesforce' ),
562
				'callback' => $callbacks['text'],
563
				'page'     => $page,
564
				'section'  => $section,
565
				'args'     => array(
566
					'type'     => 'url',
567
					'validate' => 'sanitize_validate_text',
568
					// translators: %1$s is the admin URL for the Authorize tab
569
					'desc'     => sprintf( __( 'In most cases, you will want to use %1$s for this value.', 'object-sync-for-salesforce' ),
570
						get_admin_url( null, 'options-general.php?page=object-sync-salesforce-admin&tab=authorize' )
571
					),
572
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_CALLBACK_URL',
573
				),
574
			),
575
			'login_base_url'                 => array(
576
				'title'    => __( 'Login Base URL', 'object-sync-for-salesforce' ),
577
				'callback' => $callbacks['text'],
578
				'page'     => $page,
579
				'section'  => $section,
580
				'args'     => array(
581
					'type'     => 'url',
582
					'validate' => 'sanitize_validate_text',
583
					// translators: 1) production salesforce login, 2) sandbox salesforce login
584
					'desc'     => sprintf( __( 'For most Salesforce setups, you should use %1$s for production and %2$s for sandbox.', 'object-sync-for-salesforce' ),
585
						esc_url( 'https://login.salesforce.com' ),
586
						esc_url( 'https://test.salesforce.com' )
587
					),
588
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_LOGIN_BASE_URL',
589
				),
590
			),
591
			'authorize_url_path'             => array(
592
				'title'    => __( 'Authorize URL Path', 'object-sync-for-salesforce' ),
593
				'callback' => $callbacks['text'],
594
				'page'     => $page,
595
				'section'  => $section,
596
				'args'     => array(
597
					'type'     => 'text',
598
					'validate' => 'sanitize_validate_text',
599
					'desc'     => __( 'For most Salesforce installs, this should not be changed.', 'object-sync-for-salesforce' ),
600
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_AUTHORIZE_URL_PATH',
601
					'default'  => $this->default_authorize_url_path,
602
				),
603
			),
604
			'token_url_path'                 => array(
605
				'title'    => 'Token URL Path',
606
				'callback' => $callbacks['text'],
607
				'page'     => $page,
608
				'section'  => $section,
609
				'args'     => array(
610
					'type'     => 'text',
611
					'validate' => 'sanitize_validate_text',
612
					'desc'     => __( 'For most Salesforce installs, this should not be changed.', 'object-sync-for-salesforce' ),
613
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_TOKEN_URL_PATH',
614
					'default'  => $this->default_token_url_path,
615
				),
616
			),
617
			'api_version'                    => array(
618
				'title'    => 'Salesforce API Version',
619
				'callback' => $callbacks['text'],
620
				'page'     => $page,
621
				'section'  => $section,
622
				'args'     => array(
623
					'type'     => 'text',
624
					'validate' => 'sanitize_validate_text',
625
					'desc'     => '',
626
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_API_VERSION',
627
					'default'  => $this->default_api_version,
628
				),
629
			),
630
			'object_filters'                 => array(
631
				'title'    => 'Limit Salesforce Objects',
632
				'callback' => $callbacks['checkboxes'],
633
				'page'     => $page,
634
				'section'  => $section,
635
				'args'     => array(
636
					'type'     => 'checkboxes',
637
					'validate' => 'sanitize_validate_text',
638
					'desc'     => __( 'Allows you to limit which Salesforce objects can be mapped', 'object-sync-for-salesforce' ),
639
					'items'    => array(
640
						'triggerable' => array(
641
							'text'    => 'Only Triggerable objects',
642
							'id'      => 'triggerable',
643
							'desc'    => '',
644
							'default' => $this->default_triggerable,
645
						),
646
						'updateable'  => array(
647
							'text'    => 'Only Updateable objects',
648
							'id'      => 'updateable',
649
							'desc'    => '',
650
							'default' => $this->default_updateable,
651
						),
652
					),
653
				),
654
			),
655
			'salesforce_field_display_value' => array(
656
				'title'    => 'Salesforce Field Display Value',
657
				'callback' => $callbacks['select'],
658
				'page'     => $page,
659
				'section'  => $section,
660
				'args'     => array(
661
					'type'     => 'select',
662
					'validate' => 'sanitize_validate_text',
663
					'desc'     => 'When choosing Salesforce fields to map, this value determines how the dropdown will identify Salesforce fields.',
664
					'constant' => '',
665
					'items'    => array(
666
						'field_label' => array(
667
							'text'  => __( 'Field Label', 'object-sync-for-salesforce' ),
668
							'value' => 'field_label',
669
						),
670
						/*'field_name'  => array(
671
							'text'  => __( 'Field Name', 'object-sync-for-salesforce' ),
672
							'value' => 'field_name',
673
						),*/
674
						'api_name'    => array(
675
							'text'  => __( 'API Name', 'object-sync-for-salesforce' ),
676
							'value' => 'api_name',
677
						),
678
					),
679
				),
680
			),
681
			'pull_query_limit'               => array(
682
				'title'    => 'Pull query record limit',
683
				'callback' => $callbacks['text'],
684
				'page'     => $page,
685
				'section'  => $section,
686
				'args'     => array(
687
					'type'     => 'number',
688
					'validate' => 'absint',
689
					'desc'     => __( 'Limit the number of records that can be pulled from Salesforce in a single query.', 'object-sync-for-salesforce' ),
690
					'constant' => '',
691
					'default'  => $this->default_pull_limit,
692
				),
693
			),
694
			'pull_throttle'                  => array(
695
				'title'    => 'Pull throttle (seconds)',
696
				'callback' => $callbacks['text'],
697
				'page'     => $page,
698
				'section'  => $section,
699
				'args'     => array(
700
					'type'     => 'number',
701
					'validate' => 'sanitize_validate_text',
702
					'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' ),
703
					'constant' => '',
704
					'default'  => $this->default_pull_throttle,
705
				),
706
			),
707
			'debug_mode'                     => array(
708
				'title'    => 'Debug mode?',
709
				'callback' => $callbacks['text'],
710
				'page'     => $page,
711
				'section'  => $section,
712
				'args'     => array(
713
					'type'     => 'checkbox',
714
					'validate' => 'sanitize_validate_text',
715
					'desc'     => __( 'Debug mode can, combined with the Log Settings, log things like Salesforce API requests. It can create a lot of entries if enabled; it is not recommended to use it in a production environment.', 'object-sync-for-salesforce' ),
716
					'constant' => '',
717
				),
718
			),
719
			'delete_data_on_uninstall'       => array(
720
				'title'    => 'Delete plugin data on uninstall?',
721
				'callback' => $callbacks['text'],
722
				'page'     => $page,
723
				'section'  => $section,
724
				'args'     => array(
725
					'type'     => 'checkbox',
726
					'validate' => 'sanitize_validate_text',
727
					'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' ),
728
					'constant' => '',
729
				),
730
			),
731
		);
732
733
		if ( true === is_object( $this->salesforce['sfapi'] ) && true === $this->salesforce['sfapi']->is_authorized() ) {
734
			$salesforce_settings['api_version'] = array(
735
				'title'    => 'Salesforce API Version',
736
				'callback' => $callbacks['select'],
737
				'page'     => $page,
738
				'section'  => $section,
739
				'args'     => array(
740
					'type'     => 'select',
741
					'validate' => 'sanitize_validate_text',
742
					'desc'     => '',
743
					'constant' => 'OBJECT_SYNC_SF_SALESFORCE_API_VERSION',
744
					'items'    => $this->version_options(),
745
				),
746
			);
747
		}
748
749
		foreach ( $salesforce_settings as $key => $attributes ) {
750
			$id       = $this->option_prefix . $key;
751
			$name     = $this->option_prefix . $key;
752
			$title    = $attributes['title'];
753
			$callback = $attributes['callback'];
754
			$validate = $attributes['args']['validate'];
755
			$page     = $attributes['page'];
756
			$section  = $attributes['section'];
757
			$args     = array_merge(
758
				$attributes['args'],
759
				array(
760
					'title'     => $title,
761
					'id'        => $id,
762
					'label_for' => $id,
763
					'name'      => $name,
764
				)
765
			);
766
767
			// if there is a constant and it is defined, don't run a validate function
768
			if ( isset( $attributes['args']['constant'] ) && defined( $attributes['args']['constant'] ) ) {
769
				$validate = '';
770
			}
771
772
			add_settings_field( $id, $title, $callback, $page, $section, $args );
773
			register_setting( $page, $id, array( $this, $validate ) );
774
		}
775
	}
776
777
	/**
778
	* Fields for the Fieldmaps tab
779
	* This runs add_settings_section once, as well as add_settings_field and register_setting methods for each option
780
	*
781
	* @param string $page
782
	* @param string $section
783
	* @param string $input_callback
784
	*/
785
	private function fields_fieldmaps( $page, $section, $input_callback = '' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $section is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $input_callback is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
786
		add_settings_section( $page, ucwords( $page ), null, $page );
787
	}
788
789
	/**
790
	* Fields for the Scheduling 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
794
	* @param string $section
795
	* @param string $input_callback
0 ignored issues
show
Bug introduced by
There is no parameter named $input_callback. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
796
	*/
797
	private function fields_scheduling( $page, $section, $callbacks ) {
0 ignored issues
show
Unused Code introduced by
The parameter $section is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
798
799
		add_settings_section( 'batch', __( 'Batch Settings', 'object-sync-for-salesforce' ), null, $page );
800
		$section           = 'batch';
801
		$schedule_settings = array(
802
			'action_scheduler_batch_size'         => array(
803
				'title'    => __( 'Batch size', 'object-sync-for-salesforce' ),
804
				'callback' => $callbacks['text'],
805
				'page'     => $page,
806
				'section'  => $section,
807
				'args'     => array(
808
					'type'     => 'number',
809
					'validate' => 'absint',
810
					'default'  => 5,
811
					'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' ),
812
					'constant' => '',
813
				),
814
815
			),
816
			'action_scheduler_concurrent_batches' => array(
817
				'title'    => __( 'Concurrent batches', 'object-sync-for-salesforce' ),
818
				'callback' => $callbacks['text'],
819
				'page'     => $page,
820
				'section'  => $section,
821
				'args'     => array(
822
					'type'     => 'number',
823
					'validate' => 'absint',
824
					'default'  => 3,
825
					'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' ),
826
					'constant' => '',
827
				),
828
			),
829
		);
830
831
		foreach ( $this->schedulable_classes as $key => $value ) {
832
			add_settings_section( $key, $value['label'], null, $page );
833
			if ( isset( $value['initializer'] ) ) {
834
				$schedule_settings[ $key . '_schedule_number' ] = array(
835
					'title'    => __( 'Run schedule every', 'object-sync-for-salesforce' ),
836
					'callback' => $callbacks['text'],
837
					'page'     => $page,
838
					'section'  => $key,
839
					'args'     => array(
840
						'type'     => 'number',
841
						'validate' => 'absint',
842
						'desc'     => '',
843
						'constant' => '',
844
					),
845
				);
846
				$schedule_settings[ $key . '_schedule_unit' ]   = array(
847
					'title'    => __( 'Time unit', 'object-sync-for-salesforce' ),
848
					'callback' => $callbacks['select'],
849
					'page'     => $page,
850
					'section'  => $key,
851
					'args'     => array(
852
						'type'     => 'select',
853
						'validate' => 'sanitize_validate_text',
854
						'desc'     => '',
855
						'items'    => array(
856
							'minutes' => array(
857
								'text'  => __( 'Minutes', 'object-sync-for-salesforce' ),
858
								'value' => 'minutes',
859
							),
860
							'hours'   => array(
861
								'text'  => __( 'Hours', 'object-sync-for-salesforce' ),
862
								'value' => 'hours',
863
							),
864
							'days'    => array(
865
								'text'  => __( 'Days', 'object-sync-for-salesforce' ),
866
								'value' => 'days',
867
							),
868
						),
869
					),
870
				);
871
			}
872
			$schedule_settings[ $key . '_clear_button' ] = array(
873
				// translators: $this->get_schedule_count is an integer showing how many items are in the current queue
874
				'title'    => sprintf( 'This queue has ' . _n( '%s item', '%s items', $this->get_schedule_count( $key ), 'object-sync-for-salesforce' ), $this->get_schedule_count( $key ) ),
875
				'callback' => $callbacks['link'],
876
				'page'     => $page,
877
				'section'  => $key,
878
				'args'     => array(
879
					'label'      => __( 'Clear this queue', 'object-sync-for-salesforce' ),
880
					'desc'       => '',
881
					'url'        => esc_url( '?page=object-sync-salesforce-admin&amp;tab=clear_schedule&amp;schedule_name=' . $key ),
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$key'
Loading history...
882
					'link_class' => 'button button-secondary',
883
				),
884
			);
885 View Code Duplication
			foreach ( $schedule_settings as $key => $attributes ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
886
				$id       = $this->option_prefix . $key;
887
				$name     = $this->option_prefix . $key;
888
				$title    = $attributes['title'];
889
				$callback = $attributes['callback'];
890
				$page     = $attributes['page'];
891
				$section  = $attributes['section'];
892
				$args     = array_merge(
893
					$attributes['args'],
894
					array(
895
						'title'     => $title,
896
						'id'        => $id,
897
						'label_for' => $id,
898
						'name'      => $name,
899
					)
900
				);
901
				add_settings_field( $id, $title, $callback, $page, $section, $args );
902
				register_setting( $page, $id );
903
			}
904
		} // End foreach().
905
	}
906
907
	/**
908
	* Fields for the Log Settings tab
909
	* This runs add_settings_section once, as well as add_settings_field and register_setting methods for each option
910
	*
911
	* @param string $page
912
	* @param string $section
913
	* @param array $callbacks
914
	*/
915
	private function fields_log_settings( $page, $section, $callbacks ) {
916
		add_settings_section( $page, ucwords( str_replace( '_', ' ', $page ) ), null, $page );
917
		$log_settings = array(
918
			'enable_logging'        => array(
919
				'title'    => __( 'Enable Logging?', 'object-sync-for-salesforce' ),
920
				'callback' => $callbacks['text'],
921
				'page'     => $page,
922
				'section'  => $section,
923
				'args'     => array(
924
					'type'     => 'checkbox',
925
					'validate' => 'absint',
926
					'desc'     => '',
927
					'constant' => '',
928
				),
929
			),
930
			'statuses_to_log'       => array(
931
				'title'    => __( 'Statuses to log', 'object-sync-for-salesforce' ),
932
				'callback' => $callbacks['checkboxes'],
933
				'page'     => $page,
934
				'section'  => $section,
935
				'args'     => array(
936
					'type'     => 'checkboxes',
937
					'validate' => 'sanitize_validate_text',
938
					'desc'     => __( 'these are the statuses to log', 'object-sync-for-salesforce' ),
939
					'items'    => array(
940
						'error'   => array(
941
							'text' => __( 'Error', 'object-sync-for-salesforce' ),
942
							'id'   => 'error',
943
							'desc' => '',
944
						),
945
						'success' => array(
946
							'text' => __( 'Success', 'object-sync-for-salesforce' ),
947
							'id'   => 'success',
948
							'desc' => '',
949
						),
950
						'notice'  => array(
951
							'text' => __( 'Notice', 'object-sync-for-salesforce' ),
952
							'id'   => 'notice',
953
							'desc' => '',
954
						),
955
						'debug'   => array(
956
							'text' => __( 'Debug', 'object-sync-for-salesforce' ),
957
							'id'   => 'debug',
958
							'desc' => '',
959
						),
960
					),
961
				),
962
			),
963
			'prune_logs'            => array(
964
				'title'    => __( 'Automatically delete old log entries?', 'object-sync-for-salesforce' ),
965
				'callback' => $callbacks['text'],
966
				'page'     => $page,
967
				'section'  => $section,
968
				'args'     => array(
969
					'type'     => 'checkbox',
970
					'validate' => 'absint',
971
					'desc'     => '',
972
					'constant' => '',
973
				),
974
			),
975
			'logs_how_old'          => array(
976
				'title'    => __( 'Age to delete log entries', 'object-sync-for-salesforce' ),
977
				'callback' => $callbacks['text'],
978
				'page'     => $page,
979
				'section'  => $section,
980
				'args'     => array(
981
					'type'     => 'text',
982
					'validate' => 'sanitize_validate_text',
983
					'desc'     => __( 'If automatic deleting is enabled, it will affect logs this old.', 'object-sync-for-salesforce' ),
984
					'default'  => '2 weeks',
985
					'constant' => '',
986
				),
987
			),
988
			'logs_how_often_number' => array(
989
				'title'    => __( 'Check for old logs every', 'object-sync-for-salesforce' ),
990
				'callback' => $callbacks['text'],
991
				'page'     => $page,
992
				'section'  => $section,
993
				'args'     => array(
994
					'type'     => 'number',
995
					'validate' => 'absint',
996
					'desc'     => '',
997
					'default'  => '1',
998
					'constant' => '',
999
				),
1000
			),
1001
			'logs_how_often_unit'   => array(
1002
				'title'    => __( 'Time unit', 'object-sync-for-salesforce' ),
1003
				'callback' => $callbacks['select'],
1004
				'page'     => $page,
1005
				'section'  => $section,
1006
				'args'     => array(
1007
					'type'     => 'select',
1008
					'validate' => 'sanitize_validate_text',
1009
					'desc'     => __( 'These two fields are how often the site will check for logs to delete.', 'object-sync-for-salesforce' ),
1010
					'items'    => array(
1011
						'minutes' => array(
1012
							'text'  => __( 'Minutes', 'object-sync-for-salesforce' ),
1013
							'value' => 'minutes',
1014
						),
1015
						'hours'   => array(
1016
							'text'  => __( 'Hours', 'object-sync-for-salesforce' ),
1017
							'value' => 'hours',
1018
						),
1019
						'days'    => array(
1020
							'text'  => __( 'Days', 'object-sync-for-salesforce' ),
1021
							'value' => 'days',
1022
						),
1023
					),
1024
				),
1025
			),
1026
			'triggers_to_log'       => array(
1027
				'title'    => __( 'Triggers to log', 'object-sync-for-salesforce' ),
1028
				'callback' => $callbacks['checkboxes'],
1029
				'page'     => $page,
1030
				'section'  => $section,
1031
				'args'     => array(
1032
					'type'     => 'checkboxes',
1033
					'validate' => 'sanitize_validate_text',
1034
					'desc'     => __( 'these are the triggers to log', 'object-sync-for-salesforce' ),
1035
					'items'    => array(
1036
						$this->mappings->sync_wordpress_create => array(
1037
							'text' => __( 'WordPress create', 'object-sync-for-salesforce' ),
1038
							'id'   => 'wordpress_create',
1039
							'desc' => '',
1040
						),
1041
						$this->mappings->sync_wordpress_update => array(
1042
							'text' => __( 'WordPress update', 'object-sync-for-salesforce' ),
1043
							'id'   => 'wordpress_update',
1044
							'desc' => '',
1045
						),
1046
						$this->mappings->sync_wordpress_delete => array(
1047
							'text' => __( 'WordPress delete', 'object-sync-for-salesforce' ),
1048
							'id'   => 'wordpress_delete',
1049
							'desc' => '',
1050
						),
1051
						$this->mappings->sync_sf_create => array(
1052
							'text' => __( 'Salesforce create', 'object-sync-for-salesforce' ),
1053
							'id'   => 'sf_create',
1054
							'desc' => '',
1055
						),
1056
						$this->mappings->sync_sf_update => array(
1057
							'text' => __( 'Salesforce update', 'object-sync-for-salesforce' ),
1058
							'id'   => 'sf_update',
1059
							'desc' => '',
1060
						),
1061
						$this->mappings->sync_sf_delete => array(
1062
							'text' => __( 'Salesforce delete', 'object-sync-for-salesforce' ),
1063
							'id'   => 'sf_delete',
1064
							'desc' => '',
1065
						),
1066
					),
1067
				),
1068
			),
1069
		);
1070 View Code Duplication
		foreach ( $log_settings as $key => $attributes ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1071
			$id       = $this->option_prefix . $key;
1072
			$name     = $this->option_prefix . $key;
1073
			$title    = $attributes['title'];
1074
			$callback = $attributes['callback'];
1075
			$page     = $attributes['page'];
1076
			$section  = $attributes['section'];
1077
			$args     = array_merge(
1078
				$attributes['args'],
1079
				array(
1080
					'title'     => $title,
1081
					'id'        => $id,
1082
					'label_for' => $id,
1083
					'name'      => $name,
1084
				)
1085
			);
1086
			add_settings_field( $id, $title, $callback, $page, $section, $args );
1087
			register_setting( $page, $id );
1088
		}
1089
	}
1090
1091
	/**
1092
	* Create the notices, settings, and conditions by which admin notices should appear
1093
	*
1094
	*/
1095
	public function notices() {
1096
1097
		// before a notice is displayed, we should make sure we are on a page related to this plugin
1098
		if ( ! isset( $_GET['page'] ) || 'object-sync-salesforce-admin' !== $_GET['page'] ) {
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
1099
			return;
1100
		}
1101
1102
		$get_data = filter_input_array( INPUT_GET, FILTER_SANITIZE_STRING );
1103
		require_once plugin_dir_path( __FILE__ ) . '../classes/admin-notice.php';
1104
1105
		$notices = array(
1106
			'permission'              => array(
1107
				'condition'   => false === $this->check_wordpress_admin_permissions(),
1108
				'message'     => __( "Your account does not have permission to edit the Salesforce REST API plugin's settings.", 'object-sync-for-salesforce' ),
1109
				'type'        => 'error',
1110
				'dismissible' => false,
1111
			),
1112
			'fieldmap'                => array(
1113
				'condition'   => isset( $get_data['transient'] ),
1114
				'message'     => __( 'Errors kept this fieldmap from being saved.', 'object-sync-for-salesforce' ),
1115
				'type'        => 'error',
1116
				'dismissible' => true,
1117
			),
1118
			'object_map'              => array(
1119
				'condition'   => isset( $get_data['map_transient'] ),
1120
				'message'     => __( 'Errors kept this object map from being saved.', 'object-sync-for-salesforce' ),
1121
				'type'        => 'error',
1122
				'dismissible' => true,
1123
			),
1124
			'data_saved'              => array(
1125
				'condition'   => isset( $get_data['data_saved'] ) && 'true' === $get_data['data_saved'],
1126
				'message'     => __( 'This data was successfully saved.', 'object-sync-for-salesforce' ),
1127
				'type'        => 'success',
1128
				'dismissible' => true,
1129
			),
1130
			'data_save_error'         => array(
1131
				'condition'   => isset( $get_data['data_saved'] ) && 'false' === $get_data['data_saved'],
1132
				'message'     => __( 'This data was not successfully saved. Try again.', 'object-sync-for-salesforce' ),
1133
				'type'        => 'error',
1134
				'dismissible' => true,
1135
			),
1136
			'mapping_error_transient' => array(
1137
				'condition'   => isset( $get_data['mapping_error_transient'] ),
1138
				'message'     => __( 'Errors kept these mapping errors from being deleted.', 'object-sync-for-salesforce' ),
1139
				'type'        => 'error',
1140
				'dismissible' => true,
1141
			),
1142
		);
1143
1144
		foreach ( $notices as $key => $value ) {
1145
1146
			$condition = $value['condition'];
1147
			$message   = $value['message'];
1148
1149
			if ( isset( $value['dismissible'] ) ) {
1150
				$dismissible = $value['dismissible'];
1151
			} else {
1152
				$dismissible = false;
1153
			}
1154
1155
			if ( isset( $value['type'] ) ) {
1156
				$type = $value['type'];
1157
			} else {
1158
				$type = '';
1159
			}
1160
1161
			if ( ! isset( $value['template'] ) ) {
1162
				$template = '';
1163
			}
1164
1165
			if ( $condition ) {
1166
				new Object_Sync_Sf_Admin_Notice( $condition, $message, $dismissible, $type, $template );
1167
			}
1168
		}
1169
1170
	}
1171
1172
	/**
1173
	* Get all the Salesforce object settings for fieldmapping
1174
	* This takes either the $_POST array via ajax, or can be directly called with a $data array
1175
	*
1176
	* @param array $data
1177
	* data must contain a salesforce_object
1178
	* can optionally contain a type
1179
	* @return array $object_settings
1180
	*/
1181
	public function get_salesforce_object_description( $data = array() ) {
1182
		$ajax = false;
1183
		if ( empty( $data ) ) {
1184
			$data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
1185
			$ajax = true;
1186
		}
1187
1188
		$object_description = array();
1189
1190
		if ( ! empty( $data['salesforce_object'] ) ) {
1191
			$object = $this->salesforce['sfapi']->object_describe( esc_attr( $data['salesforce_object'] ) );
1192
1193
			$object_fields        = array();
1194
			$include_record_types = array();
0 ignored issues
show
Unused Code introduced by
$include_record_types is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1195
1196
			// these can come from ajax
1197
			$include = isset( $data['include'] ) ? (array) $data['include'] : array();
1198
			$include = array_map( 'esc_attr', $include );
1199
1200
			if ( in_array( 'fields', $include, true ) || empty( $include ) ) {
1201
				$type = isset( $data['field_type'] ) ? esc_attr( $data['field_type'] ) : ''; // can come from ajax
1202 View Code Duplication
				foreach ( $object['data']['fields'] as $key => $value ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1203
					if ( '' === $type || $type === $value['type'] ) {
1204
						$object_fields[ $key ] = $value;
1205
					}
1206
				}
1207
				$object_description['fields'] = $object_fields;
1208
			}
1209
1210 View Code Duplication
			if ( in_array( 'recordTypeInfos', $include, true ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1211
				if ( isset( $object['data']['recordTypeInfos'] ) && count( $object['data']['recordTypeInfos'] ) > 1 ) {
1212
					foreach ( $object['data']['recordTypeInfos'] as $type ) {
1213
						$object_record_types[ $type['recordTypeId'] ] = $type['name'];
1214
					}
1215
					$object_description['recordTypeInfos'] = $object_record_types;
1216
				}
1217
			}
1218
		}
1219
1220
		if ( true === $ajax ) {
1221
			wp_send_json_success( $object_description );
1222
		} else {
1223
			return $object_description;
1224
		}
1225
	}
1226
1227
	/**
1228
	* Get Salesforce object fields for fieldmapping
1229
	*
1230
	* @param array $data
1231
	* data must contain a salesforce_object
1232
	* can optionally contain a type for the field
1233
	* @return array $object_fields
1234
	*/
1235
	public function get_salesforce_object_fields( $data = array() ) {
1236
1237
		if ( ! empty( $data['salesforce_object'] ) ) {
1238
			$object               = $this->salesforce['sfapi']->object_describe( esc_attr( $data['salesforce_object'] ) );
1239
			$object_fields        = array();
1240
			$type                 = isset( $data['type'] ) ? esc_attr( $data['type'] ) : '';
1241
			$include_record_types = isset( $data['include_record_types'] ) ? esc_attr( $data['include_record_types'] ) : false;
1242 View Code Duplication
			foreach ( $object['data']['fields'] as $key => $value ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1243
				if ( '' === $type || $type === $value['type'] ) {
1244
					$object_fields[ $key ] = $value;
1245
				}
1246
			}
1247 View Code Duplication
			if ( true === $include_record_types ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1248
				$object_record_types = array();
1249
				if ( isset( $object['data']['recordTypeInfos'] ) && count( $object['data']['recordTypeInfos'] ) > 1 ) {
1250
					foreach ( $object['data']['recordTypeInfos'] as $type ) {
1251
						$object_record_types[ $type['recordTypeId'] ] = $type['name'];
1252
					}
1253
				}
1254
			}
1255
		}
1256
1257
		return $object_fields;
1258
1259
	}
1260
1261
	/**
1262
	* Get WordPress object fields for fieldmapping
1263
	* This takes either the $_POST array via ajax, or can be directly called with a $wordpress_object field
1264
	*
1265
	* @param string $wordpress_object
1266
	* @return array $object_fields
1267
	*/
1268
	public function get_wordpress_object_fields( $wordpress_object = '' ) {
1269
		$ajax      = false;
1270
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
1271 View Code Duplication
		if ( empty( $wordpress_object ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1272
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? sanitize_text_field( wp_unslash( $post_data['wordpress_object'] ) ) : '';
1273
			$ajax             = true;
1274
		}
1275
1276
		$object_fields = $this->wordpress->get_wordpress_object_fields( $wordpress_object );
1277
1278
		if ( true === $ajax ) {
1279
			wp_send_json_success( $object_fields );
1280
		} else {
1281
			return $object_fields;
1282
		}
1283
	}
1284
1285
	/**
1286
	* Get WordPress and Salesforce object fields together for fieldmapping
1287
	* This takes either the $_POST array via ajax, or can be directly called with $wordpress_object and $salesforce_object fields
1288
	*
1289
	* @param string $wordpress_object
1290
	* @param string $salesforce_object
0 ignored issues
show
Documentation introduced by
There is no parameter named $salesforce_object. Did you maybe mean $salesforce?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
1291
	* @return array $object_fields
1292
	*/
1293
	public function get_wp_sf_object_fields( $wordpress_object = '', $salesforce = '' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $salesforce is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1294
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
1295 View Code Duplication
		if ( empty( $wordpress_object ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1296
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? sanitize_text_field( wp_unslash( $post_data['wordpress_object'] ) ) : '';
1297
		}
1298 View Code Duplication
		if ( empty( $salesforce_object ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1299
			$salesforce_object = isset( $post_data['salesforce_object'] ) ? sanitize_text_field( wp_unslash( $post_data['salesforce_object'] ) ) : '';
1300
		}
1301
1302
		$object_fields['wordpress']  = $this->get_wordpress_object_fields( $wordpress_object );
1303
		$object_fields['salesforce'] = $this->get_salesforce_object_fields(
1304
			array(
1305
				'salesforce_object' => $salesforce_object,
1306
			)
1307
		);
1308
1309
		if ( ! empty( $post_data ) ) {
1310
			wp_send_json_success( $object_fields );
1311
		} else {
1312
			return $object_fields;
1313
		}
1314
	}
1315
1316
	/**
1317
	* Manually push the WordPress object to Salesforce
1318
	* This takes either the $_POST array via ajax, or can be directly called with $wordpress_object and $wordpress_id fields
1319
	*
1320
	* @param string $wordpress_object
1321
	* @param int $wordpress_id
1322
	*/
1323
	public function push_to_salesforce( $wordpress_object = '', $wordpress_id = '' ) {
1324
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
1325 View Code Duplication
		if ( empty( $wordpress_object ) && empty( $wordpress_id ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1326
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? sanitize_text_field( wp_unslash( $post_data['wordpress_object'] ) ) : '';
1327
			$wordpress_id     = isset( $post_data['wordpress_id'] ) ? absint( $post_data['wordpress_id'] ) : '';
1328
		}
1329
1330
		// clarify what that variable is in this context.
1331
		$object_type = $wordpress_object;
1332
1333
		// When objects are already mapped, there is a Salesforce id as well. Otherwise, it's blank.
1334
		$salesforce_id = isset( $post_data['salesforce_id'] ) ? sanitize_text_field( $post_data['salesforce_id'] ) : '';
1335
		if ( '' === $salesforce_id ) {
1336
			$method = 'POST';
1337
		} else {
1338
			$method = 'PUT';
1339
		}
1340
1341
		$result = $this->push->manual_push( $object_type, $wordpress_id, $method );
1342
1343
		if ( ! empty( $post_data['wordpress_object'] ) && ! empty( $post_data['wordpress_id'] ) ) {
1344
			wp_send_json_success( $result );
1345
		} else {
1346
			return $result;
1347
		}
1348
1349
	}
1350
1351
	/**
1352
	* Manually pull the Salesforce object into WordPress
1353
	* This takes either the $_POST array via ajax, or can be directly called with $salesforce_id fields
1354
	*
1355
	* @param string $salesforce_id
1356
	* @param string $wordpress_object
1357
	*/
1358
	public function pull_from_salesforce( $salesforce_id = '', $wordpress_object = '' ) {
1359
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
1360 View Code Duplication
		if ( empty( $wordpress_object ) && empty( $salesforce_id ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1361
			$wordpress_object = isset( $post_data['wordpress_object'] ) ? sanitize_text_field( wp_unslash( $post_data['wordpress_object'] ) ) : '';
1362
			$salesforce_id    = isset( $post_data['salesforce_id'] ) ? sanitize_text_field( wp_unslash( $post_data['salesforce_id'] ) ) : '';
1363
		}
1364
		$type   = $this->salesforce['sfapi']->get_sobject_type( $salesforce_id );
1365
		$result = $this->pull->manual_pull( $type, $salesforce_id, $wordpress_object ); // we want the wp object to make sure we get the right fieldmap
1366
		if ( ! empty( $post_data ) ) {
1367
			wp_send_json_success( $result );
1368
		} else {
1369
			return $result;
1370
		}
1371
	}
1372
1373
	/**
1374
	* Manually pull the Salesforce object into WordPress
1375
	* This takes an id for a mapping object row
1376
	*
1377
	* @param int $mapping_id
1378
	*/
1379
	public function refresh_mapped_data( $mapping_id = '' ) {
1380
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
1381
		if ( empty( $mapping_id ) ) {
1382
			$mapping_id = isset( $post_data['mapping_id'] ) ? absint( $post_data['mapping_id'] ) : '';
1383
		}
1384
		$result = $this->mappings->get_object_maps(
1385
			array(
1386
				'id' => $mapping_id,
1387
			)
1388
		);
1389
		if ( ! empty( $post_data ) ) {
1390
			wp_send_json_success( $result );
1391
		} else {
1392
			return $result;
1393
		}
1394
	}
1395
1396
	/**
1397
	* Prepare fieldmap data and redirect after processing
1398
	* This runs when the create or update forms are submitted
1399
	* It is public because it depends on an admin hook
1400
	* It then calls the Object_Sync_Sf_Mapping class and sends prepared data over to it, then redirects to the correct page
1401
	* This method does include error handling, by loading the submission in a transient if there is an error, and then deleting it upon success
1402
	*
1403
	*/
1404
	public function prepare_fieldmap_data() {
1405
		$error     = false;
1406
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
1407
		$cachekey  = md5( wp_json_encode( $post_data ) );
1408
1409
		if ( ! isset( $post_data['label'] ) || ! isset( $post_data['salesforce_object'] ) || ! isset( $post_data['wordpress_object'] ) ) {
1410
			$error = true;
1411
		}
1412
		if ( true === $error ) {
1413
			$this->sfwp_transients->set( $cachekey, $post_data, $this->wordpress->options['cache_expiration'] );
1414
			if ( '' !== $cachekey ) {
1415
				$url = esc_url_raw( $post_data['redirect_url_error'] ) . '&transient=' . $cachekey;
1416
			}
1417
		} else { // there are no errors
1418
			// send the row to the fieldmap class
1419
			// if it is add or clone, use the create method
1420
			$method            = esc_attr( $post_data['method'] );
1421
			$salesforce_fields = $this->get_salesforce_object_fields(
1422
				array(
1423
					'salesforce_object' => $post_data['salesforce_object'],
1424
				)
1425
			);
1426
			$wordpress_fields  = $this->get_wordpress_object_fields( $post_data['wordpress_object'] );
1427
			if ( 'add' === $method || 'clone' === $method ) {
1428
				$result = $this->mappings->create_fieldmap( $post_data, $wordpress_fields, $salesforce_fields );
1429
			} elseif ( 'edit' === $method ) { // if it is edit, use the update method
1430
				$id     = esc_attr( $post_data['id'] );
1431
				$result = $this->mappings->update_fieldmap( $post_data, $wordpress_fields, $salesforce_fields, $id );
1432
			}
1433 View Code Duplication
			if ( false === $result ) { // if the database didn't save, it's still an error
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1434
				$this->sfwp_transients->set( $cachekey, $post_data, $this->wordpress->options['cache_expiration'] );
1435
				if ( '' !== $cachekey ) {
1436
					$url = esc_url_raw( $post_data['redirect_url_error'] ) . '&transient=' . $cachekey;
1437
				}
1438
			} else {
1439
				if ( isset( $post_data['transient'] ) ) { // there was previously an error saved. can delete it now.
1440
					$this->sfwp_transients->delete( esc_attr( $post_data['map_transient'] ) );
1441
				}
1442
				// then send the user to the list of fieldmaps
1443
				$url = esc_url_raw( $post_data['redirect_url_success'] );
1444
			}
1445
		}
1446
		wp_safe_redirect( $url );
1447
		exit();
1448
	}
1449
1450
	/**
1451
	* Delete fieldmap data and redirect after processing
1452
	* This runs when the delete link is clicked, after the user confirms
1453
	* It is public because it depends on an admin hook
1454
	* It then calls the Object_Sync_Sf_Mapping class and the delete method
1455
	*
1456
	*/
1457
	public function delete_fieldmap() {
1458
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
1459
		if ( $post_data['id'] ) {
1460
			$result = $this->mappings->delete_fieldmap( $post_data['id'] );
1461 View Code Duplication
			if ( true === $result ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1462
				$url = esc_url_raw( $post_data['redirect_url_success'] );
1463
			} else {
1464
				$url = esc_url_raw( $post_data['redirect_url_error'] . '&id=' . $post_data['id'] );
1465
			}
1466
			wp_safe_redirect( $url );
1467
			exit();
1468
		}
1469
	}
1470
1471
	/**
1472
	* Prepare object data and redirect after processing
1473
	* This runs when the update form is submitted
1474
	* It is public because it depends on an admin hook
1475
	* It then calls the Object_Sync_Sf_Mapping class and sends prepared data over to it, then redirects to the correct page
1476
	* This method does include error handling, by loading the submission in a transient if there is an error, and then deleting it upon success
1477
	*
1478
	*/
1479
	public function prepare_object_map_data() {
1480
		$error     = false;
1481
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
1482
		$cachekey  = md5( wp_json_encode( $post_data ) );
1483
1484
		if ( ! isset( $post_data['wordpress_id'] ) || ! isset( $post_data['salesforce_id'] ) ) {
1485
			$error = true;
1486
		}
1487
		if ( true === $error ) {
1488
			$this->sfwp_transients->set( $cachekey, $post_data, $this->wordpress->options['cache_expiration'] );
1489
			if ( '' !== $cachekey ) {
1490
				$url = esc_url_raw( $post_data['redirect_url_error'] ) . '&map_transient=' . $cachekey;
1491
			}
1492
		} else { // there are no errors
1493
			// send the row to the object map class
1494
			$method = esc_attr( $post_data['method'] );
1495
			if ( 'edit' === $method ) { // if it is edit, use the update method
1496
				$id     = esc_attr( $post_data['id'] );
1497
				$result = $this->mappings->update_object_map( $post_data, $id );
1498
			}
1499 View Code Duplication
			if ( false === $result ) { // if the database didn't save, it's still an error
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1500
				$this->sfwp_transients->set( $cachekey, $post_data, $this->wordpress->options['cache_expiration'] );
1501
				if ( '' !== $cachekey ) {
1502
					$url = esc_url_raw( $post_data['redirect_url_error'] ) . '&map_transient=' . $cachekey;
1503
				}
1504
			} else {
1505
				if ( isset( $post_data['map_transient'] ) ) { // there was previously an error saved. can delete it now.
1506
					$this->sfwp_transients->delete( esc_attr( $post_data['map_transient'] ) );
1507
				}
1508
				// then send the user to the success redirect url
1509
				$url = esc_url_raw( $post_data['redirect_url_success'] );
1510
			}
1511
		}
1512
		wp_safe_redirect( $url );
1513
		exit();
1514
	}
1515
1516
	/**
1517
	* Delete object map data and redirect after processing
1518
	* This runs when the delete link is clicked on an error row, after the user confirms
1519
	* It is public because it depends on an admin hook
1520
	* It then calls the Object_Sync_Sf_Mapping class and the delete method
1521
	*
1522
	*/
1523
	public function delete_object_map() {
1524
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
1525
		if ( isset( $post_data['id'] ) ) {
1526
			$result = $this->mappings->delete_object_map( $post_data['id'] );
1527 View Code Duplication
			if ( true === $result ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1528
				$url = esc_url_raw( $post_data['redirect_url_success'] );
1529
			} else {
1530
				$url = esc_url_raw( $post_data['redirect_url_error'] . '&id=' . $post_data['id'] );
1531
			}
1532
			wp_safe_redirect( $url );
1533
			exit();
1534
		} elseif ( $post_data['delete'] ) {
1535
			$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
1536
			$cachekey  = md5( wp_json_encode( $post_data ) );
1537
			$error     = false;
1538
			if ( ! isset( $post_data['delete'] ) ) {
1539
				$error = true;
1540
			}
1541
			if ( true === $error ) {
1542
				$this->sfwp_transients->set( $cachekey, $post_data, $this->wordpress->options['cache_expiration'] );
1543
				if ( '' !== $cachekey ) {
1544
					$url = esc_url_raw( $post_data['redirect_url_error'] ) . '&mapping_error_transient=' . $cachekey;
1545
				}
1546
			} else { // there are no errors
1547
				$result = $this->mappings->delete_object_map( array_keys( $post_data['delete'] ) );
1548
				if ( true === $result ) {
1549
					$url = esc_url_raw( $post_data['redirect_url_success'] );
1550
				}
1551
1552 View Code Duplication
				if ( false === $result ) { // if the database didn't save, it's still an error
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1553
					$this->sfwp_transients->set( $cachekey, $post_data, $this->wordpress->options['cache_expiration'] );
1554
					if ( '' !== $cachekey ) {
1555
						$url = esc_url_raw( $post_data['redirect_url_error'] ) . '&mapping_error_transient=' . $cachekey;
1556
					}
1557
				} else {
1558
					if ( isset( $post_data['mapping_error_transient'] ) ) { // there was previously an error saved. can delete it now.
1559
						$this->sfwp_transients->delete( esc_attr( $post_data['mapping_error_transient'] ) );
1560
					}
1561
					// then send the user to the list of fieldmaps
1562
					$url = esc_url_raw( $post_data['redirect_url_success'] );
1563
				}
1564
			}
1565
			wp_safe_redirect( $url );
1566
			exit();
1567
		}
1568
	}
1569
1570
	/**
1571
	* Import a json file and use it for plugin data
1572
	*
1573
	*/
1574
	public function import_json_file() {
1575
1576
		if ( ! wp_verify_nonce( $_POST['object_sync_for_salesforce_nonce_import'], 'object_sync_for_salesforce_nonce_import' ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_POST
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
1577
			return;
1578
		}
1579
		if ( ! current_user_can( 'manage_options' ) ) {
1580
			return;
1581
		}
1582
		$path      = $_FILES['import_file']['name'];
1583
		$extension = pathinfo( $path, PATHINFO_EXTENSION );
1584
		if ( 'json' !== $extension ) {
1585
			wp_die( __( 'Please upload a valid .json file' ) );
1586
		}
1587
1588
		$import_file = $_FILES['import_file']['tmp_name'];
1589
		if ( empty( $import_file ) ) {
1590
			wp_die( __( 'Please upload a file to import' ) );
1591
		}
1592
1593
		// Retrieve the data from the file and convert the json object to an array.
1594
		$data = (array) json_decode( file_get_contents( $import_file ), true );
0 ignored issues
show
introduced by
file_get_contents is highly discouraged, please use wpcom_vip_file_get_contents() instead.
Loading history...
1595
1596
		// if there is only one object map, fix the array
1597
		if ( isset( $data['object_maps'] ) ) {
1598
			if ( count( $data['object_maps'] ) === count( $data['object_maps'], COUNT_RECURSIVE ) ) {
1599
				$data['object_maps'] = array( 0 => $data['object_maps'] );
1600
			}
1601
		}
1602
1603
		$overwrite = isset( $_POST['overwrite'] ) ? esc_attr( $_POST['overwrite'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
1604
		if ( '1' === $overwrite ) {
1605
			if ( isset( $data['fieldmaps'] ) ) {
1606
				$fieldmaps = $this->mappings->get_fieldmaps();
1607
				foreach ( $fieldmaps as $fieldmap ) {
1608
					$id     = $fieldmap['id'];
1609
					$delete = $this->mappings->delete_fieldmap( $id );
0 ignored issues
show
Unused Code introduced by
$delete is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1610
				}
1611
			}
1612
			if ( isset( $data['object_maps'] ) ) {
1613
				$object_maps = $this->mappings->get_object_maps();
1614
1615
				// if there is only one existing object map, fix the array
1616
				if ( count( $object_maps ) === count( $object_maps, COUNT_RECURSIVE ) ) {
1617
					$object_maps = array( 0 => $object_maps );
1618
				}
1619
1620
				foreach ( $object_maps as $object_map ) {
1621
					$id     = $object_map['id'];
1622
					$delete = $this->mappings->delete_object_map( $id );
0 ignored issues
show
Unused Code introduced by
$delete is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1623
				}
1624
			}
1625
			if ( isset( $data['plugin_settings'] ) ) {
1626
				foreach ( $data['plugin_settings'] as $key => $value ) {
1627
					delete_option( $value['option_name'] );
1628
				}
1629
			}
1630
		}
1631
1632
		$success = true;
1633
1634
		if ( isset( $data['fieldmaps'] ) ) {
1635
			foreach ( $data['fieldmaps'] as $fieldmap ) {
1636
				unset( $fieldmap['id'] );
1637
				$create = $this->mappings->create_fieldmap( $fieldmap );
1638
				if ( false === $create ) {
1639
					$success = false;
1640
				}
1641
			}
1642
		}
1643
1644
		if ( isset( $data['object_maps'] ) ) {
1645
			foreach ( $data['object_maps'] as $object_map ) {
1646
				unset( $object_map['id'] );
1647
				$create = $this->mappings->create_object_map( $object_map );
1648
				if ( false === $create ) {
1649
					$success = false;
1650
				}
1651
			}
1652
		}
1653
1654
		if ( isset( $data['plugin_settings'] ) ) {
1655
			foreach ( $data['plugin_settings'] as $key => $value ) {
1656
				update_option( $value['option_name'], maybe_unserialize( $value['option_value'] ), $value['autoload'] );
1657
			}
1658
		}
1659
1660
		if ( true === $success ) {
1661
			wp_safe_redirect( get_admin_url( null, 'options-general.php?page=object-sync-salesforce-admin&tab=import-export&data_saved=true' ) );
1662
			exit;
1663
		} else {
1664
			wp_safe_redirect( get_admin_url( null, 'options-general.php?page=object-sync-salesforce-admin&tab=import-export&data_saved=false' ) );
1665
			exit;
1666
		}
1667
1668
	}
1669
1670
	/**
1671
	* Create a json file for exporting
1672
	*
1673
	*/
1674
	public function export_json_file() {
1675
1676
		if ( ! wp_verify_nonce( $_POST['object_sync_for_salesforce_nonce_export'], 'object_sync_for_salesforce_nonce_export' ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_POST
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
1677
			return;
1678
		}
1679
		if ( ! current_user_can( 'manage_options' ) ) {
1680
			return;
1681
		}
1682
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
1683
		$export    = array();
1684
		if ( in_array( 'fieldmaps', $post_data['export'] ) ) {
1685
			$export['fieldmaps'] = $this->mappings->get_fieldmaps();
1686
		}
1687
		if ( in_array( 'object_maps', $post_data['export'] ) ) {
1688
			$export['object_maps'] = $this->mappings->get_object_maps();
1689
		}
1690
		if ( in_array( 'plugin_settings', $post_data['export'] ) ) {
1691
			$export['plugin_settings'] = $this->wpdb->get_results( 'SELECT * FROM ' . $this->wpdb->prefix . 'options' . ' WHERE option_name like "' . $this->option_prefix . '%"', ARRAY_A );
1692
		}
1693
		nocache_headers();
1694
		header( 'Content-Type: application/json; charset=utf-8' );
1695
		header( 'Content-Disposition: attachment; filename=object-sync-for-salesforce-data-export-' . date( 'm-d-Y' ) . '.json' );
1696
		header( 'Expires: 0' );
1697
		echo wp_json_encode( $export );
1698
		exit;
1699
	}
1700
1701
	/**
1702
	* Default display for <input> fields
1703
	*
1704
	* @param array $args
1705
	*/
1706
	public function display_input_field( $args ) {
1707
		$type    = $args['type'];
1708
		$id      = $args['label_for'];
1709
		$name    = $args['name'];
1710
		$desc    = $args['desc'];
1711
		$checked = '';
1712
1713
		$class = 'regular-text';
1714
1715
		if ( 'checkbox' === $type ) {
1716
			$class = 'checkbox';
1717
		}
1718
1719
		if ( ! isset( $args['constant'] ) || ! defined( $args['constant'] ) ) {
1720
			$value = esc_attr( get_option( $id, '' ) );
1721
			if ( 'checkbox' === $type ) {
1722
				if ( '1' === $value ) {
1723
					$checked = 'checked ';
1724
				}
1725
				$value = 1;
1726
			}
1727
			if ( '' === $value && isset( $args['default'] ) && '' !== $args['default'] ) {
1728
				$value = $args['default'];
1729
			}
1730
1731
			echo sprintf( '<input type="%1$s" value="%2$s" name="%3$s" id="%4$s" class="%5$s"%6$s>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1732
				esc_attr( $type ),
1733
				esc_attr( $value ),
1734
				esc_attr( $name ),
1735
				esc_attr( $id ),
1736
				sanitize_html_class( $class . esc_html( ' code' ) ),
1737
				esc_html( $checked )
1738
			);
1739
			if ( '' !== $desc ) {
1740
				echo sprintf( '<p class="description">%1$s</p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1741
					esc_html( $desc )
1742
				);
1743
			}
1744
		} else {
1745
			echo sprintf( '<p><code>%1$s</code></p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1746
				esc_html__( 'Defined in wp-config.php', 'object-sync-for-salesforce' )
1747
			);
1748
		}
1749
	}
1750
1751
	/**
1752
	* Display for multiple checkboxes
1753
	* Above method can handle a single checkbox as it is
1754
	*
1755
	* @param array $args
1756
	*/
1757
	public function display_checkboxes( $args ) {
1758
		$type    = 'checkbox';
1759
		$name    = $args['name'];
1760
		$options = get_option( $name, array() );
1761
		foreach ( $args['items'] as $key => $value ) {
1762
			$text    = $value['text'];
1763
			$id      = $value['id'];
1764
			$desc    = $value['desc'];
1765
			$checked = '';
1766
			if ( is_array( $options ) && in_array( (string) $key, $options, true ) ) {
1767
				$checked = 'checked';
1768
			} elseif ( is_array( $options ) && empty( $options ) ) {
1769
				if ( isset( $value['default'] ) && true === $value['default'] ) {
1770
					$checked = 'checked';
1771
				}
1772
			}
1773
			echo sprintf( '<div class="checkbox"><label><input type="%1$s" value="%2$s" name="%3$s[]" id="%4$s"%5$s>%6$s</label></div>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1774
				esc_attr( $type ),
1775
				esc_attr( $key ),
1776
				esc_attr( $name ),
1777
				esc_attr( $id ),
1778
				esc_html( $checked ),
1779
				esc_html( $text )
1780
			);
1781
			if ( '' !== $desc ) {
1782
				echo sprintf( '<p class="description">%1$s</p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1783
					esc_html( $desc )
1784
				);
1785
			}
1786
		}
1787
	}
1788
1789
	/**
1790
	* Display for a dropdown
1791
	*
1792
	* @param array $args
1793
	*/
1794
	public function display_select( $args ) {
1795
		$type = $args['type'];
0 ignored issues
show
Unused Code introduced by
$type is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1796
		$id   = $args['label_for'];
1797
		$name = $args['name'];
1798
		$desc = $args['desc'];
1799
		if ( ! isset( $args['constant'] ) || ! defined( $args['constant'] ) ) {
1800
			$current_value = get_option( $name );
1801
1802
			echo sprintf( '<div class="select"><select id="%1$s" name="%2$s"><option value="">- ' . __( 'Select one', 'object-sync-for-salesforce' ) . ' -</option>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1803
				esc_attr( $id ),
1804
				esc_attr( $name )
1805
			);
1806
1807
			foreach ( $args['items'] as $key => $value ) {
1808
				$text     = $value['text'];
1809
				$value    = $value['value'];
1810
				$selected = '';
1811
				if ( $key === $current_value || $value === $current_value ) {
1812
					$selected = ' selected';
1813
				}
1814
1815
				echo sprintf( '<option value="%1$s"%2$s>%3$s</option>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1816
					esc_attr( $value ),
1817
					esc_attr( $selected ),
1818
					esc_html( $text )
1819
				);
1820
1821
			}
1822
			echo '</select>';
1823
			if ( '' !== $desc ) {
1824
				echo sprintf( '<p class="description">%1$s</p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1825
					esc_html( $desc )
1826
				);
1827
			}
1828
			echo '</div>';
1829
		} else {
1830
			echo sprintf( '<p><code>%1$s</code></p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1831
				esc_html__( 'Defined in wp-config.php', 'object-sync-for-salesforce' )
1832
			);
1833
		}
1834
	}
1835
1836
	/**
1837
	* Dropdown formatted list of Salesforce API versions
1838
	*
1839
	* @return array $args
1840
	*/
1841
	private function version_options() {
1842
		$args = array();
1843
		if ( defined( 'OBJECT_SYNC_SF_SALESFORCE_API_VERSION' ) || ! isset( $_GET['page'] ) || 'object-sync-salesforce-admin' !== $_GET['page'] ) {
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
1844
			return $args;
1845
		}
1846
		$versions = $this->salesforce['sfapi']->get_api_versions();
1847
		foreach ( $versions['data'] as $key => $value ) {
1848
			$args[] = array(
1849
				'value' => $value['version'],
1850
				'text'  => $value['label'] . ' (' . $value['version'] . ')',
1851
			);
1852
		}
1853
		return $args;
1854
	}
1855
1856
	/**
1857
	* Default display for <a href> links
1858
	*
1859
	* @param array $args
1860
	*/
1861
	public function display_link( $args ) {
1862
		$label = $args['label'];
1863
		$desc  = $args['desc'];
1864
		$url   = $args['url'];
1865
		if ( isset( $args['link_class'] ) ) {
1866
			echo sprintf( '<p><a class="%1$s" href="%2$s">%3$s</a></p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1867
				esc_attr( $args['link_class'] ),
1868
				esc_url( $url ),
1869
				esc_html( $label )
1870
			);
1871
		} else {
1872
			echo sprintf( '<p><a href="%1$s">%2$s</a></p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1873
				esc_url( $url ),
1874
				esc_html( $label )
1875
			);
1876
		}
1877
1878
		if ( '' !== $desc ) {
1879
			echo sprintf( '<p class="description">%1$s</p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1880
				esc_html( $desc )
1881
			);
1882
		}
1883
1884
	}
1885
1886
	/**
1887
	* Allow for a standard sanitize/validate method. We could use more specific ones if need be, but this one provides a baseline.
1888
	*
1889
	* @param string $option
1890
	* @return string $option
1891
	*/
1892
	public function sanitize_validate_text( $option ) {
1893
		if ( is_array( $option ) ) {
1894
			$options = array();
1895
			foreach ( $option as $key => $value ) {
1896
				$options[ $key ] = sanitize_text_field( $value );
1897
			}
1898
			return $options;
1899
		}
1900
		$option = sanitize_text_field( $option );
1901
		return $option;
1902
	}
1903
1904
	/**
1905
	* Run a demo of Salesforce API call on the authenticate tab after WordPress has authenticated with it
1906
	*
1907
	* @param object $sfapi
1908
	*/
1909
	private function status( $sfapi ) {
1910
1911
		$versions = $sfapi->get_api_versions();
1912
1913
		// format this array into text so users can see the versions
1914
		if ( true === $versions['cached'] ) {
1915
			$versions_is_cached = esc_html__( 'This list is cached, and', 'object-sync-salesforce' );
1916
		} else {
1917
			$versions_is_cached = esc_html__( 'This list is not cached, but', 'object-sync-salesforce' );
1918
		}
1919
1920
		if ( true === $versions['from_cache'] ) {
1921
			$versions_from_cache = esc_html__( 'items were loaded from the cache', 'object-sync-salesforce' );
1922
		} else {
1923
			$versions_from_cache = esc_html__( 'items were not loaded from the cache', 'object-sync-salesforce' );
1924
		}
1925
1926
		// translators: 1) $versions_is_cached is the "This list is/is not cached, and/but" line, 2) $versions_from_cache is the "items were/were not loaded from the cache" line
1927
		$versions_apicall_summary = sprintf( esc_html__( 'Available Salesforce API versions. %1$s %2$s. This is not an authenticated request, so it does not touch the Salesforce token.', 'object-sync-for-salesforce' ),
0 ignored issues
show
Unused Code introduced by
$versions_apicall_summary is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1928
			$versions_is_cached,
1929
			$versions_from_cache
1930
		);
1931
1932
		$contacts = $sfapi->query( 'SELECT Name, Id from Contact LIMIT 100' );
1933
1934
		// format this array into html so users can see the contacts
1935
		if ( true === $contacts['cached'] ) {
1936
			$contacts_is_cached = esc_html__( 'They are cached, and', 'object-sync-salesforce' );
1937
		} else {
1938
			$contacts_is_cached = esc_html__( 'They are not cached, but', 'object-sync-salesforce' );
1939
		}
1940
1941
		if ( true === $contacts['from_cache'] ) {
1942
			$contacts_from_cache = esc_html__( 'they were loaded from the cache', 'object-sync-salesforce' );
1943
		} else {
1944
			$contacts_from_cache = esc_html__( 'they were not loaded from the cache', 'object-sync-salesforce' );
1945
		}
1946
1947
		if ( true === $contacts['is_redo'] ) {
1948
			$contacts_refreshed_token = esc_html__( 'This request did require refreshing the Salesforce token', 'object-sync-salesforce' );
1949
		} else {
1950
			$contacts_refreshed_token = esc_html__( 'This request did not require refreshing the Salesforce token', 'object-sync-salesforce' );
1951
		}
1952
1953
		// 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
1954
		$contacts_apicall_summary = sprintf( esc_html__( 'Salesforce successfully returned %1$s %2$s records. %3$s %4$s. %5$s.', 'object-sync-for-salesforce' ),
0 ignored issues
show
Unused Code introduced by
$contacts_apicall_summary is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1955
			absint( $contacts['data']['totalSize'] ),
1956
			esc_html( $contacts['data']['records'][0]['attributes']['type'] ),
1957
			$contacts_is_cached,
1958
			$contacts_from_cache,
1959
			$contacts_refreshed_token
1960
		);
1961
1962
		require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/status.php' );
1963
1964
	}
1965
1966
	/**
1967
	* Deauthorize WordPress from Salesforce.
1968
	* This deletes the tokens from the database; it does not currently do anything in Salesforce
1969
	* For this plugin at this time, that is the decision we are making: don't do any kind of authorization stuff inside Salesforce
1970
	*/
1971
	private function logout() {
1972
		$this->access_token  = delete_option( $this->option_prefix . 'access_token' );
1973
		$this->instance_url  = delete_option( $this->option_prefix . 'instance_url' );
1974
		$this->refresh_token = delete_option( $this->option_prefix . 'refresh_token' );
1975
		echo sprintf( '<p>You have been logged out. You can use the <a href="%1$s">%2$s</a> tab to log in again.</p>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1976
			esc_url( get_admin_url( null, 'options-general.php?page=object-sync-salesforce-admin&tab=authorize' ) ),
1977
			esc_html__( 'Authorize', 'object-sync-for-salesforce' )
1978
		);
1979
	}
1980
1981
	/**
1982
	* Ajax call to clear the plugin cache.
1983
	*/
1984
	public function clear_sfwp_cache() {
1985
		$result   = $this->clear_cache( true );
1986
		$response = array(
1987
			'message' => $result['message'],
1988
			'success' => $result['success'],
1989
		);
1990
		wp_send_json_success( $response );
1991
	}
1992
1993
	/**
1994
	* Clear the plugin's cache.
1995
	* This uses the flush method contained in the WordPress cache to clear all of this plugin's cached data.
1996
	*/
1997
	private function clear_cache( $ajax = false ) {
1998
		$result = (bool) $this->wordpress->sfwp_transients->flush();
1999
		if ( true === $result ) {
2000
			$message = __( 'The plugin cache has been cleared.', 'object-sync-for-salesforce' );
2001
		} else {
2002
			$message = __( 'There was an error clearing the plugin cache. Try refreshing this page.', 'object-sync-for-salesforce' );
2003
		}
2004
		if ( false === $ajax ) {
2005
			// translators: parameter 1 is the result message
2006
			echo sprintf( '<p>%1$s</p>', $message );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
2007
		} else {
2008
			return array(
2009
				'message' => $message,
2010
				'success' => $result,
2011
			);
2012
		}
2013
	}
2014
2015
	/**
2016
	* Check WordPress Admin permissions
2017
	* Check if the current user is allowed to access the Salesforce plugin options
2018
	*/
2019
	private function check_wordpress_admin_permissions() {
2020
2021
		// one programmatic way to give this capability to additional user roles is the
2022
		// object_sync_for_salesforce_roles_configure_salesforce hook
2023
		// it runs on activation of this plugin, and will assign the below capability to any role
2024
		// coming from the hook
2025
2026
		// alternatively, other roles can get this capability in whatever other way you like
2027
		// point is: to administer this plugin, you need this capability
2028
2029
		if ( ! current_user_can( 'configure_salesforce' ) ) {
2030
			return false;
2031
		} else {
2032
			return true;
2033
		}
2034
2035
	}
2036
2037
	/**
2038
	* Show what we know about this user's relationship to a Salesforce object, if any
2039
	* @param object $user
2040
	*
2041
	*/
2042
	public function show_salesforce_user_fields( $user ) {
2043
		$get_data = filter_input_array( INPUT_GET, FILTER_SANITIZE_STRING );
2044
		if ( true === $this->check_wordpress_admin_permissions() ) {
2045
			$mappings = $this->mappings->load_all_by_wordpress( 'user', $user->ID );
2046
			$fieldmap = $this->mappings->get_fieldmaps(
2047
				null, // id field must be null for multiples
2048
				array(
2049
					'wordpress_object' => 'user',
2050
				)
2051
			);
2052
			foreach ( $mappings as $mapping ) {
2053
				if ( isset( $mapping['id'] ) && ! isset( $get_data['edit_salesforce_mapping'] ) ) {
2054
					require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/user-profile-salesforce.php' );
2055
				} elseif ( ! empty( $fieldmap ) ) { // is the user mapped to something already?
2056
					if ( isset( $get_data['edit_salesforce_mapping'] ) && 'true' === sanitize_key( $get_data['edit_salesforce_mapping'] ) ) {
2057
						require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/user-profile-salesforce-change.php' );
2058
					} else {
2059
						require_once( plugin_dir_path( __FILE__ ) . '/../templates/admin/user-profile-salesforce-map.php' );
2060
					}
2061
				}
2062
			}
2063
		}
2064
	}
2065
2066
	/**
2067
	* If the user profile has been mapped to Salesforce, do it
2068
	* @param int $user_id
2069
	*
2070
	*/
2071
	public function save_salesforce_user_fields( $user_id ) {
2072
		$post_data = filter_input_array( INPUT_POST, FILTER_SANITIZE_STRING );
2073
		if ( isset( $post_data['salesforce_update_mapped_user'] ) && '1' === rawurlencode( $post_data['salesforce_update_mapped_user'] ) ) {
2074
			$mapping_object                  = $this->mappings->get_object_maps(
2075
				array(
2076
					'wordpress_id'     => $user_id,
2077
					'wordpress_object' => 'user',
2078
				)
2079
			);
2080
			$mapping_object['salesforce_id'] = $post_data['salesforce_id'];
2081
2082
			$result = $this->mappings->update_object_map( $mapping_object, $mapping_object['id'] );
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2083
		} elseif ( isset( $post_data['salesforce_create_mapped_user'] ) && '1' === rawurlencode( $post_data['salesforce_create_mapped_user'] ) ) {
2084
			// if a Salesforce ID was entered
2085
			if ( isset( $post_data['salesforce_id'] ) && ! empty( $post_data['salesforce_id'] ) ) {
2086
				$mapping_object = $this->create_object_map( $user_id, 'user', $post_data['salesforce_id'] );
0 ignored issues
show
Unused Code introduced by
$mapping_object is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2087
			} elseif ( isset( $post_data['push_new_user_to_salesforce'] ) ) {
2088
				// otherwise, create a new record in Salesforce
2089
				$result = $this->push_to_salesforce( 'user', $user_id );
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2090
			}
2091
		}
2092
	}
2093
2094
	/**
2095
	* Render tabs for settings pages in admin
2096
	* @param array $tabs
2097
	* @param string $tab
2098
	*/
2099
	private function tabs( $tabs, $tab = '' ) {
2100
2101
		$get_data        = filter_input_array( INPUT_GET, FILTER_SANITIZE_STRING );
2102
		$consumer_key    = $this->login_credentials['consumer_key'];
2103
		$consumer_secret = $this->login_credentials['consumer_secret'];
2104
		$callback_url    = $this->login_credentials['callback_url'];
0 ignored issues
show
Unused Code introduced by
$callback_url is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2105
2106
		$current_tab = $tab;
2107
		echo '<h2 class="nav-tab-wrapper">';
2108
		foreach ( $tabs as $tab_key => $tab_caption ) {
2109
			$active = $current_tab === $tab_key ? ' nav-tab-active' : '';
2110
			if ( 'settings' === $tab_key || ( isset( $consumer_key ) && isset( $consumer_secret ) && ! empty( $consumer_key ) && ! empty( $consumer_secret ) ) ) {
2111
				echo sprintf( '<a class="nav-tab%1$s" href="%2$s">%3$s</a>',
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
2112
					esc_attr( $active ),
2113
					esc_url( '?page=object-sync-salesforce-admin&tab=' . $tab_key ),
2114
					esc_html( $tab_caption )
2115
				);
2116
			}
2117
		}
2118
		echo '</h2>';
2119
2120
		if ( isset( $get_data['tab'] ) ) {
2121
			$tab = sanitize_key( $get_data['tab'] );
0 ignored issues
show
Unused Code introduced by
$tab is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2122
		} else {
2123
			$tab = '';
0 ignored issues
show
Unused Code introduced by
$tab is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2124
		}
2125
	}
2126
2127
	/**
2128
	* Clear schedule
2129
	* This clears the schedule if the user clicks the button
2130
	* @param string $schedule_name
2131
	*/
2132
	private function clear_schedule( $schedule_name = '' ) {
2133
		if ( '' !== $schedule_name ) {
2134
			$this->queue->cancel( $schedule_name );
2135
			// translators: $schedule_name is the name of the current queue. Defaults: salesforce_pull, salesforce_push, salesforce
2136
			echo sprintf( esc_html__( 'You have cleared the %s schedule.', 'object-sync-for-salesforce' ), esc_html( $schedule_name ) );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
2137
		} else {
2138
			echo esc_html__( 'You need to specify the name of the schedule you want to clear.', 'object-sync-for-salesforce' );
2139
		}
2140
	}
2141
2142
	/**
2143
	* Get count of schedule items
2144
	* @param string $schedule_name
2145
	* @return int $count
2146
	*/
2147
	private function get_schedule_count( $schedule_name = '' ) {
2148
		if ( '' !== $schedule_name ) {
2149
			$count       = count( $this->queue->search(
2150
				array(
2151
					'group'  => $schedule_name,
2152
					'status' => ActionScheduler_Store::STATUS_PENDING,
2153
				),
2154
				'ARRAY_A'
2155
			) );
2156
			$group_count = count( $this->queue->search(
2157
				array(
2158
					'group'  => $schedule_name . $this->action_group_suffix,
2159
					'status' => ActionScheduler_Store::STATUS_PENDING,
2160
				),
2161
				'ARRAY_A'
2162
			) );
2163
			return $count + $group_count;
2164
		} else {
2165
			return 0;
2166
		}
2167
	}
2168
2169
	/**
2170
	* Create an object map between a WordPress object and a Salesforce object
2171
	*
2172
	* @param int $wordpress_id
2173
	*   Unique identifier for the WordPress object
2174
	* @param string $wordpress_object
2175
	*   What kind of object is it?
2176
	* @param string $salesforce_id
2177
	*   Unique identifier for the Salesforce object
2178
	* @param string $action
2179
	*   Did we push or pull?
2180
	*
2181
	* @return int $wpdb->insert_id
2182
	*   This is the database row for the map object
2183
	*
2184
	*/
2185
	private function create_object_map( $wordpress_id, $wordpress_object, $salesforce_id, $action = '' ) {
2186
		// Create object map and save it
2187
		$mapping_object = $this->mappings->create_object_map(
2188
			array(
2189
				'wordpress_id'      => $wordpress_id, // wordpress unique id
2190
				'salesforce_id'     => $salesforce_id, // salesforce unique id. we don't care what kind of object it is at this point
2191
				'wordpress_object'  => $wordpress_object, // keep track of what kind of wp object this is
2192
				'last_sync'         => current_time( 'mysql' ),
2193
				'last_sync_action'  => $action,
2194
				'last_sync_status'  => $this->mappings->status_success,
2195
				'last_sync_message' => __( 'Mapping object updated via function: ', 'object-sync-for-salesforce' ) . __FUNCTION__,
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '__FUNCTION__'
Loading history...
2196
			)
2197
		);
2198
2199
		return $mapping_object;
2200
2201
	}
2202
2203
}
2204