From 502965d6b73492ceea2ffb00b55b90d9330cd1ba Mon Sep 17 00:00:00 2001 From: Imants Date: Wed, 22 Oct 2025 13:18:37 +0300 Subject: [PATCH 01/12] test: add REST API pagination test for snippets --- tests/phpunit/test-rest-api.php | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/phpunit/test-rest-api.php diff --git a/tests/phpunit/test-rest-api.php b/tests/phpunit/test-rest-api.php new file mode 100644 index 00000000..80f11300 --- /dev/null +++ b/tests/phpunit/test-rest-api.php @@ -0,0 +1,46 @@ +name = "Snippet $i"; + $snippet->code = "// code $i"; + $result = \Code_Snippets\save_snippet( $snippet ); + $this->assertNotNull( $result ); + $created_ids[] = $result->id; + } + + // Request page 1 with per_page=10 + $request1 = new WP_REST_Request( 'GET', '/code-snippets/v1/snippets' ); + $request1->set_param( 'per_page', 10 ); + $request1->set_param( 'page', 1 ); + $response1 = rest_get_server()->dispatch( $request1 ); + $this->assertEquals( 200, $response1->get_status() ); + $data1 = $response1->get_data(); + $this->assertCount( 10, $data1 ); + + // Request page 2 with per_page=10 + $request2 = new WP_REST_Request( 'GET', '/code-snippets/v1/snippets' ); + $request2->set_param( 'per_page', 10 ); + $request2->set_param( 'page', 2 ); + $response2 = rest_get_server()->dispatch( $request2 ); + $this->assertEquals( 200, $response2->get_status() ); + $data2 = $response2->get_data(); + + // Ensure page 2 has the remaining items and is different from page 1 + $this->assertGreaterThanOrEqual( 1, count( $data2 ) ); + $this->assertNotEquals( $data1, $data2 ); + + // Check pagination headers + $this->assertEquals( '15', $response1->get_headers()['X-WP-Total'] ); + $this->assertEquals( '2', $response1->get_headers()['X-WP-TotalPages'] ); + } +} From fb9de70d656176be7717d4b5e8a69635850f8cc9 Mon Sep 17 00:00:00 2001 From: Imants Date: Wed, 22 Oct 2025 13:18:51 +0300 Subject: [PATCH 02/12] fix: pagination support to snippets REST API endpoint --- .../class-snippets-rest-controller.php | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/php/rest-api/class-snippets-rest-controller.php b/src/php/rest-api/class-snippets-rest-controller.php index 18a1f827..49fbe59d 100644 --- a/src/php/rest-api/class-snippets-rest-controller.php +++ b/src/php/rest-api/class-snippets-rest-controller.php @@ -80,6 +80,9 @@ public function register_routes() { [ 'network' ] ); + // Allow standard collection parameters (page, per_page, etc.) on the collection route. + $collection_args = array_merge( $network_args, $this->get_collection_params() ); + register_rest_route( $this->namespace, $route, @@ -88,7 +91,7 @@ public function register_routes() { 'methods' => WP_REST_Server::READABLE, 'callback' => [ $this, 'get_items' ], 'permission_callback' => [ $this, 'get_items_permissions_check' ], - 'args' => $network_args, + 'args' => $collection_args, ], [ 'methods' => WP_REST_Server::CREATABLE, @@ -193,15 +196,44 @@ public function register_routes() { * @return WP_REST_Response Response object on success. */ public function get_items( $request ): WP_REST_Response { - $snippets = get_snippets(); - $snippets_data = []; + // Respect the optional 'network' param when fetching snippets. + $network = $request->get_param( 'network' ); + $all_snippets = get_snippets( [], $network ); + + // Collection params (page, per_page) are provided via route args. Use defaults + // from get_collection_params() when not present on the request. + $collection_params = $this->get_collection_params(); + $per_page = (int) $request->get_param( 'per_page' ); + if ( ! $per_page ) { + $per_page = isset( $collection_params['per_page']['default'] ) ? (int) $collection_params['per_page']['default'] : 10; + } + $per_page = max( 1, $per_page ); + + $page = (int) $request->get_param( 'page' ); + if ( ! $page ) { + $page = isset( $collection_params['page']['default'] ) ? (int) $collection_params['page']['default'] : 1; + } + $page = max( 1, $page ); + + $total_items = count( $all_snippets ); + $total_pages = (int) ceil( $total_items / $per_page ); + + // Slice the full list to the requested page. + $offset = ( $page - 1 ) * $per_page; + $snippets = array_slice( $all_snippets, $offset, $per_page ); + $snippets_data = []; foreach ( $snippets as $snippet ) { $snippet_data = $this->prepare_item_for_response( $snippet, $request ); $snippets_data[] = $this->prepare_response_for_collection( $snippet_data ); } - return rest_ensure_response( $snippets_data ); + $response = rest_ensure_response( $snippets_data ); + // Provide total counts in the response headers like WP core REST responses do. + $response->header( 'X-WP-Total', (string) $total_items ); + $response->header( 'X-WP-TotalPages', (string) $total_pages ); + + return $response; } /** From 811be0bea73d4274fe8ac717bb87a3015ebd6b24 Mon Sep 17 00:00:00 2001 From: Imants Date: Wed, 22 Oct 2025 13:24:52 +0300 Subject: [PATCH 03/12] fix: stylelint --- src/css/settings.scss | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/css/settings.scss b/src/css/settings.scss index 2ff6dc76..e2a040ae 100644 --- a/src/css/settings.scss +++ b/src/css/settings.scss @@ -142,7 +142,7 @@ body.js { } #target_version { - min-width: 200px; + min-inline-size: 200px; margin-inline-start: 8px; } @@ -158,9 +158,9 @@ body.js { // Warning box styling #version-switch-warning { - margin-top: 20px !important; + margin-block-start: 20px !important; padding: 12px 16px; - border-left: 4px solid #dba617; + border-inline-start: 4px solid #dba617; background: #fff8e5; border-radius: 4px; @@ -183,31 +183,31 @@ body.js { } } - .notice { - &.notice { - &-success { - border-left-color: #00a32a; - } + .notice { + &.notice { + &-success { + border-inline-start-color: #00a32a; + } - &-error { - border-left-color: #d63638; - } + &-error { + border-inline-start-color: #d63638; + } - &-warning { - border-left-color: #dba617; - } + &-warning { + border-inline-start-color: #dba617; + } - &-info { - border-left-color: #72aee6; - } - } - } + &-info { + border-inline-start-color: #72aee6; + } + } + } } .version-switch-settings { .form-table { th { - width: 180px; + inline-size: 180px; } } } From df8af7b3ad9fd678c0a57a342e86ac3aab2d99cf Mon Sep 17 00:00:00 2001 From: Imants Date: Wed, 22 Oct 2025 15:10:14 +0300 Subject: [PATCH 04/12] fix: get_items method to support pagination --- src/php/rest-api/class-snippets-rest-controller.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/php/rest-api/class-snippets-rest-controller.php b/src/php/rest-api/class-snippets-rest-controller.php index 49fbe59d..25b6ccdc 100644 --- a/src/php/rest-api/class-snippets-rest-controller.php +++ b/src/php/rest-api/class-snippets-rest-controller.php @@ -189,19 +189,17 @@ public function register_routes() { } /** - * Retrieves a collection of snippets. + * Retrieves a collection of snippets, with pagination. * * @param WP_REST_Request $request Full details about the request. * * @return WP_REST_Response Response object on success. */ public function get_items( $request ): WP_REST_Response { - // Respect the optional 'network' param when fetching snippets. $network = $request->get_param( 'network' ); $all_snippets = get_snippets( [], $network ); - // Collection params (page, per_page) are provided via route args. Use defaults - // from get_collection_params() when not present on the request. + // Collection params (page, per_page) $collection_params = $this->get_collection_params(); $per_page = (int) $request->get_param( 'per_page' ); if ( ! $per_page ) { @@ -229,7 +227,6 @@ public function get_items( $request ): WP_REST_Response { } $response = rest_ensure_response( $snippets_data ); - // Provide total counts in the response headers like WP core REST responses do. $response->header( 'X-WP-Total', (string) $total_items ); $response->header( 'X-WP-TotalPages', (string) $total_pages ); From 93c700a1df02a077103035a007ad881c675688a6 Mon Sep 17 00:00:00 2001 From: Imants Date: Wed, 22 Oct 2025 15:20:30 +0300 Subject: [PATCH 05/12] fix: remove unused file --- tests/phpunit/test-rest-api.php | 46 --------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 tests/phpunit/test-rest-api.php diff --git a/tests/phpunit/test-rest-api.php b/tests/phpunit/test-rest-api.php deleted file mode 100644 index 80f11300..00000000 --- a/tests/phpunit/test-rest-api.php +++ /dev/null @@ -1,46 +0,0 @@ -name = "Snippet $i"; - $snippet->code = "// code $i"; - $result = \Code_Snippets\save_snippet( $snippet ); - $this->assertNotNull( $result ); - $created_ids[] = $result->id; - } - - // Request page 1 with per_page=10 - $request1 = new WP_REST_Request( 'GET', '/code-snippets/v1/snippets' ); - $request1->set_param( 'per_page', 10 ); - $request1->set_param( 'page', 1 ); - $response1 = rest_get_server()->dispatch( $request1 ); - $this->assertEquals( 200, $response1->get_status() ); - $data1 = $response1->get_data(); - $this->assertCount( 10, $data1 ); - - // Request page 2 with per_page=10 - $request2 = new WP_REST_Request( 'GET', '/code-snippets/v1/snippets' ); - $request2->set_param( 'per_page', 10 ); - $request2->set_param( 'page', 2 ); - $response2 = rest_get_server()->dispatch( $request2 ); - $this->assertEquals( 200, $response2->get_status() ); - $data2 = $response2->get_data(); - - // Ensure page 2 has the remaining items and is different from page 1 - $this->assertGreaterThanOrEqual( 1, count( $data2 ) ); - $this->assertNotEquals( $data1, $data2 ); - - // Check pagination headers - $this->assertEquals( '15', $response1->get_headers()['X-WP-Total'] ); - $this->assertEquals( '2', $response1->get_headers()['X-WP-TotalPages'] ); - } -} From c0aa1a72ee843d9de02027aa2089077bba77066c Mon Sep 17 00:00:00 2001 From: Imants Date: Wed, 22 Oct 2025 15:24:12 +0300 Subject: [PATCH 06/12] fix(copilot): comment style Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/php/rest-api/class-snippets-rest-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/rest-api/class-snippets-rest-controller.php b/src/php/rest-api/class-snippets-rest-controller.php index 25b6ccdc..d6a904f9 100644 --- a/src/php/rest-api/class-snippets-rest-controller.php +++ b/src/php/rest-api/class-snippets-rest-controller.php @@ -199,7 +199,7 @@ public function get_items( $request ): WP_REST_Response { $network = $request->get_param( 'network' ); $all_snippets = get_snippets( [], $network ); - // Collection params (page, per_page) + // Collection params (page, per_page). $collection_params = $this->get_collection_params(); $per_page = (int) $request->get_param( 'per_page' ); if ( ! $per_page ) { From ff728863e39e54ad1838bc7679dec860fc7dd657 Mon Sep 17 00:00:00 2001 From: Imants Date: Wed, 22 Oct 2025 15:39:22 +0300 Subject: [PATCH 07/12] fix: improve pagination --- .../class-snippets-rest-controller.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/php/rest-api/class-snippets-rest-controller.php b/src/php/rest-api/class-snippets-rest-controller.php index d6a904f9..6fe58ba9 100644 --- a/src/php/rest-api/class-snippets-rest-controller.php +++ b/src/php/rest-api/class-snippets-rest-controller.php @@ -199,20 +199,15 @@ public function get_items( $request ): WP_REST_Response { $network = $request->get_param( 'network' ); $all_snippets = get_snippets( [], $network ); - // Collection params (page, per_page). + // Get collection params (page, per_page). $collection_params = $this->get_collection_params(); - $per_page = (int) $request->get_param( 'per_page' ); - if ( ! $per_page ) { - $per_page = isset( $collection_params['per_page']['default'] ) ? (int) $collection_params['per_page']['default'] : 10; - } - $per_page = max( 1, $per_page ); + $per_page_request = (int) $request->get_param( 'per_page' ); + $per_page = max( 1, $per_page_request ? $per_page_request : (int) $collection_params['per_page']['default'] ); - $page = (int) $request->get_param( 'page' ); - if ( ! $page ) { - $page = isset( $collection_params['page']['default'] ) ? (int) $collection_params['page']['default'] : 1; - } - $page = max( 1, $page ); + $page_request = (int) $request->get_param( 'page' ); + $page = max( 1, $page_request ? $page_request : (int) $collection_params['page']['default'] ); + // Count total items $total_items = count( $all_snippets ); $total_pages = (int) ceil( $total_items / $per_page ); @@ -221,6 +216,7 @@ public function get_items( $request ): WP_REST_Response { $snippets = array_slice( $all_snippets, $offset, $per_page ); $snippets_data = []; + foreach ( $snippets as $snippet ) { $snippet_data = $this->prepare_item_for_response( $snippet, $request ); $snippets_data[] = $this->prepare_response_for_collection( $snippet_data ); From e38443222c26b850c47d8abd11bd037c176f7fb9 Mon Sep 17 00:00:00 2001 From: code-snippets-bot <139164393+code-snippets-bot@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:23:35 +0000 Subject: [PATCH 08/12] chore(release): update changelog for v3.7.1-beta.3 --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b12e762..2885abe9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ + +## [3.7.1-beta.3] (2025-10-22) + +### Added +* Snippets REST API now supports pagination via page and per_page query parameters. +* Collection responses include pagination metadata headers for total items and total pages. + +### Changed +* Settings UI CSS switched to logical properties for better RTL support and consistent layout. + +### Fixed +* Snippets REST API now correctly respects the network parameter when listing snippets. +* Pagination logic corrected to reliably slice results and return stable pages. + ## [3.7.1-beta.2] (2025-10-22) ### Added From c7d9c1079faf17d9cb6c1a2cfba0db9b8d57da24 Mon Sep 17 00:00:00 2001 From: code-snippets-bot <139164393+code-snippets-bot@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:23:35 +0000 Subject: [PATCH 09/12] chore(release): update readme for v3.7.1-beta.3 --- src/readme.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/readme.txt b/src/readme.txt index b5b0bf43..55844435 100644 --- a/src/readme.txt +++ b/src/readme.txt @@ -105,6 +105,23 @@ You can report security bugs found in the source code of this plugin through the == Changelog == + += 3.7.1-beta.3 (2025-10-22) = + +__Added__ + +* Snippets REST API now supports pagination via page and per_page query parameters. +* Collection responses include pagination metadata headers for total items and total pages. + +__Changed__ + +* Settings UI CSS switched to logical properties for better RTL support and consistent layout. + +__Fixed__ + +* Snippets REST API now correctly respects the network parameter when listing snippets. +* Pagination logic corrected to reliably slice results and return stable pages. + = 3.7.1-beta.2 (2025-10-22) = __Added__ From e1e12699647b87e817fd555bc72bdc5bc5617007 Mon Sep 17 00:00:00 2001 From: code-snippets-bot <139164393+code-snippets-bot@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:24:15 +0000 Subject: [PATCH 10/12] chore(release): bump version to v3.7.1-beta.3 --- package-lock.json | 4 ++-- package.json | 2 +- src/code-snippets.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index a6ff81b7..fe96a6f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "code-snippets", - "version": "3.7.1-beta.2", + "version": "3.7.1-beta.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "code-snippets", - "version": "3.7.1-beta.2", + "version": "3.7.1-beta.3", "license": "GPL-2.0-or-later", "dependencies": { "@codemirror/fold": "^0.19.4", diff --git a/package.json b/package.json index 63237fe4..8d664089 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "code-snippets", "description": "Manage code snippets running on a WordPress-powered site through a graphical interface.", "homepage": "https://codesnippets.pro", - "version": "3.7.1-beta.2", + "version": "3.7.1-beta.3", "main": "src/dist/edit.js", "directories": { "test": "tests" diff --git a/src/code-snippets.php b/src/code-snippets.php index abcf2270..9f7789c1 100644 --- a/src/code-snippets.php +++ b/src/code-snippets.php @@ -8,11 +8,11 @@ * License: GPL-2.0-or-later * License URI: license.txt * Text Domain: code-snippets - * Version: 3.7.1-beta.2 + * Version: 3.7.1-beta.3-beta.3 * Requires PHP: 7.4 * Requires at least: 5.0 * - * @version 3.7.1-beta.2 + * @version 3.7.1-beta.3 * @package Code_Snippets * @author Shea Bunge * @copyright 2012-2024 Code Snippets Pro @@ -37,7 +37,7 @@ * * @const string */ - define( 'CODE_SNIPPETS_VERSION', '3.7.1-beta.2' ); + define( 'CODE_SNIPPETS_VERSION', '3.7.1-beta.3' ); /** * The full path to the main file of this plugin. From 27a80f2edb01c34f79eca51cede8fb75e7c9c08e Mon Sep 17 00:00:00 2001 From: Imants Date: Wed, 22 Oct 2025 16:27:47 +0300 Subject: [PATCH 11/12] fix: changelog --- CHANGELOG.md | 7 ------- src/readme.txt | 9 --------- 2 files changed, 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2885abe9..5a333535 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,14 +7,7 @@ ### Added * Snippets REST API now supports pagination via page and per_page query parameters. -* Collection responses include pagination metadata headers for total items and total pages. -### Changed -* Settings UI CSS switched to logical properties for better RTL support and consistent layout. - -### Fixed -* Snippets REST API now correctly respects the network parameter when listing snippets. -* Pagination logic corrected to reliably slice results and return stable pages. ## [3.7.1-beta.2] (2025-10-22) diff --git a/src/readme.txt b/src/readme.txt index 55844435..167f9bf3 100644 --- a/src/readme.txt +++ b/src/readme.txt @@ -111,16 +111,7 @@ You can report security bugs found in the source code of this plugin through the __Added__ * Snippets REST API now supports pagination via page and per_page query parameters. -* Collection responses include pagination metadata headers for total items and total pages. -__Changed__ - -* Settings UI CSS switched to logical properties for better RTL support and consistent layout. - -__Fixed__ - -* Snippets REST API now correctly respects the network parameter when listing snippets. -* Pagination logic corrected to reliably slice results and return stable pages. = 3.7.1-beta.2 (2025-10-22) = From 95af256ad459ab4789058bd6712d26e23fd85e4c Mon Sep 17 00:00:00 2001 From: Imants Date: Wed, 22 Oct 2025 16:27:56 +0300 Subject: [PATCH 12/12] fix: version --- src/code-snippets.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/code-snippets.php b/src/code-snippets.php index 9f7789c1..1db3c0bc 100644 --- a/src/code-snippets.php +++ b/src/code-snippets.php @@ -8,7 +8,7 @@ * License: GPL-2.0-or-later * License URI: license.txt * Text Domain: code-snippets - * Version: 3.7.1-beta.3-beta.3 + * Version: 3.7.1-beta.3 * Requires PHP: 7.4 * Requires at least: 5.0 *