PluginProbe
Packeta / 1.5.1
Packeta v1.5.1
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
packeta / src / Packetery / Module / Upgrade.php

Upgrade.php in Packeta 1.5.1, at src/Packetery/Module/Upgrade.php

432 lines 12.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class Upgrade.
4 *
5 * @package Packetery\Module
6 */
7
8 declare( strict_types=1 );
9
10 namespace Packetery\Module;
11
12 use Packetery\Core;
13 use Packetery\Core\Log\ILogger;
14 use Packetery\Core\Log\Record;
15 use Packetery\Module\Upgrade\Version_1_4_2;
16
17 /**
18 * Class Upgrade.
19 */
20 class Upgrade {
21
22 const POST_TYPE_VALIDATED_ADDRESS = 'packetery_address';
23
24 const META_LENGTH = 'packetery_length';
25 const META_WIDTH = 'packetery_width';
26 const META_HEIGHT = 'packetery_height';
27 const META_PACKET_STATUS = 'packetery_packet_status';
28 const META_WEIGHT = 'packetery_weight';
29 const META_CARRIER_ID = 'packetery_carrier_id';
30 const META_IS_EXPORTED = 'packetery_is_exported';
31 const META_IS_LABEL_PRINTED = 'packetery_is_label_printed';
32 const META_CARRIER_NUMBER = 'packetery_carrier_number';
33 const META_PACKET_ID = 'packetery_packet_id';
34 const META_POINT_ID = 'packetery_point_id';
35 const META_POINT_NAME = 'packetery_point_name';
36 const META_POINT_CITY = 'packetery_point_city';
37 const META_POINT_ZIP = 'packetery_point_zip';
38 const META_POINT_STREET = 'packetery_point_street';
39 const META_POINT_URL = 'packetery_point_url';
40
41 /**
42 * Order repository.
43 *
44 * @var Order\Repository
45 */
46 private $orderRepository;
47
48 /**
49 * Message manager.
50 *
51 * @var MessageManager
52 */
53 private $messageManager;
54
55 /**
56 * Logger.
57 *
58 * @var ILogger
59 */
60 private $logger;
61
62 /**
63 * Log repository.
64 *
65 * @var Log\Repository
66 */
67 private $logRepository;
68
69 /**
70 * Carrier repository.
71 *
72 * @var Carrier\Repository
73 */
74 private $carrierRepository;
75
76 /**
77 * WpdbAdapter.
78 *
79 * @var WpdbAdapter
80 */
81 private $wpdbAdapter;
82
83 /**
84 * Constructor.
85 *
86 * @param Order\Repository $orderRepository Order repository.
87 * @param MessageManager $messageManager Message manager.
88 * @param ILogger $logger Logger.
89 * @param Log\Repository $logRepository Log repository.
90 * @param WpdbAdapter $wpdbAdapter WpdbAdapter.
91 * @param Carrier\Repository $carrierRepository Carrier repository.
92 */
93 public function __construct(
94 Order\Repository $orderRepository,
95 MessageManager $messageManager,
96 ILogger $logger,
97 Log\Repository $logRepository,
98 WpdbAdapter $wpdbAdapter,
99 Carrier\Repository $carrierRepository
100 ) {
101 $this->orderRepository = $orderRepository;
102 $this->messageManager = $messageManager;
103 $this->logger = $logger;
104 $this->logRepository = $logRepository;
105 $this->wpdbAdapter = $wpdbAdapter;
106 $this->carrierRepository = $carrierRepository;
107 }
108
109 /**
110 * Checks previous plugin version and runs upgrade if needed.
111 * https://www.sitepoint.com/wordpress-plugin-updates-right-way/
112 *
113 * @return void
114 */
115 public function check(): void {
116 $oldVersion = get_option( 'packetery_version' );
117 if ( Plugin::VERSION === $oldVersion ) {
118 return;
119 }
120
121 $this->createLogTable();
122 $this->createCarrierTable();
123 $this->createOrderTable();
124
125 // If no previous version detected, no upgrade will be run.
126 if ( $oldVersion && version_compare( $oldVersion, '1.2.0', '<' ) ) {
127 $logEntries = get_posts(
128 [
129 'post_type' => 'packetery_log',
130 'post_status' => 'any',
131 'nopaging' => true,
132 'fields' => 'ids',
133 ]
134 );
135 foreach ( $logEntries as $logEntryId ) {
136 wp_delete_post( $logEntryId, true );
137 }
138
139 unregister_post_type( 'packetery_log' );
140
141 $this->migrateWpOrderMetadata();
142 $addressEntries = get_posts(
143 [
144 'post_type' => self::POST_TYPE_VALIDATED_ADDRESS,
145 'post_status' => 'any',
146 'nopaging' => true,
147 'fields' => 'ids',
148 ]
149 );
150 foreach ( $addressEntries as $addressEntryId ) {
151 wp_delete_post( $addressEntryId, true );
152 }
153
154 unregister_post_type( self::POST_TYPE_VALIDATED_ADDRESS );
155 }
156
157 if ( $oldVersion && version_compare( $oldVersion, '1.2.6', '<' ) ) {
158 $this->orderRepository->deleteOrphans();
159 }
160
161 if ( $oldVersion && version_compare( $oldVersion, '1.4.2', '<' ) ) {
162 $version_1_4_2 = new Version_1_4_2( $this->wpdbAdapter );
163 $version_1_4_2->run();
164 }
165
166 if ( $oldVersion && version_compare( $oldVersion, '1.5', '<' ) ) {
167 wp_clear_scheduled_hook( CronService::CRON_CARRIERS_HOOK );
168 }
169
170 update_option( 'packetery_version', Plugin::VERSION );
171 }
172
173 /**
174 * Migrates WP order metadata.
175 *
176 * @return void
177 */
178 private function migrateWpOrderMetadata(): void {
179 $this->createOrderTable();
180
181 // Did not work when called from plugins_loaded hook.
182 $orders = wc_get_orders(
183 [
184 'packetery_all' => '1',
185 'nopaging' => true,
186 ]
187 );
188
189 foreach ( $orders as $order ) {
190 $orderEntity = new Core\Entity\Order(
191 (string) $order->get_id(),
192 $this->getMetaAsNullableString( $order, self::META_CARRIER_ID )
193 );
194 $order->delete_meta_data( self::META_CARRIER_ID );
195
196 $orderEntity->setWeight( $this->getMetaAsNullableFloat( $order, self::META_WEIGHT ) );
197 $order->delete_meta_data( self::META_WEIGHT );
198
199 $orderEntity->setPacketStatus( $this->getMetaAsNullableString( $order, self::META_PACKET_STATUS ) );
200 $order->delete_meta_data( self::META_PACKET_STATUS );
201
202 $orderEntity->setIsExported( (bool) $this->getMetaAsNullableString( $order, self::META_IS_EXPORTED ) );
203 $order->delete_meta_data( self::META_IS_EXPORTED );
204
205 $orderEntity->setIsLabelPrinted( (bool) $this->getMetaAsNullableString( $order, self::META_IS_LABEL_PRINTED ) );
206 $order->delete_meta_data( self::META_IS_LABEL_PRINTED );
207
208 $orderEntity->setCarrierNumber( $this->getMetaAsNullableString( $order, self::META_CARRIER_NUMBER ) );
209 $order->delete_meta_data( self::META_CARRIER_NUMBER );
210
211 $orderEntity->setPacketId( $this->getMetaAsNullableString( $order, self::META_PACKET_ID ) );
212 $order->delete_meta_data( self::META_PACKET_ID );
213
214 $orderEntity->setSize(
215 new Core\Entity\Size(
216 $this->getMetaAsNullableFloat( $order, self::META_LENGTH ),
217 $this->getMetaAsNullableFloat( $order, self::META_WIDTH ),
218 $this->getMetaAsNullableFloat( $order, self::META_HEIGHT )
219 )
220 );
221 $order->delete_meta_data( self::META_LENGTH );
222 $order->delete_meta_data( self::META_WIDTH );
223 $order->delete_meta_data( self::META_HEIGHT );
224
225 if ( null !== $this->getMetaAsNullableString( $order, self::META_POINT_ID ) ) {
226 $orderEntity->setPickupPoint(
227 new Core\Entity\PickupPoint(
228 $this->getMetaAsNullableString( $order, self::META_POINT_ID ),
229 $this->getMetaAsNullableString( $order, self::META_POINT_NAME ),
230 $this->getMetaAsNullableString( $order, self::META_POINT_CITY ),
231 $this->getMetaAsNullableString( $order, self::META_POINT_ZIP ),
232 $this->getMetaAsNullableString( $order, self::META_POINT_STREET ),
233 $this->getMetaAsNullableString( $order, self::META_POINT_URL )
234 )
235 );
236 }
237 $order->delete_meta_data( self::META_POINT_ID );
238 $order->delete_meta_data( self::META_POINT_NAME );
239 $order->delete_meta_data( self::META_POINT_CITY );
240 $order->delete_meta_data( self::META_POINT_ZIP );
241 $order->delete_meta_data( self::META_POINT_STREET );
242 $order->delete_meta_data( self::META_POINT_URL );
243
244 $validatedAddressId = $this->getValidatedAddressIdByOrderId( (int) $order->get_id() );
245 if ( $validatedAddressId ) {
246 $validatedAddress = $this->createAddressFromPostId( $validatedAddressId );
247 $orderEntity->setAddressValidated( true );
248 $orderEntity->setDeliveryAddress( $validatedAddress );
249 }
250
251 $this->orderRepository->save( $orderEntity );
252 $order->save_meta_data();
253 }
254 }
255
256 /**
257 * Creates active widget address using woocommerce order id.
258 *
259 * @param int $addressId Address ID.
260 *
261 * @return Core\Entity\Address|null
262 */
263 public function createAddressFromPostId( int $addressId ): ?Core\Entity\Address {
264 $address = new Core\Entity\Address(
265 get_post_meta( $addressId, 'street', true ),
266 get_post_meta( $addressId, 'city', true ),
267 get_post_meta( $addressId, 'postCode', true )
268 );
269 $address->setHouseNumber( get_post_meta( $addressId, 'houseNumber', true ) );
270 $address->setCounty( get_post_meta( $addressId, 'county', true ) );
271 $address->setLongitude( get_post_meta( $addressId, 'longitude', true ) );
272 $address->setLatitude( get_post_meta( $addressId, 'latitude', true ) );
273
274 return $address;
275 }
276
277 /**
278 * Gets active address.
279 *
280 * @param int $orderId Order ID.
281 *
282 * @return int|null
283 */
284 public function getValidatedAddressIdByOrderId( int $orderId ): ?int {
285 $postIds = get_posts(
286 [
287 'post_type' => self::POST_TYPE_VALIDATED_ADDRESS,
288 'post_status' => 'any',
289 'nopaging' => true,
290 'numberposts' => 1,
291 'fields' => 'ids',
292 'post_parent' => $orderId,
293 ]
294 );
295
296 if ( empty( $postIds ) ) {
297 return null;
298 }
299
300 return (int) array_shift( $postIds );
301 }
302
303 /**
304 * Gets meta property of order as string.
305 *
306 * @param \WC_Order $order Order.
307 * @param string $key Meta order key.
308 *
309 * @return string|null
310 */
311 private function getMetaAsNullableString( \WC_Order $order, string $key ): ?string {
312 $value = $order->get_meta( $key, true );
313 return ( ( null !== $value && '' !== $value ) ? (string) $value : null );
314 }
315
316 /**
317 * Gets meta property of order as float.
318 *
319 * @param \WC_Order $order Order.
320 * @param string $key Meta order key.
321 *
322 * @return float|null
323 */
324 private function getMetaAsNullableFloat( \WC_Order $order, string $key ): ?float {
325 $value = $order->get_meta( $key, true );
326 return ( ( null !== $value && '' !== $value ) ? (float) $value : null );
327 }
328
329 /**
330 * Transforms custom query variable to meta query.
331 *
332 * @param array $queryVars Query vars.
333 * @param array $get Input values.
334 *
335 * @return array
336 */
337 public function handleCustomQueryVar( array $queryVars, array $get ): array {
338 $metaQuery = $this->addQueryVars( ( $queryVars['meta_query'] ?? [] ), $get );
339 if ( $metaQuery ) {
340 // @codingStandardsIgnoreStart
341 $queryVars['meta_query'] = $metaQuery;
342 // @codingStandardsIgnoreEnd
343 }
344
345 return $queryVars;
346 }
347
348 /**
349 * Adds query vars to fetch order list.
350 *
351 * @param array $queryVars Query vars.
352 * @param array $get Get parameters.
353 *
354 * @return array
355 */
356 private function addQueryVars( array $queryVars, array $get ): array {
357 if ( ! empty( $get['packetery_all'] ) ) {
358 $queryVars[] = [
359 'key' => self::META_CARRIER_ID,
360 'compare' => 'EXISTS',
361 ];
362 $queryVars[] = [
363 'key' => self::META_CARRIER_ID,
364 'value' => '',
365 'compare' => '!=',
366 ];
367 }
368
369 return $queryVars;
370 }
371
372 /**
373 * Creates log table.
374 *
375 * @return void
376 */
377 private function createLogTable(): void {
378 if ( false === $this->logRepository->createOrAlterTable() ) {
379 $this->messageManager->flash_message(
380 // translators: %s: Short table name.
381 sprintf( __( 'Database %s table could not be created, more information might be found in WooCommerce logs.', 'packeta' ), 'log' ),
382 MessageManager::TYPE_ERROR
383 );
384 }
385 }
386
387 /**
388 * Creates carrier table.
389 *
390 * @return void
391 */
392 private function createCarrierTable(): void {
393 if ( false === $this->carrierRepository->createOrAlterTable() ) {
394 $this->flashAndLog( 'carrier', Record::ACTION_CARRIER_TABLE_NOT_CREATED );
395 }
396 }
397
398 /**
399 * Creates order table.
400 *
401 * @return void
402 */
403 private function createOrderTable(): void {
404 if ( false === $this->orderRepository->createOrAlterTable() ) {
405 $this->flashAndLog( 'order', Record::ACTION_ORDER_TABLE_NOT_CREATED );
406 }
407 }
408
409 /**
410 * Flashes error and logs to Packeta log.
411 *
412 * @param string $table Short table name.
413 * @param string $logMessage Message to log.
414 * @param string $action Log action.
415 *
416 * @return void
417 */
418 private function flashAndLog( string $table, string $logMessage, string $action ): void {
419 // translators: %s: Short table name.
420 $flashMessage = sprintf( __( 'Database %s table of Packeta plugin could not be created, you can find more information in Packeta log.', 'packeta' ), $table );
421 $this->messageManager->flash_message( $flashMessage, MessageManager::TYPE_ERROR );
422
423 $record = new Record();
424 $record->action = $action;
425 $record->status = Record::STATUS_ERROR;
426 // translators: %s: Short table name.
427 $record->title = sprintf( __( 'Database %s table could not be created, more information might be found in WooCommerce logs.', 'packeta' ), $table );
428 $this->logger->add( $record );
429 }
430
431 }
432