PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.20
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.20
1.10.20 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 All 164 releases
← All changes | includes/Services/Receipt_Store_Resolver.php +101 -14 1.9.15 → 1.10.20 View file →
@@ -153,8 +153,96 @@
153 153 );
154 154 }
155 155
156 156 /**
157 + * Assemble the template-facing `store` section from the POS store object.
158 + *
159 + * Every field is read through get_store_value(), so partial store objects —
160 + * including the bare \stdClass used for orders whose store has since been
161 + * deleted — fall back field by field instead of fataling. Blank values count
162 + * as "not set" for the fields that accept a fallback, which is how both
163 + * builders have always treated empty store settings.
164 + *
165 + * @param array<string,mixed> $fallbacks Optional per-field fallbacks. Recognised keys:
166 + * `id` (int, default 0),
167 + * `name` (string, default site title),
168 + * `opening_hours` (array, default empty — renders null),
169 + * `opening_hours_notes`, `personal_notes`,
170 + * `policies_and_conditions` and `footer_imprint`
171 + * (string|null, default null).
172 + *
173 + * @return array<string,mixed>
174 + */
175 + public function build_store_section( array $fallbacks = array() ): array {
176 + $address = array(
177 + 'address_1' => (string) $this->get_store_value( 'get_store_address', '' ),
178 + 'address_2' => (string) $this->get_store_value( 'get_store_address_2', '' ),
179 + 'city' => (string) $this->get_store_value( 'get_store_city', '' ),
180 + 'state' => (string) $this->get_store_value( 'get_store_state', '' ),
181 + 'postcode' => (string) $this->get_store_value( 'get_store_postcode', '' ),
182 + 'country' => (string) $this->get_store_value( 'get_store_country', '' ),
183 + );
184 +
185 + $tax_ids = $this->get_store_value( 'get_tax_ids', array() );
186 + if ( ! \is_array( $tax_ids ) ) {
187 + $tax_ids = array();
188 + }
189 +
190 + // Resolved lazily so the bloginfo filters only run when they are actually needed.
191 + $name = $this->resolve_optional_text( 'get_name', null );
192 + if ( null === $name ) {
193 + $name = isset( $fallbacks['name'] ) ? (string) $fallbacks['name'] : (string) get_bloginfo( 'name' );
194 + }
195 +
196 + $store = array(
197 + 'id' => (int) $this->get_store_value( 'get_id', $fallbacks['id'] ?? 0 ),
198 + 'name' => $name,
199 + // Structured address parts mirror customer.billing_address — templates that
200 + // want country-specific layouts compose from these. address_lines[] is the
201 + // pre-formatted default for templates that just iterate, composed via
202 + // WC_Countries::get_formatted_address() so per-country layouts are honoured.
203 + 'address' => $address,
204 + 'address_lines' => self::compose_address_lines( $address ),
205 + 'tax_ids' => self::with_store_tax_id_labels( $tax_ids, $this->resolve_locale() ),
206 + 'phone' => (string) $this->get_store_value( 'get_phone', '' ),
207 + 'email' => (string) $this->get_store_value( 'get_email', '' ),
208 + 'logo' => Store_Logo_Resolver::resolve( $this->pos_store ),
209 + );
210 +
211 + $opening_hours = $this->get_store_value( 'get_opening_hours', array() );
212 + $has_structured_hours = \is_array( $opening_hours ) && ! empty( $opening_hours );
213 + $has_legacy_hours = \is_string( $opening_hours ) && '' !== trim( $opening_hours );
214 + if ( ! $has_structured_hours && ! $has_legacy_hours ) {
215 + $opening_hours = $fallbacks['opening_hours'] ?? array();
216 + $has_structured_hours = \is_array( $opening_hours ) && ! empty( $opening_hours );
217 + }
218 +
219 + if ( $has_structured_hours ) {
220 + // Same locale the order timestamps use, so both render in one convention.
221 + $hours_locale = $this->resolve_locale();
222 + $store['opening_hours'] = Opening_Hours_Formatter::format_compact( $opening_hours, $hours_locale );
223 + $store['opening_hours_vertical'] = Opening_Hours_Formatter::format_vertical( $opening_hours, $hours_locale );
224 + $store['opening_hours_inline'] = Opening_Hours_Formatter::format_inline( $opening_hours, $hours_locale );
225 + } elseif ( $has_legacy_hours ) {
226 + // Legacy free-text hours have no per-day structure to reformat.
227 + $store['opening_hours'] = $opening_hours;
228 + $store['opening_hours_vertical'] = null;
229 + $store['opening_hours_inline'] = null;
230 + } else {
231 + $store['opening_hours'] = null;
232 + $store['opening_hours_vertical'] = null;
233 + $store['opening_hours_inline'] = null;
234 + }
235 +
236 + $store['opening_hours_notes'] = $this->resolve_optional_text( 'get_opening_hours_notes', $fallbacks['opening_hours_notes'] ?? null );
237 + $store['personal_notes'] = $this->resolve_optional_text( 'get_personal_notes', $fallbacks['personal_notes'] ?? null );
238 + $store['policies_and_conditions'] = $this->resolve_optional_text( 'get_policies_and_conditions', $fallbacks['policies_and_conditions'] ?? null );
239 + $store['footer_imprint'] = $this->resolve_optional_text( 'get_footer_imprint', $fallbacks['footer_imprint'] ?? null );
240 +
241 + return $store;
242 + }
243 +
244 + /**
157 245 * Build price, currency, and locale presentation hints for renderers.
158 246 *
159 247 * @param string $currency Currency code.
160 248 * @param bool|null $prices_include_tax Optional precomputed prices-include-tax flag.
@@ -244,22 +332,21 @@
244 332 * @param string $locale Receipt locale.
245 333 * @return array<int,array<string,mixed>>
246 334 */
247 335 public static function with_store_tax_id_labels( array $tax_ids, string $locale = '' ): array {
248 - $labels = Receipt_I18n_Labels::get_labels( $locale );
336 + return Receipt_Sections::label_tax_ids( $tax_ids, 'store', $locale );
337 + }
249 338
250 - return array_map(
251 - static function ( array $tax_id ) use ( $labels ): array {
252 - if ( ! empty( $tax_id['label'] ) ) {
253 - return $tax_id;
254 - }
339 + /**
340 + * Resolve an optional free-text store field, treating a blank value as unset.
341 + *
342 + * @param string $getter Store getter method.
343 + * @param string|null $fallback Value used when the store has nothing set.
344 + *
345 + * @return string|null
346 + */
347 + private function resolve_optional_text( string $getter, ?string $fallback ): ?string {
348 + $value = (string) $this->get_store_value( $getter, '' );
255 349
256 - $type = isset( $tax_id['type'] ) ? (string) $tax_id['type'] : 'other';
257 - $key = 'store_tax_id_label_' . $type;
258 - $tax_id['label'] = $labels[ $key ] ?? $labels['store_tax_id_label_other'];
259 -
260 - return $tax_id;
261 - },
262 - $tax_ids
263 - );
350 + return '' !== $value ? $value : $fallback;
264 351 }
265 352 }