Passed
Pull Request — master (#444)
by Jonathan
12:44 queued 08:43
created

Object_Sync_Sf_Sync_Transients::set()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 28
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 12
nc 6
nop 5
dl 0
loc 28
rs 9.5555
c 0
b 0
f 0
1
<?php
2
/**
3
 * Handles getting and setting the transients.
4
 *
5
 * @class   Object_Sync_Sf_Sync_Transients
6
 * @package Object_Sync_Salesforce
7
 */
8
9
defined( 'ABSPATH' ) || exit;
10
11
/**
12
 * Object_Sync_Sf_Sync_Transients class.
13
 */
14
class Object_Sync_Sf_Sync_Transients {
15
16
	/**
17
	 * Current version of the plugin
18
	 *
19
	 * @var string
20
	 */
21
	public $version;
22
23
	/**
24
	 * The plugin's prefix when saving options to the database
25
	 *
26
	 * @var string
27
	 */
28
	public $option_prefix;
29
30
	/**
31
	 * Transient keys that can be upgraded
32
	 *
33
	 * @var string
34
	 */
35
	private $upgradeable_keys;
36
37
	/**
38
	 * Constructor for transient records class
39
	 */
40
	public function __construct() {
41
		$this->version          = object_sync_for_salesforce()->version;
42
		$this->option_prefix    = object_sync_for_salesforce()->option_prefix;
43
		$this->upgradeable_keys = $this->get_upgradeable_keys();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->get_upgradeable_keys() of type array is incompatible with the declared type string of property $upgradeable_keys.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
44
45
	}
46
47
	/**
48
	 * Generate a transient key
49
	 *
50
	 * @param array $params the pieces to put together.
51
	 * @param bool  $legacy whether this is a legacy key. This is for deprecated keys and will be removed in a future version.
52
	 * @return string $key the full transient key.
53
	 */
54
	private function generate_transient_key( $params, $legacy = false ) {
55
		array_unshift( $params, substr( $this->option_prefix, 0, -1 ) ); // add the prefixes.
56
		$params = array_filter( $params, fn( $value ) => ! is_null( $value ) && '' !== $value ); // remove null and empty values.
57
58
		// legacy keys don't have a fieldmap.
59
		if ( true === $legacy && isset( $params['fieldmap_id'] ) ) {
60
			unset( $params['fieldmap_id'] );
61
		}
62
63
		// make the key a string.
64
		$key = implode( '_', $params );
65
66
		// allow developers to filter the key.
67
		$key = apply_filters( $this->option_prefix . 'transient_key', $key, $params );
68
69
		/* // phpcs:ignore Squiz.PHP.CommentedOutCode.Found
70
		add_filter( 'object_sync_for_salesforce_transient_key', 'change_transient_key', 10, 2 );
71
		function change_transient_key( $key, $params ) {
72
			$key = 'my_key_name';
73
			return $key;
74
		}
75
		*/
76
77
		if ( true === $legacy ) {
78
			// allow developers to filter the legacy key.
79
			$key = apply_filters( $this->option_prefix . 'transient_legacy_key', $key, $params );
80
		}
81
82
		// note: the WordPress codex indicates that option names do not need to be escaped.
83
		// see: https://developer.wordpress.org/reference/functions/update_option/.
84
85
		return $key;
86
	}
87
88
	/**
89
	 * Set individual transient records for sync operations
90
	 *
91
	 * @param string $operation what is the transient related to? last pull, current pull, merge, delete, etc.
92
	 * @param string $object_type the Salesforce object type.
93
	 * @param int    $fieldmap_id the ID of the specific fieldmap that is running.
94
	 * @param mixed  $value the value to be saved in the option.
95
	 * @param int    $expiration whether to expire the transient.
96
	 * @return bool  $result value of the save operation.
97
	 */
98
	public function set( $operation, $object_type = '', $fieldmap_id = '', $value = '', $expiration = 0 ) {
99
		// generate the option key parameters.
100
		$params = array(
101
			'operation'   => $operation,
102
			'object_type' => $object_type,
103
			'fieldmap_id' => $fieldmap_id,
104
		);
105
		$key    = $this->generate_transient_key( $params );
106
		$value  = isset( $value ) ? $value : '';
107
108
		/*
109
		 * examples
110
		 * object_sync_for_salesforce_pull_last_sync_Contact_1
111
		 * object_sync_for_salesforce_currently_pulling_query_Contact_1
112
		 * object_sync_for_salesforce_pull_merge_last_Contact_1
113
		 * object_sync_for_salesforce_pull_delete_last_Contact_1
114
		 */
115
116
		$result = set_transient( $key, $value, $expiration );
117
118
		if ( true === $result ) {
119
			$legacy_key = $this->generate_transient_key( $params, true );
120
			// if the legacy key exists and the keys are not the same, we might need to upgrade.
121
			if ( get_transient( $legacy_key ) && $key !== $legacy_key ) {
122
				$this->legacy_transient_upgrade( $operation, $object_type, $fieldmap_id );
0 ignored issues
show
Bug introduced by
It seems like $fieldmap_id can also be of type string; however, parameter $fieldmap_id of Object_Sync_Sf_Sync_Tran...acy_transient_upgrade() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

122
				$this->legacy_transient_upgrade( $operation, $object_type, /** @scrutinizer ignore-type */ $fieldmap_id );
Loading history...
Deprecated Code introduced by
The function Object_Sync_Sf_Sync_Tran...acy_transient_upgrade() has been deprecated: this was added in 2.1.0 to upgrade old transient keys, but will be removed in a future version. ( Ignorable by Annotation )

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

122
				/** @scrutinizer ignore-deprecated */ $this->legacy_transient_upgrade( $operation, $object_type, $fieldmap_id );

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

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

Loading history...
123
			}
124
		}
125
		return $result;
126
	}
127
128
	/**
129
	 * Set individual transient records for sync operations
130
	 *
131
	 * @param string $operation what is the option related to? last pull, current pull, merge, delete, etc.
132
	 * @param string $object_type the Salesforce object type.
133
	 * @param int    $fieldmap_id the ID of the specific fieldmap that is running.
134
	 * @param mixed  $value the value to be saved in the option.
135
	 * @param int    $expiration whether to expire the transient.
136
	 * @return bool  $result value of the save operation.
137
	 * @deprecated   this was added in 2.1.0 to upgrade old transient keys, but will be removed in a future version.
138
	 */
139
	private function legacy_transient_upgrade( $operation, $object_type = '', $fieldmap_id = '', $value = '', $expiration = 0 ) {
0 ignored issues
show
Unused Code introduced by
The parameter $expiration is not used and could be removed. ( Ignorable by Annotation )

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

139
	private function legacy_transient_upgrade( $operation, $object_type = '', $fieldmap_id = '', $value = '', /** @scrutinizer ignore-unused */ $expiration = 0 ) {

This check looks for 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 $value is not used and could be removed. ( Ignorable by Annotation )

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

139
	private function legacy_transient_upgrade( $operation, $object_type = '', $fieldmap_id = '', /** @scrutinizer ignore-unused */ $value = '', $expiration = 0 ) {

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

Loading history...
140
		$result       = false;
141
		$legacy_value = $this->legacy_get( $operation, $object_type, $fieldmap_id );
0 ignored issues
show
Bug introduced by
It seems like $fieldmap_id can also be of type string; however, parameter $fieldmap_id of Object_Sync_Sf_Sync_Transients::legacy_get() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

141
		$legacy_value = $this->legacy_get( $operation, $object_type, /** @scrutinizer ignore-type */ $fieldmap_id );
Loading history...
142
		if ( false !== $legacy_value ) {
143
			// generate the option key parameters.
144
			$params = array(
145
				'operation'   => $operation,
146
				'object_type' => $object_type,
147
				'fieldmap_id' => $fieldmap_id,
148
			);
149
			$key    = $this->generate_transient_key( $params, true );
150
			$this->add_upgradeable_key( $key );
151
			$result = $this->set( $operation, $object_type, $fieldmap_id, $legacy_value );
0 ignored issues
show
Bug introduced by
It seems like $fieldmap_id can also be of type string; however, parameter $fieldmap_id of Object_Sync_Sf_Sync_Transients::set() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

151
			$result = $this->set( $operation, $object_type, /** @scrutinizer ignore-type */ $fieldmap_id, $legacy_value );
Loading history...
152
			if ( true === $result ) {
153
				$this->legacy_delete( $key );
154
			}
155
		}
156
		return $result;
157
	}
158
159
	/**
160
	 * Get individual transient records for sync operations
161
	 *
162
	 * @param string $operation what is the option related to? last pull, current pull, merge, delete, etc.
163
	 * @param string $object_type the WordPress or Salesforce object type.
164
	 * @param int    $fieldmap_id the ID of the specific fieldmap that is running.
165
	 * @param mixed  $default the default value for the transient.
166
	 * @return mixed $value the value of the item. False if it's empty.
167
	 */
168
	public function get( $operation, $object_type = '', $fieldmap_id = '', $default = false ) {
169
		// generate the transient key parameters.
170
		$params = array(
171
			'operation'   => $operation,
172
			'object_type' => $object_type,
173
			'fieldmap_id' => $fieldmap_id,
174
		);
175
		$key    = $this->generate_transient_key( $params );
176
		$value  = get_transient( $key );
177
178
		/*
179
		 * examples
180
		 * object_sync_for_salesforce_pull_last_sync_Contact_1
181
		 * object_sync_for_salesforce_currently_pulling_query_Contact_1
182
		 * object_sync_for_salesforce_pull_merge_last_Contact_1
183
		 * object_sync_for_salesforce_pull_delete_last_Contact_1
184
		 */
185
186
		// if the new transient value does exist but it has a default value, try to upgrade the old one.
187
		if ( get_transient( $key ) && $default === $value ) {
188
			$legacy_key = $this->generate_transient_key( $params, true );
189
			// if the keys are not the same, we might need to upgrade.
190
			if ( $key !== $legacy_key ) {
191
				$this->legacy_transient_upgrade( $operation, $object_type, $fieldmap_id, $value );
0 ignored issues
show
Bug introduced by
It seems like $fieldmap_id can also be of type string; however, parameter $fieldmap_id of Object_Sync_Sf_Sync_Tran...acy_transient_upgrade() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

191
				$this->legacy_transient_upgrade( $operation, $object_type, /** @scrutinizer ignore-type */ $fieldmap_id, $value );
Loading history...
Deprecated Code introduced by
The function Object_Sync_Sf_Sync_Tran...acy_transient_upgrade() has been deprecated: this was added in 2.1.0 to upgrade old transient keys, but will be removed in a future version. ( Ignorable by Annotation )

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

191
				/** @scrutinizer ignore-deprecated */ $this->legacy_transient_upgrade( $operation, $object_type, $fieldmap_id, $value );

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

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

Loading history...
192
			}
193
		}
194
		return $value;
195
	}
196
197
	/**
198
	 * Get legacy named individual transiuent records for sync operations
199
	 *
200
	 * @param string $operation what is the transient related to? last pull, current pull, merge, delete, etc.
201
	 * @param string $object_type the WordPress or Salesforce object type.
202
	 * @param int    $fieldmap_id the ID of the specific fieldmap that is running.
203
	 * @return mixed $value the value of the item. False if it's empty.
204
	 */
205
	public function legacy_get( $operation, $object_type = '', $fieldmap_id ) {
206
		// generate the transient key parameters.
207
		$params = array(
208
			'operation'   => $operation,
209
			'object_type' => $object_type,
210
			'fieldmap_id' => $fieldmap_id,
211
		);
212
		$key    = $this->generate_transient_key( $params, true );
213
		$value  = get_transient( $key );
214
		return $value;
215
	}
216
217
	/**
218
	 * Delete the individual transient records for sync operation
219
	 *
220
	 * @param string $operation what is the transient related to? last pull, current pull, merge, delete, etc.
221
	 * @param string $object_type the WordPress or Salesforce object type.
222
	 * @param int    $fieldmap_id the ID of the specific fieldmap that is running.
223
	 * @return bool  $result True if successful, false otherwise.
224
	 */
225
	public function delete( $operation, $object_type = '', $fieldmap_id = '' ) {
226
		// generate the transient key parameters.
227
		$params = array(
228
			'operation'   => $operation,
229
			'object_type' => $object_type,
230
			'fieldmap_id' => $fieldmap_id,
231
		);
232
		$key    = $this->generate_transient_key( $params );
233
		$result = delete_transient( $key );
234
		return $result;
235
	}
236
237
	/**
238
	 * Delete the legacy individual transient records for sync operation
239
	 *
240
	 * @param string $key the legacy key to delete.
241
	 * @return bool  $result True if successful, false otherwise.
242
	 */
243
	public function legacy_delete( $key ) {
244
		$result = delete_transient( $key );
245
		if ( true === $result ) {
246
			$this->remove_upgradeable_key( $key );
247
		}
248
		return $result;
249
	}
250
251
	/**
252
	 * Add an transient key to the array of upgradeable keys.
253
	 *
254
	 * @param string $key the key to add to the array.
255
	 * @return array $this->upgradeable_keys the array of keys.
256
	 */
257
	private function add_upgradeable_key( $key ) {
258
		$keys   = $this->get_upgradeable_keys();
259
		$keys[] = $key;
260
		$keys   = array_unique( $keys );
261
		$result = update_option( $this->option_prefix . 'upgradeable_keys', $keys );
262
		if ( true === $result ) {
263
			$this->upgradeable_keys = $keys;
0 ignored issues
show
Documentation Bug introduced by
It seems like $keys of type array is incompatible with the declared type string of property $upgradeable_keys.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
264
			return $this->upgradeable_keys;
265
		}
266
	}
267
268
	/**
269
	 * Remove a transient key from the array of upgradeable keys.
270
	 *
271
	 * @param string $key the key to remove from the array.
272
	 * @return array $this->upgradeable_keys the array of keys.
273
	 */
274
	private function remove_upgradeable_key( $key ) {
275
		$keys      = $this->get_upgradeable_keys();
276
		$array_key = array_search( $key, $keys, true );
277
		if ( false !== $array_key ) {
278
			unset( $keys[ $array_key ] );
279
		}
280
		$result = update_option( $this->option_prefix . 'upgradeable_keys', $keys );
281
		if ( true === $result ) {
282
			$this->upgradeable_keys = $keys;
0 ignored issues
show
Documentation Bug introduced by
It seems like $keys of type array is incompatible with the declared type string of property $upgradeable_keys.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
283
			if ( empty( $keys ) ) {
284
				delete_option( $this->option_prefix . 'upgradeable_keys' );
285
			}
286
			return $this->upgradeable_keys;
287
		}
288
	}
289
290
	/**
291
	 * Get the array of upgradeable keys.
292
	 *
293
	 * @return array $this->upgradeable_keys the array of keys.
294
	 */
295
	private function get_upgradeable_keys() {
296
		$keys                   = get_option( $this->option_prefix . 'upgradeable_keys', array() );
297
		$keys                   = array_unique( $keys );
0 ignored issues
show
Bug introduced by
It seems like $keys can also be of type false; however, parameter $array of array_unique() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

297
		$keys                   = array_unique( /** @scrutinizer ignore-type */ $keys );
Loading history...
298
		$this->upgradeable_keys = $keys;
0 ignored issues
show
Documentation Bug introduced by
It seems like $keys of type array is incompatible with the declared type string of property $upgradeable_keys.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
299
		return $this->upgradeable_keys;
300
	}
301
}
302