PluginProbe
Code Snippets / trunk
Code Snippets vtrunk
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
code-snippets / php / Model / Cloud_Snippets.php

Cloud_Snippets.php in Code Snippets trunk, at php/Model/Cloud_Snippets.php

189 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Code_Snippets\Model;
4
5 use WP_REST_Response;
6
7 /**
8 * A list of snippets as retrieved from the cloud API.
9 *
10 * @since 3.4.0
11 * @package Code_Snippets
12 *
13 * @property Cloud_Snippet[] $snippets List of snippet items for the current page.
14 * @property int $page Page of data that this data belongs to.
15 * @property int $per_page Number of items requested per page.
16 * @property int $total_pages Total number of available pages of items.
17 * @property int $total_snippets Total number of available snippet items.
18 * @property array<int, int> $cloud_id_rev An array of all cloud snippet IDs and their revision numbers.
19 * @property array<string, array> $available_filters An array of available filters that can be applied to the collection.
20 */
21 class Cloud_Snippets extends Model {
22
23 /**
24 * List of default values provided for fields.
25 *
26 * @var array<string, mixed>
27 */
28 protected static array $default_values = [
29 'snippets' => [],
30 'total_snippets' => 0,
31 'total_pages' => 0,
32 'page' => 0,
33 'per_page' => 0,
34 'cloud_id_rev' => [],
35 'available_filters' => [],
36 ];
37
38 /**
39 * List of field name aliases to map when resolving a field name.
40 *
41 * @var array<string, string> Field alias names keyed to actual field names.
42 */
43 protected static array $field_aliases = [
44 'items' => 'snippets',
45 'total_items' => 'total_snippets',
46 'page' => 'page',
47 'cloud_id_rev' => 'cloud_id_rev',
48 ];
49
50 /**
51 * Prepare a value before it is stored.
52 *
53 * @param mixed $value Value to prepare.
54 * @param string $field Field name.
55 *
56 * @return mixed Value in the correct format.
57 */
58 protected function prepare_field( $value, string $field ) {
59 switch ( $field ) {
60 case 'page':
61 case 'per_page':
62 case 'total_pages':
63 case 'total_snippets':
64 return absint( $value );
65
66 default:
67 return $value;
68 }
69 }
70
71 /**
72 * Prepare the `snippets` field by ensuring it is a list of Cloud_Snippets objects.
73 *
74 * @param mixed $snippets The field as provided.
75 *
76 * @return Cloud_Snippets[] The field in the correct format.
77 * @noinspection PhpUnused
78 */
79 protected function prepare_snippets( $snippets ): array {
80 $result = [];
81 $snippets = is_array( $snippets ) ? $snippets : [ $snippets ];
82
83 foreach ( $snippets as $snippet ) {
84 $result[] = $snippet instanceof Cloud_Snippet ? $snippet : new Cloud_Snippet( $snippet );
85 }
86
87 return $result;
88 }
89
90 /**
91 * Unpack meta values from API response.
92 *
93 * @param array $meta Response meta data.
94 *
95 * @return void
96 */
97 public function unpack_api_meta( array $meta ) {
98 if ( isset( $meta['total'] ) && is_numeric( $meta['total'] ) ) {
99 $this->total_snippets = $meta['total'];
100 }
101
102 if ( isset( $meta['total_pages'] ) && is_numeric( $meta['total_pages'] ) ) {
103 $this->total_pages = $meta['total_pages'];
104 }
105
106 if ( isset( $meta['page'] ) && is_numeric( $meta['page'] ) ) {
107 $this->page = max( 0, (int) $meta['page'] - 1 );
108 }
109
110 if ( isset( $meta['per_page'] ) && is_numeric( $meta['per_page'] ) ) {
111 $this->per_page = $meta['per_page'];
112 }
113 }
114
115 /**
116 * Normalize payloads returned by the cloud API into the shape expected by this class.
117 *
118 * @param array|null $response Response data as returned from API.
119 * @param int|null $page_number Page number requested, if applicible.
120 * @param int|null $per_page Page size requested, if applicible.
121 *
122 * @return Cloud_Snippets Constructed cloud snippets object from response data.
123 */
124 public static function unpack_api_response(
125 ?array $response,
126 ?int $page_number = null,
127 ?int $per_page = null
128 ): ?Cloud_Snippets {
129 if ( ! $response ) {
130 return null;
131 }
132
133 $result = new Cloud_Snippets();
134 $snippets_data = $response['snippets'] ?? $response['data'] ?? null;
135
136 if ( is_array( $snippets_data ) ) {
137 $result->snippets = array_map(
138 fn( $snippet_data ) => new Cloud_Snippet( $snippet_data ),
139 $snippets_data
140 );
141 }
142
143 $result->cloud_id_rev = $response['cloud_id_rev'] ?? [];
144 $result->available_filters = $response['available_filters'] ?? [];
145
146 if ( isset( $response['meta'] ) && is_array( $response['meta'] ) ) {
147 $result->unpack_api_meta( $response['meta'] );
148 }
149
150 if ( ! is_null( $page_number ) ) {
151 $result->page = $page_number;
152 }
153
154 // The requested size, not the reported one: callers compare it against a
155 // later request to decide whether cached data still covers what is asked
156 // for, and older cloud builds omit `per_page` from the meta block.
157 if ( ! is_null( $per_page ) ) {
158 $result->per_page = $per_page;
159 }
160
161 return $result;
162 }
163
164 /**
165 * Transform the data stored into this class into a REST API response.
166 *
167 * @return WP_REST_Response
168 */
169 public function to_rest_response(): WP_REST_Response {
170 $response = rest_ensure_response(
171 [
172 'snippets' => array_map(
173 fn( Cloud_Snippet $snippet ) => $snippet->get_fields(),
174 $this->snippets
175 ),
176 'page' => $this->page,
177 'total_pages' => $this->total_pages,
178 'total_snippets' => $this->total_snippets,
179 'available_filters' => $this->available_filters,
180 ]
181 );
182
183 $response->header( 'X-WP-Total', $this->total_snippets );
184 $response->header( 'X-WP-TotalPages', $this->total_pages );
185
186 return $response;
187 }
188 }
189