PluginProbe
Image Optimizer – Compress Images and Convert to WebP or AVIF / 1.7.4
Image Optimizer – Compress Images and Convert to WebP or AVIF v1.7.4
1.7.7 1.7.6 1.7.5 1.7.4 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.2.1 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 All 33 releases
image-optimization / vendor / elementor / wp-one-package / src / Admin / Controllers / Themes.php

Themes.php in Image Optimizer – Compress Images and Convert to WebP or AVIF 1.7.4, at vendor/elementor/wp-one-package/src/Admin/Controllers/Themes.php

229 lines 5.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace ElementorOne\Admin\Controllers;
4
5 use ElementorOne\Admin\Config;
6 use ElementorOne\Common\RestError;
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly
10 }
11
12 /**
13 * Class Themes
14 * Extends WordPress's built-in REST Themes Controller
15 * Handles all themes-related REST API endpoints
16 */
17 class Themes extends \WP_REST_Themes_Controller {
18
19 /**
20 * Constructor
21 * @return void
22 */
23 public function __construct() {
24 $this->namespace = Config::APP_REST_NAMESPACE;
25 $this->rest_base = 'themes';
26
27 add_action( 'rest_api_init', [ $this, 'register_routes' ] );
28 }
29
30 /**
31 * Register all themes-related routes
32 * @return void
33 */
34 public function register_routes() {
35 // POST /themes - Install theme
36 register_rest_route(
37 $this->namespace,
38 '/' . $this->rest_base,
39 [
40 [
41 'methods' => \WP_REST_Server::CREATABLE,
42 'callback' => [ $this, 'install_theme' ],
43 'permission_callback' => [ $this, 'create_item_permissions_check' ],
44 'args' => [
45 'slug' => [
46 'type' => 'string',
47 'required' => true,
48 'description' => 'WordPress.org theme directory slug.',
49 'pattern' => '[\w\-]+',
50 ],
51 'status' => [
52 'description' => 'The theme activation status.',
53 'type' => 'string',
54 'enum' => [ 'inactive', 'active' ],
55 'default' => 'inactive',
56 ],
57 ],
58 ],
59 ]
60 );
61
62 // POST /themes/{slug}/activate
63 register_rest_route(
64 $this->namespace,
65 '/' . $this->rest_base . '/(?P<slug>[\w\-]+)/activate',
66 [
67 [
68 'methods' => \WP_REST_Server::CREATABLE,
69 'callback' => [ $this, 'activate_theme' ],
70 'permission_callback' => [ $this, 'user_can_manage_theme_status' ],
71 'args' => [
72 'slug' => [
73 'type' => 'string',
74 'required' => true,
75 'description' => 'WordPress.org theme directory slug.',
76 'pattern' => '[\w\-]+',
77 ],
78 ],
79 ],
80 ]
81 );
82 }
83
84 /**
85 * Install a theme
86 * @param \WP_REST_Request $request
87 * @return \WP_REST_Response|\WP_Error
88 */
89 public function install_theme( $request ) {
90 require_once ABSPATH . 'wp-admin/includes/file.php';
91 require_once ABSPATH . 'wp-admin/includes/theme.php';
92 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
93 require_once ABSPATH . 'wp-admin/includes/theme-install.php';
94
95 $skin = new \WP_Ajax_Upgrader_Skin();
96 $upgrader = new \Theme_Upgrader( $skin );
97
98 $package_url = $this->get_package_url_from_theme_slug( $request['slug'] );
99
100 if ( is_wp_error( $package_url ) ) {
101 return $package_url;
102 }
103
104 $result = $upgrader->install( $package_url );
105
106 if ( is_wp_error( $result ) ) {
107 return $result;
108 }
109
110 if ( is_wp_error( $skin->result ) ) {
111 return $skin->result;
112 }
113
114 if ( $skin->get_errors()->has_errors() ) {
115 return $skin->get_errors();
116 }
117
118 if ( ! $result ) {
119 return RestError::internal_server_error( 'Unable to install the theme.' );
120 }
121
122 if ( 'active' === $request['status'] ) {
123 $theme = wp_get_theme( $request['slug'] );
124 if ( ! $theme->exists() ) {
125 return RestError::not_found( 'Theme not found.' );
126 }
127
128 if ( ! $theme->is_allowed() ) {
129 return RestError::bad_request( 'Theme is broken or not compatible.' );
130 }
131
132 switch_theme( $theme->get_stylesheet() );
133 }
134
135 return rest_ensure_response( [
136 'status' => 'success',
137 'message' => 'Theme installed successfully.',
138 ] );
139 }
140
141 /**
142 * Activate a theme
143 * @param \WP_REST_Request $request
144 * @return \WP_REST_Response|\WP_Error
145 */
146 public function activate_theme( $request ) {
147 $theme = wp_get_theme( $request['slug'] );
148 if ( ! $theme->exists() ) {
149 return RestError::not_found( 'Theme not found.' );
150 }
151
152 if ( $theme->get_stylesheet() === get_stylesheet() ) {
153 return RestError::bad_request( 'Theme is already active.' );
154 }
155
156 if ( ! $theme->is_allowed() ) {
157 return RestError::bad_request( 'Theme is broken or not compatible.' );
158 }
159
160 switch_theme( $theme->get_stylesheet() );
161
162 return rest_ensure_response( [
163 'status' => 'success',
164 'message' => 'Theme activated successfully.',
165 ] );
166 }
167
168 /**
169 * Get the package URL from the theme slug
170 * @param string $theme_slug
171 * @return string|WP_Error
172 */
173 private function get_package_url_from_theme_slug( string $theme_slug ) {
174 $installed_themes = wp_get_themes();
175 if ( isset( $installed_themes[ $theme_slug ] ) ) {
176 return RestError::conflict( 'Theme already installed.' );
177 }
178
179 $api = themes_api( 'theme_information', [
180 'slug' => $theme_slug,
181 'fields' => [
182 'sections' => false,
183 ],
184 ] );
185
186 if ( is_wp_error( $api ) ) {
187 if ( str_contains( $api->get_error_message(), 'Theme not found.' ) ) {
188 return RestError::not_found( $api->get_error_message() );
189 } else {
190 return RestError::internal_server_error( $api->get_error_message() );
191 }
192 }
193
194 return $api->download_link;
195 }
196
197 /**
198 * Checks if a given request has access to upload themes.
199 *
200 * @since 5.5.0
201 *
202 * @param WP_REST_Request $request Full details about the request.
203 * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
204 */
205 public function create_item_permissions_check( $request ) {
206 if ( ! current_user_can( 'install_themes' ) ) {
207 return RestError::forbidden( 'Sorry, you are not allowed to install themes on this site.' );
208 }
209
210 return true;
211 }
212
213 /**
214 * Checks if a given request has access to manage theme status.
215 *
216 * @since 5.5.0
217 *
218 * @param WP_REST_Request $request Full details about the request.
219 * @return true|WP_Error True if the request has access to manage theme status, WP_Error object otherwise.
220 */
221 public function user_can_manage_theme_status( $request ) {
222 if ( ! current_user_can( 'switch_themes' ) ) {
223 return RestError::forbidden( 'Sorry, you are not allowed to switch themes on this site.' );
224 }
225
226 return true;
227 }
228 }
229