PluginProbe
Cool Timeline (Horizontal & Vertical Timeline) / trunk
Cool Timeline (Horizontal & Vertical Timeline) vtrunk
3.4.0 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 2.2.3 2.3.3 2.4 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.6.1 2.7.1 2.8.3 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8 2.9.9 3.0.0 All 79 releases
cool-timeline / admin / class-ctl-plugin-installer.php

class-ctl-plugin-installer.php in Cool Timeline (Horizontal & Vertical Timeline) trunk, at admin/class-ctl-plugin-installer.php

202 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Shared plugin install/activation service.
4 *
5 * @package CoolTimeline
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 if ( ! class_exists( 'CTL_Plugin_Installer' ) ) {
13 /**
14 * Installs WordPress.org plugins and activates existing plugin files.
15 */
16 class CTL_Plugin_Installer {
17
18 /**
19 * Install a plugin from WordPress.org and activate it when possible.
20 *
21 * @param string $slug WordPress.org plugin slug.
22 * @param array $status Base response payload.
23 * @return array{success:bool,data:array}
24 */
25 public function install_and_activate( $slug, $status = array() ) {
26 if(!current_user_can('install_plugins')){
27 return $this->error( array( 'message' => __( 'Permission denied', 'cool-timeline' ) ) );
28 }
29
30 $this->load_dependencies();
31
32 $status = array_merge(
33 array(
34 'install' => 'plugin',
35 'slug' => $slug,
36 ),
37 $status
38 );
39
40 $api = plugins_api(
41 'plugin_information',
42 array(
43 'slug' => $slug,
44 'fields' => array(
45 'sections' => false,
46 ),
47 )
48 );
49
50 if ( is_wp_error( $api ) ) {
51 $status['errorMessage'] = $api->get_error_message();
52 return $this->error( $status );
53 }
54
55 $status['pluginName'] = $api->name;
56
57 $skin = new WP_Ajax_Upgrader_Skin();
58 $upgrader = new Plugin_Upgrader( $skin );
59 $result = $upgrader->install( $api->download_link );
60
61 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
62 $status['debug'] = $skin->get_upgrade_messages();
63 }
64
65 if ( is_wp_error( $result ) ) {
66 $status['errorCode'] = $result->get_error_code();
67 $status['errorMessage'] = $result->get_error_message();
68 return $this->error( $status );
69 }
70
71 if ( is_wp_error( $skin->result ) ) {
72 if ( 'Destination folder already exists.' === $skin->result->get_error_message() ) {
73 return $this->activate_installed_plugin( $api, $status );
74 }
75
76 $status['errorCode'] = $skin->result->get_error_code();
77 $status['errorMessage'] = $skin->result->get_error_message();
78 return $this->error( $status );
79 }
80
81 if ( $skin->get_errors()->has_errors() ) {
82 $status['errorMessage'] = $skin->get_error_messages();
83 return $this->error( $status );
84 }
85
86 if ( is_null( $result ) ) {
87 global $wp_filesystem;
88
89 $status['errorCode'] = 'unable_to_connect_to_filesystem';
90 $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.', 'cool-timeline' );
91
92 if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() ) {
93 $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() );
94 }
95
96 return $this->error( $status );
97 }
98
99 return $this->activate_installed_plugin( $api, $status );
100 }
101
102 /**
103 * Activate an already installed plugin file.
104 *
105 * @param string $plugin_file Plugin basename.
106 * @param string $slug Plugin slug for response payload.
107 * @return array{success:bool,data:array}
108 */
109 public function activate_plugin_file( $plugin_file, $slug ) {
110 $this->load_dependencies();
111
112 if ( ! current_user_can( 'activate_plugin', $plugin_file ) ) {
113 return $this->error( array( 'message' => __( 'Permission denied', 'cool-timeline' ) ) );
114 }
115
116 $activation_result = activate_plugin( $plugin_file, '', $this->is_network_wide_request() );
117 if ( is_wp_error( $activation_result ) ) {
118 return $this->error( array( 'message' => $activation_result->get_error_message() ) );
119 }
120
121 return $this->success(
122 array(
123 'message' => __( 'Plugin activated successfully', 'cool-timeline' ),
124 'activated' => true,
125 'plugin_slug' => $slug,
126 )
127 );
128 }
129
130 /**
131 * Activate plugin reported by install_plugin_install_status().
132 *
133 * @param object $api Plugin API response.
134 * @param array $status Response payload.
135 * @return array{success:bool,data:array}
136 */
137 private function activate_installed_plugin( $api, $status ) {
138 $install_status = install_plugin_install_status( $api );
139
140 if ( current_user_can( 'activate_plugin', $install_status['file'] ) && is_plugin_inactive( $install_status['file'] ) ) {
141 $activation_result = activate_plugin( $install_status['file'], '', $this->is_network_wide_request() );
142 if ( is_wp_error( $activation_result ) ) {
143 $status['errorCode'] = $activation_result->get_error_code();
144 $status['errorMessage'] = $activation_result->get_error_message();
145 return $this->error( $status );
146 }
147
148 $status['activated'] = true;
149 }
150
151 return $this->success( $status );
152 }
153
154 /**
155 * Load WordPress plugin installer dependencies.
156 */
157 private function load_dependencies() {
158 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
159 require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
160 require_once ABSPATH . 'wp-admin/includes/plugin.php';
161 }
162
163 /**
164 * Determine whether activation should be network-wide.
165 *
166 * @return bool
167 */
168 private function is_network_wide_request() {
169 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce is checked in AJAX handlers.
170 $pagenow = isset( $_POST['pagenow'] ) ? sanitize_key( wp_unslash( $_POST['pagenow'] ) ) : '';
171
172 return is_multisite() && 'import' !== $pagenow;
173 }
174
175 /**
176 * Build a success result.
177 *
178 * @param array $data Response data.
179 * @return array{success:bool,data:array}
180 */
181 private function success( $data ) {
182 return array(
183 'success' => true,
184 'data' => $data,
185 );
186 }
187
188 /**
189 * Build an error result.
190 *
191 * @param array $data Response data.
192 * @return array{success:bool,data:array}
193 */
194 private function error( $data ) {
195 return array(
196 'success' => false,
197 'data' => $data,
198 );
199 }
200 }
201 }
202