PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.19
ووسلام – همگام سازی ووکامرس و باسلام v1.10.19
1.10.19 1.10.20 1.10.18 1.10.17 1.10.15 1.10.14 1.10.13 1.10.12 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.2 1.9.1 1.9.0 1.8.8 1.8.5 1.8.6 All 53 releases
← All changes | JobManager.php +59 -13 1.9.11.10.19 View file →
@@ -23,25 +23,33 @@
23 23 public function createJob($jobType, $status = 'pending', $payload = null, $maxAttempts = 3)
24 24 {
25 25 global $wpdb;
26 26
27 - return $wpdb->insert(
28 - $this->jobManagerTableName,
29 - array(
30 - 'job_type' => $jobType,
31 - 'status' => $status,
27 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom plugin table; no object cache for these operational queries.
28 + $result = $wpdb->insert(
29 + $this->jobManagerTableName,
30 + array(
31 + 'job_type' => $jobType,
32 + 'status' => $status,
32 33 'payload' => $payload,
33 34 'attempts' => 0,
34 35 'max_attempts' => $maxAttempts,
35 - 'created_at' => time(),
36 - )
37 - );
38 - }
36 + 'created_at' => time(),
37 + )
38 + );
39 +
40 + if ($result !== false) {
41 + do_action('sync_basalam_job_created', $jobType, $status, $payload);
42 + }
43 +
44 + return $result;
45 + }
39 46
40 47 public function getNextEligibleJob(string $jobType): ?object
41 48 {
42 49 global $wpdb;
43 50
51 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom plugin table; identifier from $wpdb->prefix, not user input.
44 52 return $wpdb->get_row($wpdb->prepare(
45 53 "SELECT * FROM {$this->jobManagerTableName}
46 54 WHERE job_type = %s
47 55 AND status = 'pending'
@@ -56,10 +64,36 @@
56 64 public function hasAnyProcessingJob(): bool
57 65 {
58 66 return $this->getCountJobs(['status' => 'processing']) > 0;
59 67 }
60 -
61 - public function getJob($where = array())
68 +
69 + public function hasPendingOrStaleProcessingJobs(int $staleProcessingTimeoutSeconds = 120): bool
70 + {
71 + global $wpdb;
72 +
73 + $now = time();
74 + $staleBefore = $now - $staleProcessingTimeoutSeconds;
75 +
76 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom plugin table; identifier from $wpdb->prefix, not user input.
77 + $result = $wpdb->get_var($wpdb->prepare(
78 + "SELECT 1 FROM {$this->jobManagerTableName}
79 + WHERE (
80 + status = 'pending'
81 + AND (retry_after IS NULL OR retry_after <= %d)
82 + ) OR (
83 + status = 'processing'
84 + AND started_at IS NOT NULL
85 + AND started_at < %d
86 + )
87 + LIMIT 1",
88 + $now,
89 + $staleBefore
90 + ));
91 +
92 + return (string) $result === '1';
93 + }
94 +
95 + public function getJob($where = array())
62 96 {
63 97 global $wpdb;
64 98
65 99 if (empty($where)) return null;
@@ -68,9 +102,9 @@
68 102 $values = [];
69 103
70 104 foreach ($where as $column => $value) {
71 105 if (!in_array($column, self::ALLOWED_COLUMNS, true)) {
72 - throw new \InvalidArgumentException("Invalid column: {$column}");
106 + throw new \InvalidArgumentException(esc_html("Invalid column: {$column}"));
73 107 }
74 108 $conditions[] = "{$column} = %s";
75 109 $values[] = $value;
76 110 }
@@ -76,8 +110,9 @@
76 110 }
77 111
78 112 $sql = "SELECT * FROM {$this->jobManagerTableName} WHERE " . implode(" AND ", $conditions) . " LIMIT 1";
79 113
114 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom plugin table; identifiers from $wpdb->prefix and whitelisted column list, not user input; values are prepared.
80 115 return $wpdb->get_row($wpdb->prepare($sql, $values));
81 116 }
82 117
83 118 public function getCountJobs($where = array())
@@ -90,9 +125,9 @@
90 125 $values = [];
91 126
92 127 foreach ($where as $column => $value) {
93 128 if (!in_array($column, self::ALLOWED_COLUMNS, true)) {
94 - throw new \InvalidArgumentException("Invalid column: {$column}");
129 + throw new \InvalidArgumentException(esc_html("Invalid column: {$column}"));
95 130 }
96 131 if (is_array($value)) {
97 132 $placeholders = array_fill(0, count($value), '%s');
98 133 $conditions[] = "{$column} IN (" . implode(',', $placeholders) . ")";
@@ -104,8 +139,9 @@
104 139 }
105 140
106 141 $sql = "SELECT COUNT(*) FROM {$this->jobManagerTableName} WHERE " . implode(" AND ", $conditions);
107 142
143 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom plugin table; identifiers from $wpdb->prefix and whitelisted column list, not user input; values are prepared.
108 144 return (int) $wpdb->get_var($wpdb->prepare($sql, $values));
109 145 }
110 146
111 147 public function updateJob($jobData, $where = array())
@@ -113,8 +149,9 @@
113 149 global $wpdb;
114 150
115 151 if (empty($where) || empty($jobData)) return false;
116 152
153 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom plugin table; no object cache for these operational queries.
117 154 return $wpdb->update($this->jobManagerTableName, $jobData, $where);
118 155 }
119 156
120 157 public function deleteJob($where = array())
@@ -122,8 +159,9 @@
122 159 global $wpdb;
123 160
124 161 if (empty($where)) return false;
125 162
163 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom plugin table; no object cache for these operational queries.
126 164 return $wpdb->delete($this->jobManagerTableName, $where);
127 165 }
128 166
129 167 public function ConvertStaleProcessingJobs($timeoutSeconds = 120)
@@ -131,8 +169,9 @@
131 169 global $wpdb;
132 170
133 171 $timeoutTimestamp = time() - $timeoutSeconds;
134 172
173 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom plugin table; identifier from $wpdb->prefix, not user input.
135 174 $wpdb->query(
136 175 $wpdb->prepare(
137 176 "UPDATE {$this->jobManagerTableName}
138 177 SET status = CASE
@@ -157,8 +196,9 @@
157 196 public function hasProductJobInProgress(int $productId, string $jobType): bool
158 197 {
159 198 global $wpdb;
160 199
200 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom plugin table; identifier from $wpdb->prefix, not user input.
161 201 $jobs = $wpdb->get_results($wpdb->prepare(
162 202 "SELECT payload FROM {$this->jobManagerTableName}
163 203 WHERE job_type = %s
164 204 AND (status = %s OR status = %s)",
@@ -186,8 +226,9 @@
186 226 public function retryJob(int $jobId, ?string $errorMessage = null): bool
187 227 {
188 228 global $wpdb;
189 229
230 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom plugin table; identifier from $wpdb->prefix, not user input.
190 231 $job = $wpdb->get_row($wpdb->prepare(
191 232 "SELECT * FROM {$this->jobManagerTableName} WHERE id = %d",
192 233 $jobId
193 234 ));
@@ -224,12 +265,15 @@
224 265 $delaySeconds = 30 * (int) pow(2, $newAttempts - 1);
225 266 $retryAfter = time() + $delaySeconds;
226 267
227 268 // Atomic DELETE + INSERT inside a transaction so a crash can't lose the job.
269 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Transaction control for atomic job requeue; no object cache applicable.
228 270 $wpdb->query('START TRANSACTION');
229 271 try {
272 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom plugin table; no object cache for these operational queries.
230 273 $wpdb->delete($this->jobManagerTableName, ['id' => $jobId]);
231 274
275 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom plugin table; no object cache for these operational queries.
232 276 $wpdb->insert(
233 277 $this->jobManagerTableName,
234 278 [
235 279 'job_type' => $job->job_type,
@@ -243,10 +287,12 @@
243 287 'started_at' => 0,
244 288 ]
245 289 );
246 290
291 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Transaction control for atomic job requeue; no object cache applicable.
247 292 $wpdb->query('COMMIT');
248 293 } catch (\Exception $e) {
294 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Transaction control for atomic job requeue; no object cache applicable.
249 295 $wpdb->query('ROLLBACK');
250 296 throw $e;
251 297 }
252 298