PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.17
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.17
1.10.19 1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 1.9.14 All 163 releases
woocommerce-pos / includes / Services / Receipt_Preview_Fixture_Loader.php

Receipt_Preview_Fixture_Loader.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.17, at includes/Services/Receipt_Preview_Fixture_Loader.php

163 lines 3.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Receipt preview JSON fixture loader.
4 *
5 * @package WCPOS\WooCommercePOS\Services
6 */
7
8 namespace WCPOS\WooCommercePOS\Services;
9
10 use const WCPOS\WooCommercePOS\PLUGIN_PATH;
11 use const WCPOS\WooCommercePOS\PLUGIN_URL;
12
13 /**
14 * Loads controlled JSON fixture profiles for receipt gallery previews.
15 */
16 class Receipt_Preview_Fixture_Loader {
17
18 /**
19 * Base fixture profile name.
20 *
21 * @var string
22 */
23 private const BASE_PROFILE = 'base-receipt';
24
25 /**
26 * Build receipt preview data for a fixture profile.
27 *
28 * @param string|null $profile Fixture profile name.
29 * @param object|null $pos_store POS store object. Falls back to default store.
30 *
31 * @return array Receipt data.
32 */
33 public function build( ?string $profile = null, $pos_store = null ): array {
34 $data = ( new Preview_Receipt_Builder() )->build( $pos_store );
35
36 $base_overrides = $this->load_overrides( self::BASE_PROFILE );
37 if ( ! empty( $base_overrides ) ) {
38 $data = self::deep_merge( $data, $base_overrides );
39 }
40
41 $profile = $this->normalize_profile( $profile );
42 if ( self::BASE_PROFILE !== $profile ) {
43 $profile_overrides = $this->load_overrides( $profile );
44 if ( ! empty( $profile_overrides ) ) {
45 $data = self::deep_merge( $data, $profile_overrides );
46 }
47 }
48
49 return $this->resolve_assets( $data );
50 }
51
52 /**
53 * Load a fixture profile's overrides.
54 *
55 * @param string $profile Fixture profile name.
56 *
57 * @return array Override data.
58 */
59 private function load_overrides( string $profile ): array {
60 $file = $this->get_profile_path( $profile );
61 if ( ! is_readable( $file ) ) {
62 return array();
63 }
64
65 $decoded = json_decode( (string) file_get_contents( $file ), true );
66 if ( ! \is_array( $decoded ) ) {
67 return array();
68 }
69
70 $overrides = $decoded['overrides'] ?? $decoded;
71
72 return \is_array( $overrides ) ? $overrides : array();
73 }
74
75 /**
76 * Resolve profile path.
77 *
78 * @param string $profile Fixture profile name.
79 *
80 * @return string Profile path.
81 */
82 private function get_profile_path( string $profile ): string {
83 return trailingslashit( PLUGIN_PATH ) . 'templates/gallery/preview-data/' . $profile . '.json';
84 }
85
86 /**
87 * Normalize profile names to safe fixture slugs.
88 *
89 * @param string|null $profile Profile name.
90 *
91 * @return string Safe profile name.
92 */
93 private function normalize_profile( ?string $profile ): string {
94 $profile = \is_string( $profile ) ? sanitize_key( $profile ) : '';
95
96 return '' !== $profile ? $profile : self::BASE_PROFILE;
97 }
98
99 /**
100 * Deep merge arrays. Associative arrays merge recursively; lists replace.
101 *
102 * @param array $base Base array.
103 * @param array $override Override array.
104 *
105 * @return array Merged array.
106 */
107 private static function deep_merge( array $base, array $override ): array {
108 foreach ( $override as $key => $value ) {
109 if (
110 isset( $base[ $key ] )
111 && \is_array( $base[ $key ] )
112 && \is_array( $value )
113 && self::is_assoc( $base[ $key ] )
114 && self::is_assoc( $value )
115 ) {
116 $base[ $key ] = self::deep_merge( $base[ $key ], $value );
117 } else {
118 $base[ $key ] = $value;
119 }
120 }
121
122 return $base;
123 }
124
125 /**
126 * Determine whether an array is associative.
127 *
128 * @param array $value Array to inspect.
129 *
130 * @return bool True for associative arrays.
131 */
132 private static function is_assoc( array $value ): bool {
133 if ( array() === $value ) {
134 return false;
135 }
136
137 return array_keys( $value ) !== range( 0, count( $value ) - 1 );
138 }
139
140 /**
141 * Resolve asset placeholders in fixture data.
142 *
143 * @param mixed $value Value to resolve.
144 *
145 * @return mixed Resolved value.
146 */
147 private function resolve_assets( $value ) {
148 if ( \is_array( $value ) ) {
149 foreach ( $value as $key => $item ) {
150 $value[ $key ] = $this->resolve_assets( $item );
151 }
152
153 return $value;
154 }
155
156 if ( '{{asset:coffee-monster-logo}}' === $value ) {
157 return trailingslashit( PLUGIN_URL ) . 'assets/img/template-gallery/preview-assets/coffee-monster.png';
158 }
159
160 return $value;
161 }
162 }
163