PluginProbe ʕ •ᴥ•ʔ
Event Tickets with Ticket Scanner / 3.1.2
Event Tickets with Ticket Scanner v3.1.2
3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.4 trunk 2.6.0 2.7.0 2.7.1 2.7.10 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.10 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.0 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8 2.9.9 3.0.0 3.0.1 3.0.2 3.0.3
event-tickets-with-ticket-scanner / includes / seating / class-seating-base.php
event-tickets-with-ticket-scanner / includes / seating Last commit date
class-seating-admin.php 1 week ago class-seating-base.php 1 week ago class-seating-block.php 1 week ago class-seating-frontend.php 1 week ago class-seating-plan.php 1 week ago class-seating-seat.php 1 week ago
class-seating-base.php
293 lines
1 <?php
2 /**
3 * Seating Integration Base Class
4 *
5 * Provides shared constants for all Seating classes.
6 * Keeps it minimal - uses existing infrastructure from sasoEventtickets_Base.
7 *
8 * @package Event_Tickets_With_Ticket_Scanner
9 * @subpackage Seating
10 * @since 2.8.0
11 */
12
13 // Exit if accessed directly
14 if (!defined('ABSPATH')) {
15 exit;
16 }
17
18 /**
19 * Base Class for Seating Integration
20 *
21 * Only constants and minimal shared utilities.
22 * Limit checks use $this->MAIN->getBase()->getMaxValue()
23 *
24 * @since 2.8.0
25 */
26 if (!class_exists('sasoEventtickets_Seating_Base')) {
27 abstract class sasoEventtickets_Seating_Base {
28
29 /**
30 * Main plugin instance
31 *
32 * @var sasoEventtickets
33 */
34 protected $MAIN;
35
36 // =====================================================================
37 // Meta Key Methods (using prefix from MAIN)
38 // =====================================================================
39
40 /**
41 * Get meta key prefix (public keys)
42 *
43 * @return string Prefix like 'sasoEventtickets_'
44 */
45 protected function getMetaPrefix(): string {
46 return $this->MAIN->getPrefix() . '_';
47 }
48
49 /**
50 * Get meta key prefix (private keys, prefixed with underscore)
51 *
52 * @return string Prefix like '_sasoEventtickets_'
53 */
54 protected function getMetaPrefixPrivate(): string {
55 return '_' . $this->MAIN->getPrefix() . '_';
56 }
57
58 /**
59 * Get meta key: Seatingplan ID assigned to product
60 *
61 * @return string Meta key
62 */
63 public function getMetaProductSeatingplan(): string {
64 return $this->getMetaPrefix() . 'seatingplan_id';
65 }
66
67 /**
68 * Get meta key: Product requires seat selection (value: "yes")
69 *
70 * @return string Meta key
71 */
72 public function getMetaProductSeatingRequired(): string {
73 return $this->getMetaPrefix() . 'seating_required';
74 }
75
76 /**
77 * Get meta key: Seatingplan ID override for variation (private)
78 *
79 * @return string Meta key
80 */
81 public function getMetaVariationSeatingplan(): string {
82 return $this->getMetaPrefixPrivate() . 'seatingplan_id';
83 }
84
85 /**
86 * Get meta key: Selected seat data on order item (JSON, private)
87 *
88 * @return string Meta key
89 */
90 public function getMetaOrderItemSeat(): string {
91 return $this->getMetaPrefixPrivate() . 'seat';
92 }
93
94 /**
95 * Get meta key: Seat block ID reference on order item (private)
96 *
97 * @return string Meta key
98 */
99 public function getMetaOrderItemSeatBlockId(): string {
100 return $this->getMetaPrefixPrivate() . 'seat_block_id';
101 }
102
103 /**
104 * Get meta key: Selected seat in cart item (JSON, private)
105 *
106 * @return string Meta key
107 */
108 public function getMetaCartItemSeat(): string {
109 return $this->getMetaPrefixPrivate() . 'seat_selection';
110 }
111
112 /**
113 * Get form field name for seat selection input
114 *
115 * @return string Field name
116 */
117 public function getFieldSeatSelection(): string {
118 return $this->getMetaPrefix() . 'seat_selection';
119 }
120
121 // =====================================================================
122 // Seat Block Status Constants
123 // =====================================================================
124
125 /** @var string Status: temporarily blocked (session-based) */
126 public const STATUS_BLOCKED = 'blocked';
127
128 /** @var string Status: confirmed (order completed) */
129 public const STATUS_CONFIRMED = 'confirmed';
130
131 /** @var string Status: released (refund/cancel) */
132 public const STATUS_RELEASED = 'released';
133
134 // =====================================================================
135 // Block Type Constants
136 // =====================================================================
137
138 /** @var string Block type: session-based temporary block */
139 public const BLOCK_TYPE_SESSION = 'session';
140
141 /** @var string Block type: order-based confirmed block */
142 public const BLOCK_TYPE_ORDER = 'order';
143
144 /** @var string Block type: admin-created block */
145 public const BLOCK_TYPE_ADMIN = 'admin';
146
147 // =====================================================================
148 // Layout Type Constants
149 // =====================================================================
150
151 /** @var string Layout type: simple text/dropdown */
152 public const LAYOUT_SIMPLE = 'simple';
153
154 /** @var string Layout type: visual SVG/Canvas editor */
155 public const LAYOUT_VISUAL = 'visual';
156
157 // =====================================================================
158 // Default Values
159 // =====================================================================
160
161 /** @var int Default seat block timeout in minutes */
162 public const DEFAULT_BLOCK_TIMEOUT_MINUTES = 15;
163
164 /**
165 * Constructor
166 *
167 * @param sasoEventtickets $main Main plugin instance
168 */
169 public function __construct($main) {
170 $this->MAIN = $main;
171 }
172
173 /**
174 * Get table name with prefix
175 *
176 * @param string $table Table name without prefix
177 * @return string Full table name
178 */
179 protected function getTable(string $table): string {
180 return $this->MAIN->getDB()->getTabelle($table);
181 }
182
183 /**
184 * Get WooCommerce session ID
185 *
186 * @return string|null Session ID or null if not available
187 */
188 protected function getSessionId(): ?string {
189 if (function_exists('WC') && WC()->session) {
190 return WC()->session->get_customer_id();
191 }
192 return null;
193 }
194
195 // =====================================================================
196 // Meta Object Pattern (from Core.php)
197 // =====================================================================
198
199 /**
200 * Get meta object structure with all defaults
201 *
202 * IMPORTANT: This defines ALL possible meta fields with defaults.
203 * - New fields added here are automatically available for old stored data
204 * - Premium plugin can add fields via hook without basic plugin update
205 * - Always add new fields HERE first before using them anywhere in code
206 *
207 * Each child class MUST implement this with their specific fields.
208 *
209 * @return array Meta object structure with all defaults
210 */
211 abstract public function getMetaObject(): array;
212
213 /**
214 * Decode and merge stored meta with defaults
215 *
216 * Uses Core's generic decodeAndMergeMeta() with this class's getMetaObject().
217 *
218 * @param string|null $metaJson JSON meta string from DB
219 * @return array Merged meta array with all fields guaranteed
220 */
221 protected function decodeAndMergeMeta(?string $metaJson): array {
222 return $this->MAIN->getCore()->decodeAndMergeMeta($metaJson, $this->getMetaObject());
223 }
224
225 // =====================================================================
226 // Product-Plan Resolution (Shared)
227 // =====================================================================
228
229 /**
230 * Resolve seating plan ID for a product (with variation support)
231 *
232 * Checks in this order:
233 * 1. Variation-specific plan (if variationId given)
234 * 2. If productId is a variation: check it, then fall back to parent
235 * 3. Main product plan
236 *
237 * Note: Caller is responsible for WPML normalization via getWPMLProductId()
238 *
239 * @param int $productId Product ID (or variation ID)
240 * @param int|null $variationId Variation ID (optional)
241 * @return int|null Plan ID or null if no plan found
242 */
243 protected function resolvePlanIdForProduct(int $productId, ?int $variationId = null): ?int {
244 $planId = null;
245
246 // Check variation first if given
247 if ($variationId) {
248 $planId = get_post_meta($variationId, $this->getMetaVariationSeatingplan(), true);
249 }
250
251 // Also check if productId itself is a variation
252 if (empty($planId) && get_post_type($productId) === 'product_variation') {
253 $planId = get_post_meta($productId, $this->getMetaVariationSeatingplan(), true);
254 // Fall back to parent product
255 if (empty($planId)) {
256 $parentId = wp_get_post_parent_id($productId);
257 if ($parentId) {
258 $planId = get_post_meta($parentId, $this->getMetaProductSeatingplan(), true);
259 }
260 }
261 }
262
263 // Check main product
264 if (empty($planId)) {
265 $planId = get_post_meta($productId, $this->getMetaProductSeatingplan(), true);
266 }
267
268 return empty($planId) ? null : (int) $planId;
269 }
270
271 /**
272 * Get seating plan for a product (with variation support)
273 *
274 * Returns full plan data - use for admin/internal operations.
275 * Note: Caller is responsible for WPML normalization.
276 *
277 * @param int $productId Product ID (or variation ID)
278 * @param int|null $variationId Variation ID (optional)
279 * @return array|null Plan data or null
280 */
281 public function getPlanForProduct(int $productId, ?int $variationId = null): ?array {
282 // Validate product ID
283 if ($productId <= 0) {
284 $this->MAIN->getDB()->logError('getPlanForProduct: Invalid product ID: ' . $productId);
285 return null;
286 }
287
288 $planId = $this->resolvePlanIdForProduct($productId, $variationId);
289 return $planId ? $this->MAIN->getSeating()->getPlanManager()->getById($planId) : null;
290 }
291 }
292 }
293