diff --git a/lib/class-wp-rest-plugins-controller.php b/lib/class-wp-rest-plugins-controller.php index 8e6ac19..c34da84 100644 --- a/lib/class-wp-rest-plugins-controller.php +++ b/lib/class-wp-rest-plugins-controller.php @@ -57,7 +57,7 @@ public function get_items( $request ) { $data = array(); require_once ABSPATH . '/wp-admin/includes/plugin.php'; - foreach ( get_plugins() as $obj ) { + foreach ( $this->get_plugins() as $obj ) { $plugin = $this->prepare_item_for_response( $obj, $request ); if ( is_wp_error( $plugin ) ) { continue; @@ -87,21 +87,10 @@ public function get_item_permissions_check( $request ) { public function get_item( $request ) { $slug = $request['slug']; - $plugin = null; + $plugin = $this->get_plugin( $slug ); - require_once ABSPATH . '/wp-admin/includes/plugin.php'; - $plugins = get_plugins(); - - foreach ( $plugins as $active_plugin ) { - $sanitized_title = sanitize_title( $active_plugin['Name'] ); - if ( $slug === $sanitized_title ) { - $plugin = $active_plugin; - break; - } - } - - if ( ! $plugin ) { - return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post id.' ), array( 'status' => 404 ) ); + if ( null === $plugin ) { + return new WP_Error( 'rest_plugin_invalid_slug', sprintf( __( 'Plugin with slug %s not found.' ), $slug ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $plugin, $request ); @@ -120,7 +109,7 @@ public function get_item( $request ) { public function delete_item_permissions_check( $request ) { if ( ! current_user_can( 'delete_plugins' ) ) { - return new WP_Error( 'rest_forbidden', __( 'Sorry, you cannot delete this plugin' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'rest_forbidden', __( 'Sorry, you cannot delete plugins' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -135,6 +124,27 @@ public function delete_item_permissions_check( $request ) { */ public function delete_item( $request ) { + $slug = $request['slug']; + + $plugin = $this->get_plugin( $slug ); + + if ( null === $plugin ) { + return new WP_Error( 'rest_plugin_invalid_slug', sprintf( __( 'Plugin with slug %s not found.' ), $slug ), array( 'status' => 404 ) ); + } + + /* + * TODO: we cannot directly use the delete_plugins() function because that has the possibility of terminating the script with a nice exit() call + * + * my initial stab at this would be: + * + * ob_start() + * request_filesystem_credentials() - if this is false => WP_Error (code =? message =?) + * if ( ! WP_filesyste( $credentials ) ) => WP_Error + * + * at this point, delete_plugins() can be called + * + */ + } public function get_item_schema() { @@ -143,6 +153,10 @@ public function get_item_schema() { 'title' => 'plugin', 'type' => 'object', 'properties' => array( + 'slug' => array( + 'description' => __( 'Identifier for the plugin' ), + 'type' => 'string', + ), 'name' => array( 'description' => __( 'The title for the resource.' ), 'type' => 'string', @@ -200,6 +214,7 @@ public function get_collection_params() { public function prepare_item_for_response( $plugin, $request ) { $data = array( + 'slug' => $plugin['slug'], 'name' => $plugin['Name'], 'plugin_uri' => $plugin['PluginURI'], 'version' => $plugin['Version'], @@ -215,4 +230,52 @@ public function prepare_item_for_response( $plugin, $request ) { return $data; } + + /** + * Find a plugin by slug + * + * @param string $slug + * @return array|null + */ + protected function get_plugin( $slug ) { + + require_once ABSPATH . '/wp-admin/includes/plugin.php'; + + foreach ( $this->get_plugins() as $_path => $plugin ) { + if ( $slug === $plugin['slug'] ) { + return $plugin; + } + } + + return null; + } + + /** + * Fetches the list of plugins, with additional slug and _path fields added to each item + * + * @return array + */ + protected function get_plugins() { + $_plugins = array(); + + foreach ( get_plugins() as $_path => $plugin ) { + $plugin['_path'] = $_path; + $plugin['slug'] = $this->get_slug( $plugin ); + $_plugins[ $_path ] = $plugin; + } + + return $_plugins; + } + + /** + * Get the slug (identifier) for a plugin based on its name + * + * @param array $plugin + * @return string + */ + protected function get_slug( $plugin ) { + + return sanitize_title( $plugin['Name'] ); + + } } diff --git a/tests/test-rest-plugins-controller.php b/tests/test-rest-plugins-controller.php index 350260b..ce18357 100644 --- a/tests/test-rest-plugins-controller.php +++ b/tests/test-rest-plugins-controller.php @@ -75,7 +75,8 @@ public function test_get_item_schema() { $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertEquals( 11, count( $properties ) ); + $this->assertEquals( 12, count( $properties ) ); + $this->assertArrayHasKey( 'slug', $properties ); $this->assertArrayHasKey( 'name', $properties ); $this->assertArrayHasKey( 'plugin_uri', $properties ); $this->assertArrayHasKey( 'version', $properties ); diff --git a/tests/test-rest-themes-controller.php b/tests/test-rest-themes-controller.php index 1682b9f..8bfe2f2 100644 --- a/tests/test-rest-themes-controller.php +++ b/tests/test-rest-themes-controller.php @@ -11,7 +11,7 @@ public function test_register_routes() { public function test_get_items_without_permissions() { wp_set_current_user( 0 ); - $request = new WP_REST_Request( 'GET', '/wp/v2/plugins' ); + $request = new WP_REST_Request( 'GET', '/wp/v2/themes' ); $response = $this->server->dispatch( $request );