PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.4
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.4
1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk 1.2.0 All 47 releases
fluent-cart / app / Modules / FluentPlayer / ProductVideoSettings.php

ProductVideoSettings.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.4, at app/Modules/FluentPlayer/ProductVideoSettings.php

148 lines 4.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Modules\FluentPlayer;
4
5 use FluentCart\App\Models\Product;
6 use FluentCart\Framework\Support\Arr;
7
8 /**
9 * `fct_product_details.other_info.fluent_player_video` =>
10 * ['media_ids' => int[], 'positions' => (int|null)[]].
11 *
12 * `positions[i]` is how many gallery images precede `media_ids[i]` in the
13 * product gallery, so a video the admin dragged in front of everything has
14 * position 0. null (and any position past the last image) means "after every
15 * image" — which is where videos saved before ordering existed still sit.
16 * Pure PHP so the Unit suite can cover it.
17 */
18 class ProductVideoSettings
19 {
20 const KEY = 'fluent_player_video';
21
22 const MAX_VIDEOS = 20;
23
24 public static function defaults(): array
25 {
26 return ['media_ids' => [], 'positions' => []];
27 }
28
29 /**
30 * Wire shape from the admin is a comma-separated string ("12,15" with
31 * "0,,2" for the positions); an empty JSON array does not survive the
32 * product update request, so "no videos" could never arrive as `[]`. The
33 * stored shape is int[], which is why the array form is accepted too
34 * (fromOtherInfo re-runs this).
35 *
36 * @param mixed $value
37 */
38 public static function sanitize($value): array
39 {
40 $config = self::defaults();
41
42 if (!is_array($value)) {
43 return $config;
44 }
45
46 $raw = self::toList(Arr::get($value, 'media_ids', []));
47
48 $legacy = Arr::get($value, 'media_id');
49 if (is_numeric($legacy) && !array_key_exists('media_ids', $value)) {
50 $raw = [$legacy];
51 }
52
53 $rawPositions = self::toList(Arr::get($value, 'positions', []));
54
55 $ids = [];
56 $positions = [];
57 foreach (array_slice($raw, 0, self::MAX_VIDEOS, true) as $index => $id) {
58 $id = is_string($id) ? trim($id) : $id;
59 if (!is_numeric($id)) {
60 continue;
61 }
62 $id = (int) $id;
63 if ($id <= 0 || isset($ids[$id])) {
64 continue;
65 }
66 $ids[$id] = $id;
67 $positions[$id] = self::toPosition(isset($rawPositions[$index]) ? $rawPositions[$index] : null);
68 }
69
70 $config['media_ids'] = array_values($ids);
71 $config['positions'] = array_values($positions);
72
73 return $config;
74 }
75
76 /**
77 * @param mixed $value
78 * @return array
79 */
80 protected static function toList($value): array
81 {
82 if (is_string($value)) {
83 return explode(',', $value);
84 }
85
86 return is_array($value) ? array_values($value) : [];
87 }
88
89 /**
90 * @param mixed $value
91 * @return int|null null = after every image.
92 */
93 protected static function toPosition($value)
94 {
95 if (is_string($value)) {
96 $value = trim($value);
97 }
98
99 if ($value === null || $value === '' || !is_numeric($value)) {
100 return null;
101 }
102
103 $position = (int) $value;
104
105 return $position >= 0 ? $position : null;
106 }
107
108 /**
109 * @return array<int, int|null> media id => position, in stored order.
110 */
111 public static function positionMap(array $config): array
112 {
113 $positions = Arr::get($config, 'positions', []);
114
115 $map = [];
116 foreach (Arr::get($config, 'media_ids', []) as $index => $mediaId) {
117 $map[(int) $mediaId] = isset($positions[$index]) ? $positions[$index] : null;
118 }
119
120 return $map;
121 }
122
123 /**
124 * @param mixed $otherInfo
125 * @return array|null null when no video is set.
126 */
127 public static function fromOtherInfo($otherInfo): ?array
128 {
129 if (!is_array($otherInfo) || !array_key_exists(self::KEY, $otherInfo)) {
130 return null;
131 }
132
133 $config = self::sanitize($otherInfo[self::KEY]);
134
135 return count($config['media_ids']) > 0 ? $config : null;
136 }
137
138 public static function fromProduct(Product $product): ?array
139 {
140 $detail = $product->detail;
141 if (!$detail) {
142 return null;
143 }
144
145 return self::fromOtherInfo($detail->other_info);
146 }
147 }
148