PluginProbe
Packeta / 2.3.2
Packeta v2.3.2
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
← All changes | src/Packetery/Module/Upgrade.php +214 -134 1.42.3.2 View file →
@@ -11,8 +11,12 @@
11 11
12 12 use Packetery\Core;
13 13 use Packetery\Core\Log\ILogger;
14 14 use Packetery\Core\Log\Record;
15 +use Packetery\Module\Carrier\EntityRepository;
16 +use Packetery\Module\Options\OptionNames;
17 +use Packetery\Module\Options\OptionsProvider;
18 +use Packetery\Module\Upgrade\Version_1_4_2;
15 19
16 20 /**
17 21 * Class Upgrade.
18 22 */
@@ -72,38 +76,53 @@
72 76 */
73 77 private $carrierRepository;
74 78
75 79 /**
76 - * WPDB.
80 + * Customs declaration repository.
77 81 *
78 - * @var \wpdb
82 + * @var CustomsDeclaration\Repository
79 83 */
80 - private $wpdb;
84 + private $customsDeclarationRepository;
81 85
82 86 /**
83 - * Constructor.
87 + * WpdbAdapter.
84 88 *
85 - * @param Order\Repository $orderRepository Order repository.
86 - * @param MessageManager $messageManager Message manager.
87 - * @param ILogger $logger Logger.
88 - * @param Log\Repository $logRepository Log repository.
89 - * @param \wpdb $wpdb WPDB.
90 - * @param Carrier\Repository $carrierRepository Carrier repository.
89 + * @var WpdbAdapter
91 90 */
91 + private $wpdbAdapter;
92 +
93 + /**
94 + * Options provider.
95 + *
96 + * @var OptionsProvider
97 + */
98 + private $optionsProvider;
99 +
100 + /**
101 + * @var EntityRepository
102 + */
103 + private $carrierEntityRepository;
104 +
92 105 public function __construct(
93 106 Order\Repository $orderRepository,
94 107 MessageManager $messageManager,
95 108 ILogger $logger,
96 109 Log\Repository $logRepository,
97 - \wpdb $wpdb,
98 - Carrier\Repository $carrierRepository
110 + WpdbAdapter $wpdbAdapter,
111 + Carrier\Repository $carrierRepository,
112 + CustomsDeclaration\Repository $customsDeclarationRepository,
113 + OptionsProvider $optionsProvider,
114 + EntityRepository $carrierEntityRepository
99 115 ) {
100 - $this->orderRepository = $orderRepository;
101 - $this->messageManager = $messageManager;
102 - $this->logger = $logger;
103 - $this->logRepository = $logRepository;
104 - $this->wpdb = $wpdb;
105 - $this->carrierRepository = $carrierRepository;
116 + $this->orderRepository = $orderRepository;
117 + $this->messageManager = $messageManager;
118 + $this->logger = $logger;
119 + $this->logRepository = $logRepository;
120 + $this->wpdbAdapter = $wpdbAdapter;
121 + $this->carrierRepository = $carrierRepository;
122 + $this->customsDeclarationRepository = $customsDeclarationRepository;
123 + $this->optionsProvider = $optionsProvider;
124 + $this->carrierEntityRepository = $carrierEntityRepository;
106 125 }
107 126
108 127 /**
109 128 * Checks previous plugin version and runs upgrade if needed.
@@ -111,88 +130,120 @@
111 130 *
112 131 * @return void
113 132 */
114 133 public function check(): void {
115 - $oldVersion = get_option( 'packetery_version' );
116 - if ( Plugin::VERSION === $oldVersion ) {
134 + $oldVersion = get_option( OptionNames::VERSION );
135 + if ( $oldVersion === Plugin::VERSION ) {
117 136 return;
118 137 }
119 138
120 - $this->logRepository->createTable();
121 - $createResult = $this->carrierRepository->createTable();
122 - if ( false === $createResult ) {
123 - $lastError = $this->wpdb->last_error;
124 - $this->messageManager->flash_message( __( 'Database carrier table was not created, you can find more information in Packeta log.', 'packeta' ), MessageManager::TYPE_ERROR );
139 + $this->runCreateTables();
125 140
126 - $record = new Record();
127 - $record->action = Record::ACTION_CARRIER_TABLE_NOT_CREATED;
128 - $record->status = Record::STATUS_ERROR;
129 - $record->title = __( 'Database carrier table was not created.', 'packeta' );
130 - $record->params = [
131 - 'errorMessage' => $lastError,
132 - ];
133 - $this->logger->add( $record );
134 - }
141 + // If no previous version detected, no upgrade will be run.
142 + if ( $oldVersion !== null && $oldVersion !== false ) {
143 + if ( version_compare( $oldVersion, '1.2.0', '<' ) ) {
144 + $logEntries = get_posts(
145 + [
146 + 'post_type' => 'packetery_log',
147 + 'post_status' => 'any',
148 + 'nopaging' => true,
149 + 'fields' => 'ids',
150 + ]
151 + );
152 + foreach ( $logEntries as $logEntryId ) {
153 + wp_delete_post( $logEntryId, true );
154 + }
135 155
136 - $createResult = $this->orderRepository->createTable();
137 - if ( false === $createResult ) {
138 - $lastError = $this->wpdb->last_error;
139 - $this->messageManager->flash_message( __( 'Database order table was not created, you can find more information in Packeta log.', 'packeta' ), MessageManager::TYPE_ERROR );
156 + unregister_post_type( 'packetery_log' );
140 157
141 - $record = new Record();
142 - $record->action = Record::ACTION_ORDER_TABLE_NOT_CREATED;
143 - $record->status = Record::STATUS_ERROR;
144 - $record->title = __( 'Database order table was not created.', 'packeta' );
145 - $record->params = [
146 - 'errorMessage' => $lastError,
147 - ];
148 - $this->logger->add( $record );
149 - }
158 + $this->migrateWpOrderMetadata();
159 + $addressEntries = get_posts(
160 + [
161 + 'post_type' => self::POST_TYPE_VALIDATED_ADDRESS,
162 + 'post_status' => 'any',
163 + 'nopaging' => true,
164 + 'fields' => 'ids',
165 + ]
166 + );
167 + foreach ( $addressEntries as $addressEntryId ) {
168 + wp_delete_post( $addressEntryId, true );
169 + }
150 170
151 - // If no previous version detected, no upgrade will be run.
152 - if ( $oldVersion && version_compare( $oldVersion, '1.2.0', '<' ) ) {
153 - $logEntries = get_posts(
154 - [
155 - 'post_type' => 'packetery_log',
156 - 'post_status' => 'any',
157 - 'nopaging' => true,
158 - 'fields' => 'ids',
159 - ]
160 - );
161 - foreach ( $logEntries as $logEntryId ) {
162 - wp_delete_post( $logEntryId, true );
171 + unregister_post_type( self::POST_TYPE_VALIDATED_ADDRESS );
163 172 }
164 173
165 - unregister_post_type( 'packetery_log' );
174 + if ( version_compare( $oldVersion, '1.2.6', '<' ) ) {
175 + $this->orderRepository->deleteOrphans();
176 + }
166 177
167 - $this->migrateWpOrderMetadata();
168 - $addressEntries = get_posts(
169 - [
170 - 'post_type' => self::POST_TYPE_VALIDATED_ADDRESS,
171 - 'post_status' => 'any',
172 - 'nopaging' => true,
173 - 'fields' => 'ids',
174 - ]
175 - );
176 - foreach ( $addressEntries as $addressEntryId ) {
177 - wp_delete_post( $addressEntryId, true );
178 + if ( version_compare( $oldVersion, '1.4.2', '<' ) ) {
179 + $migration = new Version_1_4_2( $this->wpdbAdapter );
180 + $migration->run();
178 181 }
179 182
180 - unregister_post_type( self::POST_TYPE_VALIDATED_ADDRESS );
181 - }
183 + if ( version_compare( $oldVersion, '1.5', '<' ) ) {
184 + wp_clear_scheduled_hook( CronService::CRON_CARRIERS_HOOK );
185 + }
182 186
183 - if ( $oldVersion && version_compare( $oldVersion, '1.2.6', '<' ) ) {
184 - $this->orderRepository->deleteOrphans();
187 + if ( version_compare( $oldVersion, '1.6.0', '<' ) ) {
188 + wp_clear_scheduled_hook( CronService::CRON_LOG_AUTO_DELETION_HOOK );
189 + wp_clear_scheduled_hook( CronService::CRON_PACKET_STATUS_SYNC_HOOK );
190 + }
191 +
192 + if ( version_compare( $oldVersion, '1.7.0', '<' ) ) {
193 + $orderStatusAutoChange = $this->optionsProvider->isOrderStatusAutoChangeEnabled();
194 + $autoOrderStatus = $this->optionsProvider->getAutoOrderStatus();
195 + $syncSettings = $this->optionsProvider->getOptionsByName( OptionNames::PACKETERY_SYNC );
196 + if ( $orderStatusAutoChange ) {
197 + $syncSettings['allow_order_status_change'] = true;
198 + }
199 + if ( $autoOrderStatus !== null ) {
200 + $syncSettings['order_status_change_packet_statuses'] = [
201 + Core\Entity\PacketStatus::RECEIVED_DATA => $autoOrderStatus,
202 + ];
203 + }
204 +
205 + update_option( OptionNames::PACKETERY_SYNC, $syncSettings );
206 + }
207 +
208 + if ( version_compare( $oldVersion, '1.7.1', '<' ) ) {
209 + $syncSettings = $this->optionsProvider->getOptionsByName( OptionNames::PACKETERY_SYNC );
210 + if (
211 + isset( $syncSettings['order_status_change_packet_statuses'][ Core\Entity\PacketStatus::RECEIVED_DATA ] ) &&
212 + $syncSettings['order_status_change_packet_statuses'][ Core\Entity\PacketStatus::RECEIVED_DATA ] === ''
213 + ) {
214 + unset( $syncSettings['order_status_change_packet_statuses'][ Core\Entity\PacketStatus::RECEIVED_DATA ] );
215 + update_option( OptionNames::PACKETERY_SYNC, $syncSettings );
216 + }
217 + }
218 +
219 + if ( version_compare( $oldVersion, '1.8.0', '<' ) ) {
220 + $generalSettings = $this->optionsProvider->getOptionsByName( OptionNames::PACKETERY );
221 + if ( isset( $generalSettings['cod_payment_method'] ) ) {
222 + $generalSettings['cod_payment_methods'] = [ $generalSettings['cod_payment_method'] ];
223 + unset( $generalSettings['cod_payment_method'] );
224 + }
225 +
226 + update_option( OptionNames::PACKETERY, $generalSettings );
227 + }
228 +
229 + if ( version_compare( $oldVersion, '2.1.0', '<' ) ) {
230 + add_option( OptionNames::PACKETERY_TUTORIAL_ORDER_DETAIL_EDIT_PACKET, 0 );
231 + add_option( OptionNames::PACKETERY_TUTORIAL_ORDER_GRID_EDIT_PACKET, 0 );
232 + }
233 + } else {
234 + add_option( OptionNames::PACKETERY_TUTORIAL_ORDER_DETAIL_EDIT_PACKET, 1 );
235 + add_option( OptionNames::PACKETERY_TUTORIAL_ORDER_GRID_EDIT_PACKET, 1 );
185 236 }
186 237
187 - if ( $oldVersion && version_compare( $oldVersion, '1.4', '<' ) ) {
188 - $this->logRepository->addOrderIdColumn();
189 - $this->orderRepository->addAdultContentColumn();
190 - $this->orderRepository->addValueColumn();
191 - $this->orderRepository->addCodColumn();
192 - }
238 + update_option( OptionNames::VERSION, Plugin::VERSION );
239 + }
193 240
194 - update_option( 'packetery_version', Plugin::VERSION );
241 + public function runCreateTables(): void {
242 + $this->createLogTable();
243 + $this->createCarrierTable();
244 + $this->createOrderTable();
245 + $this->createCustomsDeclarationTables();
195 246 }
196 247
197 248 /**
198 249 * Migrates WP order metadata.
@@ -199,30 +250,26 @@
199 250 *
200 251 * @return void
201 252 */
202 253 private function migrateWpOrderMetadata(): void {
203 - global $wpdb;
254 + $this->createOrderTable();
204 255
205 - $createResult = $this->orderRepository->createTable();
206 - if ( false === $createResult ) {
207 - $lastError = $wpdb->last_error;
208 - $this->messageManager->flash_message( __( 'Database order table was not created, you can find more information in Packeta log.', 'packeta' ), MessageManager::TYPE_ERROR );
209 -
210 - $record = new Record();
211 - $record->action = Record::ACTION_ORDER_TABLE_NOT_CREATED;
212 - $record->status = Record::STATUS_ERROR;
213 - $record->title = __( 'Database order table was not created.', 'packeta' );
214 - $record->params = [
215 - 'errorMessage' => $lastError,
216 - ];
217 - $this->logger->add( $record );
218 - }
219 -
220 256 // Did not work when called from plugins_loaded hook.
221 257 $orders = wc_get_orders(
222 258 [
223 - 'packetery_all' => '1',
224 - 'nopaging' => true,
259 + 'nopaging' => true,
260 + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
261 + 'meta_query' => [
262 + [
263 + 'key' => self::META_CARRIER_ID,
264 + 'compare' => 'EXISTS',
265 + ],
266 + [
267 + 'key' => self::META_CARRIER_ID,
268 + 'compare' => '!=',
269 + 'value' => '',
270 + ],
271 + ],
225 272 ]
226 273 );
227 274
228 275 foreach ( $orders as $order ) {
@@ -227,9 +274,9 @@
227 274
228 275 foreach ( $orders as $order ) {
229 276 $orderEntity = new Core\Entity\Order(
230 277 (string) $order->get_id(),
231 - $this->getMetaAsNullableString( $order, self::META_CARRIER_ID )
278 + $this->carrierEntityRepository->getAnyById( $this->getMetaAsNullableString( $order, self::META_CARRIER_ID ) )
232 279 );
233 280 $order->delete_meta_data( self::META_CARRIER_ID );
234 281
235 282 $orderEntity->setWeight( $this->getMetaAsNullableFloat( $order, self::META_WEIGHT ) );
@@ -260,12 +307,13 @@
260 307 $order->delete_meta_data( self::META_LENGTH );
261 308 $order->delete_meta_data( self::META_WIDTH );
262 309 $order->delete_meta_data( self::META_HEIGHT );
263 310
264 - if ( null !== $this->getMetaAsNullableString( $order, self::META_POINT_ID ) ) {
311 + if ( $this->getMetaAsNullableString( $order, self::META_POINT_ID ) !== null ) {
265 312 $orderEntity->setPickupPoint(
266 313 new Core\Entity\PickupPoint(
267 314 $this->getMetaAsNullableString( $order, self::META_POINT_ID ),
315 + null,
268 316 $this->getMetaAsNullableString( $order, self::META_POINT_NAME ),
269 317 $this->getMetaAsNullableString( $order, self::META_POINT_CITY ),
270 318 $this->getMetaAsNullableString( $order, self::META_POINT_ZIP ),
271 319 $this->getMetaAsNullableString( $order, self::META_POINT_STREET ),
@@ -280,9 +328,9 @@
280 328 $order->delete_meta_data( self::META_POINT_STREET );
281 329 $order->delete_meta_data( self::META_POINT_URL );
282 330
283 331 $validatedAddressId = $this->getValidatedAddressIdByOrderId( (int) $order->get_id() );
284 - if ( $validatedAddressId ) {
332 + if ( $validatedAddressId !== null ) {
285 333 $validatedAddress = $this->createAddressFromPostId( $validatedAddressId );
286 334 $orderEntity->setAddressValidated( true );
287 335 $orderEntity->setDeliveryAddress( $validatedAddress );
288 336 }
@@ -287,8 +335,9 @@
287 335 $orderEntity->setDeliveryAddress( $validatedAddress );
288 336 }
289 337
290 338 $this->orderRepository->save( $orderEntity );
339 + // Ignore errors. Save the metadata even if the previous call fails.
291 340 $order->save_meta_data();
292 341 }
293 342 }
294 343
@@ -331,9 +380,9 @@
331 380 'post_parent' => $orderId,
332 381 ]
333 382 );
334 383
335 - if ( empty( $postIds ) ) {
384 + if ( count( $postIds ) === 0 ) {
336 385 return null;
337 386 }
338 387
339 388 return (int) array_shift( $postIds );
@@ -348,9 +397,10 @@
348 397 * @return string|null
349 398 */
350 399 private function getMetaAsNullableString( \WC_Order $order, string $key ): ?string {
351 400 $value = $order->get_meta( $key, true );
352 - return ( ( null !== $value && '' !== $value ) ? (string) $value : null );
401 +
402 + return ( ( $value !== null && $value !== '' ) ? (string) $value : null );
353 403 }
354 404
355 405 /**
356 406 * Gets meta property of order as float.
@@ -361,51 +411,81 @@
361 411 * @return float|null
362 412 */
363 413 private function getMetaAsNullableFloat( \WC_Order $order, string $key ): ?float {
364 414 $value = $order->get_meta( $key, true );
365 - return ( ( null !== $value && '' !== $value ) ? (float) $value : null );
415 +
416 + return ( ( $value !== null && $value !== '' ) ? (float) $value : null );
366 417 }
367 418
368 419 /**
369 - * Transforms custom query variable to meta query.
420 + * Creates log table.
370 421 *
371 - * @param array $queryVars Query vars.
372 - * @param array $get Input values.
422 + * @return void
423 + */
424 + private function createLogTable(): void {
425 + if ( $this->logRepository->createOrAlterTable() === false ) {
426 + $this->messageManager->flash_message(
427 + // translators: %s: Short table name.
428 + sprintf( __( 'Database %s table could not be created or altered, more information might be found in WooCommerce logs.', 'packeta' ), 'log' ),
429 + MessageManager::TYPE_ERROR
430 + );
431 + }
432 + }
433 +
434 + /**
435 + * Creates carrier table.
373 436 *
374 - * @return array
437 + * @return void
375 438 */
376 - public function handleCustomQueryVar( array $queryVars, array $get ): array {
377 - $metaQuery = $this->addQueryVars( ( $queryVars['meta_query'] ?? [] ), $get );
378 - if ( $metaQuery ) {
379 - // @codingStandardsIgnoreStart
380 - $queryVars['meta_query'] = $metaQuery;
381 - // @codingStandardsIgnoreEnd
439 + private function createCarrierTable(): void {
440 + if ( $this->carrierRepository->createOrAlterTable() === false ) {
441 + $this->flashAndLog( 'carrier', Record::ACTION_CARRIER_TABLE_NOT_CREATED );
382 442 }
443 + }
383 444
384 - return $queryVars;
445 + /**
446 + * Creates order table.
447 + *
448 + * @return void
449 + */
450 + private function createOrderTable(): void {
451 + if ( $this->orderRepository->createOrAlterTable() === false ) {
452 + $this->flashAndLog( 'order', Record::ACTION_ORDER_TABLE_NOT_CREATED );
453 + }
385 454 }
386 455
387 456 /**
388 - * Adds query vars to fetch order list.
457 + * Creates order table.
389 458 *
390 - * @param array $queryVars Query vars.
391 - * @param array $get Get parameters.
392 - *
393 - * @return array
459 + * @return void
394 460 */
395 - private function addQueryVars( array $queryVars, array $get ): array {
396 - if ( ! empty( $get['packetery_all'] ) ) {
397 - $queryVars[] = [
398 - 'key' => self::META_CARRIER_ID,
399 - 'compare' => 'EXISTS',
400 - ];
401 - $queryVars[] = [
402 - 'key' => self::META_CARRIER_ID,
403 - 'value' => '',
404 - 'compare' => '!=',
405 - ];
461 + private function createCustomsDeclarationTables(): void {
462 + if ( $this->customsDeclarationRepository->createOrAlterTable() === false ) {
463 + $this->flashAndLog( 'customs_declaration', Record::ACTION_CUSTOMS_DECLARATION_TABLE_NOT_CREATED );
406 464 }
407 465
408 - return $queryVars;
466 + if ( $this->customsDeclarationRepository->createOrAlterItemTable() === false ) {
467 + $this->flashAndLog( 'customs_declaration_item', Record::ACTION_CUSTOMS_DECLARATION_ITEM_TABLE_NOT_CREATED );
468 + }
409 469 }
410 470
471 + /**
472 + * Flashes error and logs to Packeta log.
473 + *
474 + * @param string $table Short table name.
475 + * @param string $action Log action.
476 + *
477 + * @return void
478 + */
479 + private function flashAndLog( string $table, string $action ): void {
480 + // translators: %s: Short table name.
481 + $flashMessage = sprintf( __( 'Database %s table of Packeta plugin could not be created or altered, you can find more information in Packeta log.', 'packeta' ), $table );
482 + $this->messageManager->flash_message( $flashMessage, MessageManager::TYPE_ERROR );
483 +
484 + $record = new Record();
485 + $record->action = $action;
486 + $record->status = Record::STATUS_ERROR;
487 + // translators: %s: Short table name.
488 + $record->title = sprintf( __( 'Database %s table could not be created or altered, more information might be found in WooCommerce logs.', 'packeta' ), $table );
489 + $this->logger->add( $record );
490 + }
411 491 }