PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.14.2
Yatra – Travel Booking & Tour Operator Software v3.0.14.2
3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 2.0.10 All 83 releases
yatra / app / Migrations / CouponMigration.php

CouponMigration.php in Yatra – Travel Booking & Tour Operator Software 3.0.14.2, at app/Migrations/CouponMigration.php

170 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yatra\Migration;
4
5 use Yatra\Database\Tables\DiscountsTable;
6 use Yatra\Migration\MigrationProgress;
7 use Yatra\Utils\Logger;
8
9 /**
10 * CouponMigration - Migrates coupons from old Yatra CPT (yatra-coupons) to new discounts table.
11 *
12 * Old system: Custom Post Type 'yatra-coupons'
13 * - post_title = coupon name/title (NOT the coupon code)
14 * - post_meta 'yatra_coupon_code' = actual coupon code string
15 * - post_meta 'yatra_coupon_type' = 'percentage' or 'fixed'
16 * - post_meta 'yatra_coupon_value' = discount value (number)
17 * - post_meta 'yatra_coupon_expiry_date' = expiry datetime
18 * - post_meta 'yatra_coupon_using_limit' = max usage limit
19 * - post_meta 'yatra_coupon_usages_bookings' = array of booking IDs (usage count = count of this array)
20 *
21 * New system: Custom table wp_yatra_discounts
22 */
23 class CouponMigration extends BaseMigration
24 {
25 public function __construct(MigrationProgress $service)
26 {
27 parent::__construct($service);
28 }
29
30 /**
31 * Map legacy CPT post_status to 3.x discount status (draft|publish|trash).
32 * Live coupons must use DiscountService convention "publish", not "active".
33 * Legacy Yatra 2.x coupon lookup used get_posts(), which only returned published posts by default.
34 */
35 private function mapLegacyCouponPostStatusToDiscountStatus(string $postStatus): string
36 {
37 $postStatus = strtolower($postStatus);
38
39 if ($postStatus === 'publish') {
40 return 'publish';
41 }
42
43 return 'draft';
44 }
45
46 public function run(): array
47 {
48 $migrated = 0;
49 $skipped = 0;
50 $failed = 0;
51
52 $oldCoupons = $this->wpdb->get_results(
53 "SELECT * FROM {$this->wpdb->posts}
54 WHERE post_type = 'yatra-coupons'
55 AND post_status NOT IN ('trash', 'auto-draft')"
56 );
57 $total = count($oldCoupons);
58
59 if ($total === 0) {
60 return compact('migrated', 'skipped', 'failed');
61 }
62
63 Logger::info("Found {$total} old coupons to migrate", ['source' => 'migration', 'data_type' => 'coupons']);
64
65 foreach ($oldCoupons as $oldCoupon) {
66 try {
67 // Check if already migrated
68 $migratedId = $this->getRawPostMeta($oldCoupon->ID, '_migrated_to_coupon_id');
69 if ($migratedId && !$this->isForceMigration()) {
70 $skipped++;
71 $this->updateProgress('coupons', 'running', $migrated, $skipped, $failed, $total, null, null);
72 continue;
73 }
74
75 $meta = $this->getPostMeta($oldCoupon->ID);
76
77 // Old system: yatra_coupon_code is the actual code, post_title is the coupon name
78 $couponCode = $meta['yatra_coupon_code'] ?? $oldCoupon->post_title;
79 $couponType = $meta['yatra_coupon_type'] ?? 'percentage';
80 $couponValue = (float) ($meta['yatra_coupon_value'] ?? 0);
81 $expiryDate = $meta['yatra_coupon_expiry_date'] ?? null;
82 $usageLimit = (int) ($meta['yatra_coupon_using_limit'] ?? 0);
83
84 // Usage count is determined by counting the yatra_coupon_usages_bookings array
85 $usageBookings = maybe_unserialize($meta['yatra_coupon_usages_bookings'] ?? '');
86 $usageCount = is_array($usageBookings) ? count($usageBookings) : 0;
87
88 // Map coupon type: old uses 'percentage'/'fixed', new uses same
89 $discountType = $couponType;
90
91 // Check if coupon code already exists in new table
92 $existingId = $this->wpdb->get_var($this->wpdb->prepare(
93 "SELECT id FROM " . DiscountsTable::getTableName() . " WHERE code = %s",
94 $couponCode
95 ));
96
97 $couponData = [
98 'code' => $couponCode,
99 'description' => $oldCoupon->post_content ?: $oldCoupon->post_title,
100 'type' => $discountType,
101 'amount' => $couponValue,
102 'usage_limit' => $usageLimit,
103 'usage_count' => $usageCount,
104 'expiry_date' => $expiryDate ?: null,
105 'status' => $this->mapLegacyCouponPostStatusToDiscountStatus((string) $oldCoupon->post_status),
106 'created_at' => $oldCoupon->post_date,
107 'updated_at' => $oldCoupon->post_modified,
108 'created_by' => (int) $oldCoupon->post_author ?: 0,
109 'updated_by' => (int) $oldCoupon->post_author ?: 0,
110 ];
111
112 if ($existingId && !$this->isForceMigration()) {
113 // Update existing coupon
114 $updateData = $couponData;
115 unset($updateData['code']);
116 unset($updateData['created_at']);
117
118 $this->wpdb->update(
119 DiscountsTable::getTableName(),
120 $updateData,
121 ['id' => $existingId]
122 );
123 $newCouponId = $existingId;
124 $migrated++;
125 } else {
126 // For force migration, ensure unique code
127 if ($this->isForceMigration() && $existingId) {
128 $couponData['code'] = $couponCode . '-' . time();
129 }
130
131 $inserted = $this->wpdb->insert(
132 DiscountsTable::getTableName(),
133 $couponData
134 );
135
136 if ($inserted) {
137 $newCouponId = $this->wpdb->insert_id;
138 $migrated++;
139 } else {
140 $failed++;
141 Logger::error("Failed to insert coupon ID {$oldCoupon->ID}: {$this->wpdb->last_error}", [
142 'source' => 'migration',
143 'data_type' => 'coupons',
144 'coupon_id' => $oldCoupon->ID,
145 'code' => $couponCode,
146 ]);
147 $this->updateProgress('coupons', 'running', $migrated, $skipped, $failed, $total, null, null);
148 continue;
149 }
150 }
151
152 // Mark as migrated
153 $this->setRawPostMeta($oldCoupon->ID, '_migrated_to_coupon_id', (string) $newCouponId);
154
155 $this->updateProgress('coupons', 'running', $migrated, $skipped, $failed, $total, null, null);
156 } catch (\Exception $e) {
157 $failed++;
158 Logger::error("Exception migrating coupon ID {$oldCoupon->ID}: {$e->getMessage()}", [
159 'source' => 'migration',
160 'data_type' => 'coupons',
161 'coupon_id' => $oldCoupon->ID,
162 ]);
163 $this->updateProgress('coupons', 'running', $migrated, $skipped, $failed, $total, null, null);
164 }
165 }
166
167 return compact('migrated', 'skipped', 'failed');
168 }
169 }
170