From e754d249af4b960fc06f2232b9dc50628bca56ac Mon Sep 17 00:00:00 2001 From: Enej Bajgoric Date: Mon, 7 Nov 2016 15:45:24 -0800 Subject: [PATCH] Add Themes New api endpoint. --- class.jetpack.php | 6 ++ class.json-api-endpoints.php | 1 + ...pack-json-api-plugins-install-endpoint.php | 4 +- ...s.jetpack-json-api-themes-new-endpoint.php | 82 +++++++++++++++++++ .../jetpack/json-api-jetpack-endpoints.php | 26 ++++++ 5 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 json-endpoints/jetpack/class.jetpack-json-api-themes-new-endpoint.php diff --git a/class.jetpack.php b/class.jetpack.php index 25c9db6d736b2..e6e5c28fba90c 100644 --- a/class.jetpack.php +++ b/class.jetpack.php @@ -3090,6 +3090,12 @@ function upload_handler() { 'type' => $attachment->post_mime_type, 'meta' => wp_get_attachment_metadata( $attachment_id ), ); + // Zip files uploads are not supported unless they are done for installation purposed + // lets delete them in case something goes wrong in this whole process + if ( 'application/zip' === $attachment->post_mime_type ) { + // Schedule a cleanup for 2 hours from now in case of failed install. + wp_schedule_single_event( time() + 2 * HOUR_IN_SECONDS, 'upgrader_scheduled_cleanup', array( $attachment_id ) ); + } } } if ( ! is_null( $global_post ) ) { diff --git a/class.json-api-endpoints.php b/class.json-api-endpoints.php index 5d4eb288e277c..69f457dda1644 100644 --- a/class.json-api-endpoints.php +++ b/class.json-api-endpoints.php @@ -384,6 +384,7 @@ function cast_and_filter_item( &$return, $type, $key, $value, $types = array(), case 'safehtml' : $return[$key] = wp_kses( (string) $value, wp_kses_allowed_html() ); break; + case 'zip' : case 'media' : if ( is_array( $value ) ) { if ( isset( $value['name'] ) && is_array( $value['name'] ) ) { diff --git a/json-endpoints/jetpack/class.jetpack-json-api-plugins-install-endpoint.php b/json-endpoints/jetpack/class.jetpack-json-api-plugins-install-endpoint.php index 328919f972c27..bc950b399cf0e 100644 --- a/json-endpoints/jetpack/class.jetpack-json-api-plugins-install-endpoint.php +++ b/json-endpoints/jetpack/class.jetpack-json-api-plugins-install-endpoint.php @@ -12,7 +12,7 @@ class Jetpack_JSON_API_Plugins_Install_Endpoint extends Jetpack_JSON_API_Plugins protected function install() { foreach ( $this->plugins as $index => $slug ) { - $skin = new Jetpack_Automatic_Plugin_Install_Skin(); + $skin = new Jetpack_Automatic_Install_Skin(); $upgrader = new Plugin_Upgrader( $skin ); $zip_url = self::generate_wordpress_org_plugin_download_link( $slug ); @@ -98,7 +98,7 @@ protected static function get_slug_from_file_path( $plugin_file ) { * Allows us to capture that the site doesn't have proper file system access. * In order to update the plugin. */ -class Jetpack_Automatic_Plugin_Install_Skin extends Automatic_Upgrader_Skin { +class Jetpack_Automatic_Install_Skin extends Automatic_Upgrader_Skin { /** * Stores the last error key; **/ diff --git a/json-endpoints/jetpack/class.jetpack-json-api-themes-new-endpoint.php b/json-endpoints/jetpack/class.jetpack-json-api-themes-new-endpoint.php new file mode 100644 index 0000000000000..eeacfce91254a --- /dev/null +++ b/json-endpoints/jetpack/class.jetpack-json-api-themes-new-endpoint.php @@ -0,0 +1,82 @@ +input(); + if ( isset( $args['zip'][0]['id'] ) ) { + wp_delete_attachment( $args['zip'][0]['id'], true ); + } + } + + return $validate; + } + + protected function validate_input( $theme ) { + $this->bulk = false; + $this->themes = array(); + } + + function install() { + $args = $this->input(); + + if ( isset( $args['zip'][0]['id'] ) ) { + $attachment_id = $args['zip'][0]['id']; + $local_file = get_attached_file( $attachment_id ); + if ( ! $local_file ) { + return new WP_Error( 'local-file-does-not-exist' ); + } + $skin = new Jetpack_Automatic_Install_Skin(); + $upgrader = new Theme_Upgrader( $skin ); + + $pre_install_list = wp_get_themes(); + $result = $upgrader->install( $local_file ); + + // clean up. + wp_delete_attachment( $attachment_id, true ); + + if ( is_wp_error( $result ) ) { + return $result; + } + + $after_install_list = wp_get_themes(); + $plugin = array_values( array_diff( array_keys( $after_install_list ), array_keys( $pre_install_list ) ) ); + + if ( ! $result ) { + $error_code = $upgrader->skin->get_main_error_code(); + $message = $upgrader->skin->get_main_error_message(); + if ( empty( $message ) ) { + $message = __( 'An unknown error occurred during installation', 'jetpack' ); + } + + if ( 'download_failed' === $error_code ) { + $error_code = 'no_package'; + } + + return new WP_Error( $error_code, $message, 400 ); + } + + if ( empty( $plugin ) ) { + return new WP_Error( 'theme_already_installed' ); + } + + $this->themes = $plugin; + $this->log[ $plugin[0] ] = $upgrader->skin->get_upgrade_messages(); + + return true; + } + + return new WP_Error( 'no_theme_installed' ); + } +} diff --git a/json-endpoints/jetpack/json-api-jetpack-endpoints.php b/json-endpoints/jetpack/json-api-jetpack-endpoints.php index e41d5e79d0236..78180ea4f0228 100644 --- a/json-endpoints/jetpack/json-api-jetpack-endpoints.php +++ b/json-endpoints/jetpack/json-api-jetpack-endpoints.php @@ -75,6 +75,32 @@ ) ); require_once( $json_jetpack_endpoints_dir . 'class.jetpack-json-api-themes-get-endpoint.php' ); +require_once( $json_jetpack_endpoints_dir . 'class.jetpack-json-api-themes-new-endpoint.php' ); + +// POST /sites/%s/themes/%new +new Jetpack_JSON_API_Themes_new_Endpoint( array( + 'description' => 'Install a theme to your jetpack blog', + 'group' => '__do_not_document', + 'stat' => 'themes:new', + 'method' => 'POST', + 'path' => '/sites/%s/themes/new', + 'path_labels' => array( + '$site' => '(int|string) The site ID, The site domain', + ), + 'request_format' => array( + 'zip' => '(zip) Theme package zip file. multipart/form-data encoded. ', + ), + 'response_format' => Jetpack_JSON_API_Themes_Endpoint::$_response_format, + 'example_request_data' => array( + 'headers' => array( + 'authorization' => 'Bearer YOUR_API_TOKEN' + ), + ), + 'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/example.wordpress.org/themes/new' +) ); + + + new Jetpack_JSON_API_Themes_Get_Endpoint( array( 'description' => 'Get a single theme on a jetpack blog', 'group' => '__do_not_document',