PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.5.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.5.0
4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / app / src / Sync / ImportState.php
surecart / app / src / Sync Last commit date
Concerns 6 months ago Jobs 1 year ago Tasks 1 year ago WooCommerce 2 weeks ago BatchCheckService.php 6 months ago ContentSyncService.php 6 months ago CustomerSyncService.php 1 year ago ImportState.php 2 months ago PostSyncService.php 2 days ago ProductSyncService.php 1 year ago ProductsSyncService.php 1 year ago StoreSyncService.php 1 year ago SyncService.php 2 months ago SyncServiceProvider.php 2 months ago
ImportState.php
203 lines
1 <?php
2
3 namespace SureCart\Sync;
4
5 /**
6 * Centralized state management for background import processes.
7 *
8 * Encapsulates WordPress options and transients used to track import progress
9 * across background job batches. Designed to be reusable for different import
10 * types (WooCommerce, Shopify, EDD, etc.) via the $type constructor parameter.
11 *
12 * Key prefixing: all storage keys follow the pattern sc_{type}_import_{suffix}.
13 *
14 * Note: Not concurrency-safe. Relies on the single-import constraint
15 * (only one import of a given type runs at a time, enforced by isRunning()).
16 */
17 final class ImportState {
18
19 /**
20 * Import type prefix, e.g. 'woo' → keys are sc_woo_import_*.
21 *
22 * @var string
23 */
24 private string $type;
25
26 /**
27 * Constructor.
28 *
29 * @param string $type Import type prefix (e.g. 'woo').
30 */
31 public function __construct( string $type ) {
32 $this->type = $type;
33 }
34
35 /**
36 * Build a prefixed storage key.
37 *
38 * @param string $suffix Key suffix (e.g. 'ids', 'session_id', 'all_skipped').
39 *
40 * @return string Full key like 'sc_woo_import_ids'.
41 */
42 private function key( string $suffix ): string {
43 return "sc_{$this->type}_import_{$suffix}";
44 }
45
46 // --- Session ---
47
48 /**
49 * Get or create the session ID for this import run.
50 * Matches current behavior: lazy session creation on first call.
51 *
52 * @return string Session ID (UUID).
53 */
54 public function getOrCreateSessionId(): string {
55 $session_id = get_option( $this->key( 'session_id' ) );
56 if ( ! $session_id ) {
57 $session_id = wp_generate_uuid4();
58 update_option( $this->key( 'session_id' ), $session_id, false );
59 }
60 return $session_id;
61 }
62
63 /**
64 * Get the current session ID without creating one.
65 *
66 * @return string|null Session ID or null if not set.
67 */
68 public function getSessionId(): ?string {
69 $session_id = get_option( $this->key( 'session_id' ) );
70 return $session_id ? $session_id : null;
71 }
72
73 // --- Result IDs ---
74
75 /**
76 * Append an import batch ID to the accumulated results.
77 *
78 * Not concurrency-safe: read-modify-write. Safe under single-import constraint (isRunning() guard).
79 *
80 * @param string $id The import ID to append.
81 *
82 * @return void
83 */
84 public function appendResultId( string $id ): void {
85 $existing_ids = get_option( $this->key( 'ids' ), [] );
86 $existing_ids[] = sanitize_key( $id );
87 update_option( $this->key( 'ids' ), $existing_ids, false );
88 }
89
90 /**
91 * Get all accumulated import result IDs.
92 *
93 * @return array Array of import IDs.
94 */
95 public function getResultIds(): array {
96 return get_option( $this->key( 'ids' ), [] );
97 }
98
99 // --- Skipped items (transient, 7-day TTL) ---
100
101 /**
102 * Merge skipped items into the session's transient.
103 *
104 * Session is lazily created here to match existing behavior where the first
105 * batch with skipped items creates the session.
106 *
107 * @param array $items Array of skipped item data.
108 *
109 * @return void
110 */
111 public function addSkippedItems( array $items ): void {
112 if ( empty( $items ) ) {
113 return;
114 }
115
116 $session_id = $this->getOrCreateSessionId();
117 $transient_key = $this->key( 'skipped_' ) . $session_id;
118
119 // Merge with any previously stored skipped items from earlier batches.
120 $existing = get_transient( $transient_key );
121 if ( ! is_array( $existing ) ) {
122 $existing = [];
123 }
124
125 set_transient( $transient_key, array_merge( $existing, $items ), 7 * DAY_IN_SECONDS );
126 }
127
128 /**
129 * Get skipped items for the current session.
130 *
131 * @return array Array of skipped items, or empty array if no session exists.
132 */
133 public function getSkippedItems(): array {
134 $session_id = $this->getSessionId();
135 if ( ! $session_id ) {
136 return [];
137 }
138 return $this->getSkippedItemsBySession( $session_id );
139 }
140
141 /**
142 * Get skipped items by arbitrary session ID.
143 *
144 * @param string $session_id The session ID to look up.
145 *
146 * @return array Array of skipped items.
147 */
148 public function getSkippedItemsBySession( string $session_id ): array {
149 $transient_key = $this->key( 'skipped_' ) . $session_id;
150 $items = get_transient( $transient_key );
151 return is_array( $items ) ? $items : [];
152 }
153
154 // --- All-skipped flag ---
155
156 /**
157 * Mark this import as all-skipped (stores current session ID).
158 *
159 * @return void
160 */
161 public function markAllSkipped(): void {
162 $session_id = $this->getOrCreateSessionId();
163 update_option( $this->key( 'all_skipped' ), $session_id, false );
164 }
165
166 /**
167 * Check if all products were skipped.
168 *
169 * @return bool
170 */
171 public function isAllSkipped(): bool {
172 return (bool) get_option( $this->key( 'all_skipped' ) );
173 }
174
175 /**
176 * Get the session ID stored in the all-skipped flag.
177 *
178 * @return string|null Session ID or null if not set.
179 */
180 public function getAllSkippedSessionId(): ?string {
181 $session_id = get_option( $this->key( 'all_skipped' ) );
182 return $session_id ? $session_id : null;
183 }
184
185 // --- Lifecycle ---
186
187 /**
188 * Clear all option-based state.
189 *
190 * Deletes sc_{type}_import_ids, sc_{type}_import_session_id, sc_{type}_import_all_skipped.
191 *
192 * Only deletes options, not transients. Skipped items transient expires via 7-day TTL.
193 * This matches the current dispatch() and importResults() cleanup behavior.
194 *
195 * @return void
196 */
197 public function reset(): void {
198 delete_option( $this->key( 'ids' ) );
199 delete_option( $this->key( 'session_id' ) );
200 delete_option( $this->key( 'all_skipped' ) );
201 }
202 }
203