diff --git a/mu-plugins/osi-api/osi-api.php b/mu-plugins/osi-api/osi-api.php index 6f47e19..08d2241 100644 --- a/mu-plugins/osi-api/osi-api.php +++ b/mu-plugins/osi-api/osi-api.php @@ -119,6 +119,9 @@ public function get_licenses( WP_REST_Request $data ) { // Check if we have any steward passed. $steward = $data->get_param( 'steward' ); + // Check the SPDX parameter. + $spdx = $data->get_param( 'spdx' ); + // Get all public posts from the 'osi_license' post type $args = array( 'post_type' => 'license', @@ -132,6 +135,13 @@ public function get_licenses( WP_REST_Request $data ) { add_filter( 'posts_where', array( $this, 'posts_where_title_like' ), 10, 2 ); $args['post_title_like'] = sanitize_text_field( $searched_slug ); // Use the post name (slug) to filter by ID + } elseif ( ! empty( $spdx ) ) { + // If we have no wildcards, look for a direct match + $args['meta_query'][] = array( + 'key' => 'spdx_identifier_display_text', + 'value' => str_contains( $spdx, '*' ) ? $this->cast_wildcard_to_regex( $spdx ) : sanitize_text_field( $spdx ), + 'compare' => str_contains( $spdx, '*' ) ? 'REGEXP' : '==', + ); } elseif ( ! empty( $keyword ) ) { // Add a tax query on taxonomy-license-category where passed term is a the slug $args['tax_query'] = array( @@ -169,6 +179,26 @@ public function get_licenses( WP_REST_Request $data ) { return new WP_REST_Response( $all, 200 ); } + /** + * Turns a wildcard string into a LIKE query format. + * + * @param string $spdx The SPDX identifier to search for. + * + * @return string The LIKE query format for the SPDX identifier. + */ + public function cast_wildcard_to_regex( string $spdx ): string { + $escaped = preg_quote( $spdx, '/' ); + + $pattern = str_replace( + array( '\*', '\?' ), + array( '.*', '.' ), + $escaped + ); + + // Ensure it matches the whole string + return '^' . $pattern . '$'; + } + /** * Get a license by its slug. * @@ -222,12 +252,13 @@ public function get_license_model( string $id ): ?array { 'id' => $license->post_name, 'name' => $license->post_title, ); - - $meta = array( + $meta = array( + 'spdx_id' => get_post_meta( $license->ID, 'spdx_identifier_display_text', true ), 'version' => get_post_meta( $license->ID, 'version', true ), 'submission_date' => get_post_meta( $license->ID, 'release_date', true ), 'submission_url' => get_post_meta( $license->ID, 'submission_url', true ), 'submitter_name' => get_post_meta( $license->ID, 'submitter', true ), + 'approved' => get_post_meta( $license->ID, 'approved', true ) === '1' ? true : false, 'approval_date' => get_post_meta( $license->ID, 'approval_date', true ), 'license_steward_version' => get_post_meta( $license->ID, 'license_steward_version', true ), 'license_steward_url' => get_post_meta( $license->ID, 'license_steward_version_url', true ), @@ -273,13 +304,24 @@ function ( $category ) { return array_merge( $model, - array_map( 'esc_html', $meta ), + array_map( array( $this, 'sanitize_value' ), $meta ), array( 'stewards' => $license_stewards ), array( 'keywords' => $license_categories ), array( '_links' => $links ) ); } + /** + * Sanitize values to ensure all but bools are escaped. + * + * @param mixed $value The value to sanitize. + * + * @return mixed The sanitized value. + */ + public function sanitize_value( $value ) { // phpcs:ignore + return is_bool( $value ) ? $value : esc_html( $value ); + } + /** * Filter to allow the LIKE search of a post title. * @@ -405,7 +447,6 @@ public function handle_redirects() { } } - /** * Get the License scehema. * @@ -418,6 +459,11 @@ public function get_license_schema(): array { 'type' => 'string', 'context' => array( 'view', 'edit' ), ), + 'spdx_id' => array( + 'description' => 'The SPDX identifier for the license.', + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), 'name' => array( 'description' => 'The name of the license.', 'type' => 'string', @@ -445,6 +491,12 @@ public function get_license_schema(): array { 'type' => 'string', 'context' => array( 'view' ), ), + 'approved' => array( + 'description' => 'Whether the license is approved.', + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), 'approval_date' => array( 'description' => 'Date the license was approved.', 'type' => 'string', diff --git a/plugins/osi-features/acf-fields/group_62d0160caa7af.json b/plugins/osi-features/acf-fields/group_62d0160caa7af.json index b055258..e28b98f 100644 --- a/plugins/osi-features/acf-fields/group_62d0160caa7af.json +++ b/plugins/osi-features/acf-fields/group_62d0160caa7af.json @@ -1,8 +1,7 @@ { "key": "group_62d0160caa7af", "title": "License Data", - "fields": [ - { + "fields": [{ "key": "field_62fcd8910c9f7", "label": "Version", "name": "version", @@ -42,41 +41,41 @@ "first_day": 1 }, { - "key": "field_6783hdda5y544gf", - "label": "Submission URL", - "name": "submission_url", - "aria-label": "", - "type": "url", - "instructions": "", - "required": 0, - "conditional_logic": 0, - "wrapper": { - "width": "", - "class": "", - "id": "" - }, - "default_value": "", - "placeholder": "" + "key": "field_6783hdda5y544gf", + "label": "Submission URL", + "name": "submission_url", + "aria-label": "", + "type": "url", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "placeholder": "" }, { - "key": "field_62fcda3b00451", - "label": "Submitter", - "name": "submitter", - "aria-label": "", - "type": "text", - "instructions": "", - "required": 0, - "conditional_logic": 0, - "wrapper": { - "width": "", - "class": "", - "id": "" - }, - "default_value": "", - "placeholder": "", - "prepend": "", - "append": "", - "maxlength": "" + "key": "field_62fcda3b00451", + "label": "Submitter", + "name": "submitter", + "aria-label": "", + "type": "text", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "placeholder": "", + "prepend": "", + "append": "", + "maxlength": "" }, { "key": "field_62fcd90c2f885", @@ -112,28 +111,26 @@ "id": "" }, "layout": "block", - "sub_fields": [ - { - "key": "field_62fcfcecb4ab2", - "label": "Display Text", - "name": "display_text", - "aria-label": "", - "type": "text", - "instructions": "", - "required": 0, - "conditional_logic": 0, - "wrapper": { - "width": "", - "class": "", - "id": "" - }, - "default_value": "", - "placeholder": "", - "prepend": "", - "append": "", - "maxlength": "" - } - ] + "sub_fields": [{ + "key": "field_62fcfcecb4ab2", + "label": "Display Text", + "name": "display_text", + "aria-label": "", + "type": "text", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "placeholder": "", + "prepend": "", + "append": "", + "maxlength": "" + }] }, { "key": "field_62fcda1400450", @@ -150,25 +147,23 @@ "id": "" }, "layout": "block", - "sub_fields": [ - { - "key": "field_62fcda4d00452", - "label": "URL", - "name": "url", - "aria-label": "", - "type": "url", - "instructions": "", - "required": 0, - "conditional_logic": 0, - "wrapper": { - "width": "", - "class": "", - "id": "" - }, - "default_value": "", - "placeholder": "" - } - ] + "sub_fields": [{ + "key": "field_62fcda4d00452", + "label": "URL", + "name": "url", + "aria-label": "", + "type": "url", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "placeholder": "" + }] }, { "key": "field_62fcda6600453", @@ -186,35 +181,53 @@ }, "relevanssi_exclude": 1, "layout": "block", - "sub_fields": [ - { - "key": "field_62fcda6600455", - "label": "URL", - "name": "url", - "aria-label": "", - "type": "url", - "instructions": "", - "required": 0, - "conditional_logic": 0, - "wrapper": { - "width": "", - "class": "", - "id": "" - }, - "default_value": "", - "placeholder": "" - } - ] + "sub_fields": [{ + "key": "field_62fcda6600455", + "label": "URL", + "name": "url", + "aria-label": "", + "type": "url", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "placeholder": "" + }] + }, + { + "key": "field_6855605992d38", + "label": "Approved", + "name": "approved", + "aria-label": "", + "type": "true_false", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "relevanssi_exclude": 0, + "message": "Denotes if a license has been approved", + "default_value": 0, + "allow_in_bindings": 0, + "ui": 0, + "ui_on_text": "", + "ui_off_text": "" } ], "location": [ - [ - { - "param": "post_type", - "operator": "==", - "value": "license" - } - ] + [{ + "param": "post_type", + "operator": "==", + "value": "license" + }] ], "menu_order": 0, "position": "side", @@ -224,6 +237,6 @@ "hide_on_screen": "", "active": true, "description": "", - "show_in_rest": 0, - "modified": 1686668177 -} + "show_in_rest": 1, + "modified": 1750425728 +} \ No newline at end of file