| @@ -9,14 +9,15 @@ | ||
| 9 | 9 | * |
| 10 | 10 | * @since 3.4.0 |
| 11 | 11 | * @package Code_Snippets |
| 12 | 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 $total_pages Total number of available pages of items. | |
| 16 | - * @property int $total_snippets Total number of available snippet items. | |
| 17 | - * @property array $cloud_id_rev An array of all cloud snippet IDs and their revision numbers. | |
| 18 | - * @property array $available_filters An array of available filters that can be applied to the collection. | |
| 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. | |
| 19 | 20 | */ |
| 20 | 21 | class Cloud_Snippets extends Model { |
| 21 | 22 | |
| 22 | 23 | /** |
| @@ -28,8 +29,9 @@ | ||
| 28 | 29 | 'snippets' => [], |
| 29 | 30 | 'total_snippets' => 0, |
| 30 | 31 | 'total_pages' => 0, |
| 31 | 32 | 'page' => 0, |
| 33 | + 'per_page' => 0, | |
| 32 | 34 | 'cloud_id_rev' => [], |
| 33 | 35 | 'available_filters' => [], |
| 34 | 36 | ]; |
| 35 | 37 | |
| @@ -44,19 +46,9 @@ | ||
| 44 | 46 | 'page' => 'page', |
| 45 | 47 | 'cloud_id_rev' => 'cloud_id_rev', |
| 46 | 48 | ]; |
| 47 | 49 | |
| 48 | - | |
| 49 | 50 | /** |
| 50 | - * Class constructor. | |
| 51 | - * | |
| 52 | - * @param array|null $initial_data Initial data from the cloud API response. | |
| 53 | - */ | |
| 54 | - public function __construct( $initial_data = null ) { | |
| 55 | - parent::__construct( $this->normalize_cloud_api( $initial_data ) ); | |
| 56 | - } | |
| 57 | - | |
| 58 | - /** | |
| 59 | 51 | * Prepare a value before it is stored. |
| 60 | 52 | * |
| 61 | 53 | * @param mixed $value Value to prepare. |
| 62 | 54 | * @param string $field Field name. |
| @@ -65,8 +57,9 @@ | ||
| 65 | 57 | */ |
| 66 | 58 | protected function prepare_field( $value, string $field ) { |
| 67 | 59 | switch ( $field ) { |
| 68 | 60 | case 'page': |
| 61 | + case 'per_page': | |
| 69 | 62 | case 'total_pages': |
| 70 | 63 | case 'total_snippets': |
| 71 | 64 | return absint( $value ); |
| 72 | 65 | |
| @@ -94,29 +87,76 @@ | ||
| 94 | 87 | return $result; |
| 95 | 88 | } |
| 96 | 89 | |
| 97 | 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 | + /** | |
| 98 | 116 | * Normalize payloads returned by the cloud API into the shape expected by this class. |
| 99 | 117 | * |
| 100 | - * @param mixed $initial_data Raw data passed into the constructor. | |
| 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. | |
| 101 | 121 | * |
| 102 | - * @return array Normalized data array or original value when no normalization is required. | |
| 122 | + * @return Cloud_Snippets Constructed cloud snippets object from response data. | |
| 103 | 123 | */ |
| 104 | - private function normalize_cloud_api( $initial_data ): array { | |
| 105 | - $result = []; | |
| 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 | + } | |
| 106 | 132 | |
| 107 | - if ( is_array( $initial_data ) ) { | |
| 108 | - $meta = $initial_data['meta'] ?? []; | |
| 133 | + $result = new Cloud_Snippets(); | |
| 134 | + $snippets_data = $response['snippets'] ?? $response['data'] ?? null; | |
| 109 | 135 | |
| 110 | - $result['snippets'] = $initial_data['snippets'] ?? []; | |
| 111 | - $result['cloud_id_rev'] = $initial_data['cloud_id_rev'] ?? []; | |
| 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 | + } | |
| 112 | 142 | |
| 113 | - if ( $meta ) { | |
| 114 | - $result['total_snippets'] = isset( $meta['total'] ) ? (int) $meta['total'] : 0; | |
| 115 | - $result['total_pages'] = isset( $meta['total_pages'] ) ? (int) $meta['total_pages'] : 0; | |
| 116 | - $result['page'] = isset( $meta['page'] ) ? max( 0, (int) $meta['page'] - 1 ) : 0; | |
| 117 | - $result['available_filters'] = $initial_data['available_filters'] ?? []; | |
| 118 | - } | |
| 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; | |
| 119 | 159 | } |
| 120 | 160 | |
| 121 | 161 | return $result; |
| 122 | 162 | } |