|
2 | 2 |
|
3 | 3 | namespace Cerberus\AdminPluginsManager;
|
4 | 4 |
|
| 5 | +use ZipArchive; |
| 6 | + |
5 | 7 | class SettingsPage
|
6 | 8 | {
|
7 |
| - private $file_name; |
8 |
| - |
9 |
| - public function __construct( string $file_name ) |
10 |
| - { |
11 |
| - $this->file_name = $file_name; |
12 |
| - add_action( 'admin_menu', [ $this, 'admin_menu' ], 1000 ); |
13 |
| - add_action( 'admin_post_cpm_settings', [ $this, 'admin_post_cpm_settings' ] ); |
14 |
| - add_action( 'admin_post_nopriv_cpm_settings', [ $this, 'admin_post_cpm_settings' ] ); |
15 |
| - |
16 |
| - add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] ); |
17 |
| - } |
18 |
| - |
19 |
| - public final function admin_enqueue_scripts(): void |
20 |
| - { |
21 |
| - wp_enqueue_style( 'cpm-admin', plugin_dir_url( $this->file_name ) . 'admin/assets/css/admin.css' ); |
22 |
| - } |
23 |
| - |
24 |
| - public final function admin_menu(): void |
25 |
| - { |
26 |
| - $title = __( 'Cerberus Plugins Manager Settings', 'cerberus-plugins-manager' ); |
27 |
| - add_submenu_page( |
28 |
| - 'woocommerce', |
29 |
| - $title, |
30 |
| - $title, |
31 |
| - 'administrator', |
32 |
| - 'cerberus_plugins_manager', |
33 |
| - array( $this, 'settingsPage' ) |
34 |
| - ); |
35 |
| - } |
36 |
| - |
37 |
| - public final function settingsPage(): void |
38 |
| - { |
39 |
| - $repoKey = get_option( 'repo-key', '' ); |
40 |
| - $title = __( 'Cerberus Plugins Manager Settings', 'cerberus-plugins-manager' ); |
41 |
| - |
42 |
| - ?> |
| 9 | + private $file_name; |
| 10 | + |
| 11 | + public function __construct(string $file_name) |
| 12 | + { |
| 13 | + $this->file_name = $file_name; |
| 14 | + add_action('admin_menu', [$this, 'admin_menu'], 1000); |
| 15 | + add_action('admin_post_cpm_settings', [$this, 'admin_post_cpm_settings']); |
| 16 | + add_action('admin_post_nopriv_cpm_settings', [$this, 'admin_post_cpm_settings']); |
| 17 | + |
| 18 | + add_action('admin_enqueue_scripts', [$this, 'admin_enqueue_scripts']); |
| 19 | + |
| 20 | + add_action('admin_post_download_and_extract_repo', [$this, 'download_and_extract_repo']); |
| 21 | + add_action('admin_post_nopriv_download_and_extract_repo', [$this, 'download_and_extract_repo']); |
| 22 | + } |
| 23 | + |
| 24 | + public final function admin_enqueue_scripts(): void |
| 25 | + { |
| 26 | + wp_enqueue_style('cpm-admin', plugin_dir_url($this->file_name) . 'admin/assets/css/admin.css'); |
| 27 | + } |
| 28 | + |
| 29 | + public final function admin_menu(): void |
| 30 | + { |
| 31 | + $title = __('Cerberus Plugins Manager Settings', 'cerberus-plugins-manager'); |
| 32 | + add_submenu_page('woocommerce', $title, $title, 'administrator', 'cerberus_plugins_manager', array( |
| 33 | + $this, |
| 34 | + 'settingsPage' |
| 35 | + )); |
| 36 | + } |
| 37 | + |
| 38 | + public final function settingsPage(): void |
| 39 | + { |
| 40 | + $repoKey = get_option('repo-key', ''); |
| 41 | + $title = __('Cerberus Plugins Manager Settings', 'cerberus-plugins-manager'); |
| 42 | + |
| 43 | + ?> |
43 | 44 | <div>
|
44 | 45 | <h3><?= $title; ?> </h3>
|
45 | 46 | </div>
|
46 | 47 | <div>
|
47 |
| - <form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post" |
| 48 | + <form action="<?php echo esc_url(admin_url('admin-post.php')); ?>" method="post" |
48 | 49 | id="cpm_settings">
|
49 | 50 | <input type="hidden" name="action" value="cpm_settings"/>
|
50 | 51 | <label for="repo-key">
|
51 | 52 | <span>Repo Key: </span>
|
52 | 53 | <input type="text" name="repo-key" minlength="1">
|
53 | 54 | </label>
|
54 |
| - <?php |
55 |
| - if ( ! empty( $repoKey ) ) { |
56 |
| - echo '<span>Your repo key is set but hidden away.</span>'; |
57 |
| - } ?> |
| 55 | + <?php |
| 56 | + if (!empty($repoKey)) { |
| 57 | + echo '<span>Your repo key is set but hidden away.</span>'; |
| 58 | + } ?> |
58 | 59 | <div>
|
59 | 60 | <button class="button-primary" type="submit">Save</button>
|
60 | 61 | </div>
|
61 | 62 | </form>
|
62 | 63 | </div>
|
63 |
| - <?php |
| 64 | + <?php |
| 65 | + |
| 66 | + $repoKey = get_option('repo-key'); |
| 67 | + $repos = $this->getRepos('Trizelos', $repoKey); |
64 | 68 |
|
65 |
| - $responses = apply_filters( 'cerberus-core-repos-settings', [] ); |
| 69 | + $responses = apply_filters('cerberus-core-repos-settings', $repos); |
66 | 70 |
|
67 |
| - ?> |
| 71 | + ?> |
68 | 72 | <br>
|
69 |
| - <table class="cpm"> |
70 |
| - <thead> |
71 |
| - <tr> |
72 |
| - <th>Plugin</th> |
73 |
| - <th>Connection Status to Repo</th> |
74 |
| - <th>Newest Version</th> |
75 |
| - <th>Current Version</th> |
76 |
| - </tr> |
77 |
| - </thead> |
78 |
| - <tbody> |
79 |
| - <?php |
80 |
| - foreach ( $responses as $name => $data ) { |
81 |
| - $response = $data['response']; |
82 |
| - $plugin_data = $data['plugin_data']; |
83 |
| - |
84 |
| - $out_of_date = false; |
85 |
| - if ( ! empty( $response['tag_name'] ) ) { |
86 |
| - $out_of_date = version_compare( $response['tag_name'], $plugin_data['Version'], 'gt' ); |
87 |
| - } |
88 |
| - ?> |
89 |
| - <tr class="<?= $out_of_date ? 'out-of-date' : ''; ?>"> |
90 |
| - <td><?= $name; ?></td> |
91 |
| - <td><?= ( ! empty( $response ) && is_array( $response ) ? 'connected' : ( ! empty( $response ) ? $response : 'no release found' ) ); ?></td> |
92 |
| - <td> |
93 |
| - <?= ! empty( $response['tag_name'] ) ? $response['tag_name'] : 'Not version Found'; ?> |
94 |
| - </td> |
95 |
| - <td> |
96 |
| - <?= $plugin_data['Version']; ?> |
97 |
| - </td> |
| 73 | + <form action="<?php echo esc_url(admin_url('admin-post.php')); ?>" method="post" , |
| 74 | + id="download_and_repo_install"> |
| 75 | + <input type="hidden" name="action" value="download_and_extract_repo"/> |
| 76 | + <input type="hidden" name="repo-to-install" id="repo-to-install" value=""/> |
| 77 | + <table class="cpm"> |
| 78 | + <thead> |
| 79 | + <tr> |
| 80 | + <th>Plugin</th> |
| 81 | + <th>Connection Status to Repo</th> |
| 82 | + <th>Newest Version</th> |
| 83 | + <th>Current Version</th> |
| 84 | + <th>Install</th> |
98 | 85 | </tr>
|
99 |
| - <?php } ?> |
100 |
| - </tbody> |
101 |
| - </table> |
102 |
| - <?php |
103 |
| - } |
104 |
| - |
105 |
| - public final function admin_post_cpm_settings(): void |
106 |
| - { |
107 |
| - $data = $_POST; |
108 |
| - if ( ! empty( $data['repo-key'] ) ) { |
109 |
| - update_option( 'repo-key', $data['repo-key'] ); |
110 |
| - } |
111 |
| - |
112 |
| - wp_redirect( wp_get_referer() ); |
113 |
| - } |
| 86 | + </thead> |
| 87 | + <tbody> |
| 88 | + <?php |
| 89 | + foreach ($responses as $name => $data) { |
| 90 | + if ($name == 'cerberus-plugins-manager/cerberus-plugins-manager.php') { |
| 91 | + continue; |
| 92 | + } |
| 93 | + $response = $data['response']; |
| 94 | + $plugin_data = $data['plugin_data']; |
| 95 | + $installed = !empty($response); |
| 96 | + |
| 97 | + $out_of_date = false; |
| 98 | + if (!empty($response['tag_name'])) { |
| 99 | + $out_of_date = version_compare($response['tag_name'], $plugin_data['Version'], 'gt'); |
| 100 | + } |
| 101 | + ?> |
| 102 | + <tr class="<?= $out_of_date ? 'out-of-date' : ''; ?>"> |
| 103 | + <td><?= $name; ?></td> |
| 104 | + <td><?= (!empty($response) && is_array($response) ? 'connected' : (!empty($response) ? $response : 'no release found')); ?></td> |
| 105 | + <td> |
| 106 | + <?= !empty($response['tag_name']) ? $response['tag_name'] : 'No version Found'; ?> |
| 107 | + </td> |
| 108 | + <td> |
| 109 | + <?= !empty($plugin_data['Version']) ? $plugin_data['Version'] : 'Base'; ?> |
| 110 | + </td> |
| 111 | + <td> |
| 112 | + <button class="install-button primary button" <?= $installed ? 'disabled' : '' ?> |
| 113 | + data-repo="<?= empty($data['name']) ? '' : $data['name']; ?>" |
| 114 | + onclick="document.querySelector('#repo-to-install').value =this.dataset.repo;"> |
| 115 | + Install |
| 116 | + </button> |
| 117 | + </td> |
| 118 | + </tr> |
| 119 | + <?php } ?> |
| 120 | + </tbody> |
| 121 | + </table> |
| 122 | + </form> |
| 123 | + <?php |
| 124 | + } |
| 125 | + |
| 126 | + public function getRepos(string $repository, string $authorizeToken): array |
| 127 | + { |
| 128 | + $args = array(); |
| 129 | + $request_uri = sprintf('https://api.github.com/orgs/%s/repos', $repository); // Build URI |
| 130 | + |
| 131 | + if ($authorizeToken) { // Is there an access token? |
| 132 | + $args['headers']['Authorization'] = "bearer {$authorizeToken}"; // Set the headers |
| 133 | + } |
| 134 | + |
| 135 | + $responses = json_decode(wp_remote_retrieve_body(wp_remote_get($request_uri, $args)), true); // Get JSON and parse it |
| 136 | + |
| 137 | + $repos = []; |
| 138 | + foreach ($responses as $response) { |
| 139 | + if (!str_contains($response['name'], 'cerberus')) { |
| 140 | + continue; |
| 141 | + } |
| 142 | + $repos[$response['name'] . '/' . $response['name'] . '.php']['name'] = $response['name']; |
| 143 | + $repos[$response['name'] . '/' . $response['name'] . '.php']['response'] = ""; |
| 144 | + $repos[$response['name'] . '/' . $response['name'] . '.php']['plugin_data'] = ""; |
| 145 | + } |
| 146 | + |
| 147 | + return $repos; |
| 148 | + } |
| 149 | + |
| 150 | + public final function download_and_extract_repo(): void |
| 151 | + { |
| 152 | + if (empty($_POST['repo-to-install'])) { |
| 153 | + wp_redirect(wp_get_referer()); |
| 154 | + return; |
| 155 | + } |
| 156 | + |
| 157 | + $repository = $_POST['repo-to-install']; |
| 158 | + |
| 159 | + $response = $this->getRepoResponse($repository); |
| 160 | + |
| 161 | + if (!isset($response["zipball_url"])) { |
| 162 | + wp_redirect(wp_get_referer()); |
| 163 | + return; |
| 164 | + } |
| 165 | + |
| 166 | + $zip_url = $response["zipball_url"]; |
| 167 | + $destination_path = WP_PLUGIN_DIR . '/' . $repository . ".zip"; |
| 168 | + |
| 169 | + if (!$this->downloadZipFile($zip_url, $destination_path)) { |
| 170 | + wp_redirect(wp_get_referer()); |
| 171 | + return; |
| 172 | + } |
| 173 | + |
| 174 | + |
| 175 | + $zip = new ZipArchive(); |
| 176 | + if ($zip->open($destination_path) === true) { |
| 177 | + $pluginDestination = WP_PLUGIN_DIR; |
| 178 | + |
| 179 | + $name = $zip->getNameIndex(0); |
| 180 | + |
| 181 | + // extract the plugin |
| 182 | + $success = $zip->extractTo($pluginDestination); |
| 183 | + $zip->close(); |
| 184 | + |
| 185 | + $pluginRepoPath = $pluginDestination . '/' . $repository; |
| 186 | + $pluginRepoGeneratedName = $pluginDestination . '/' . $name; |
| 187 | + |
| 188 | + // if old repo data exists delete it |
| 189 | + if ($success && is_dir($pluginRepoPath)) { |
| 190 | + $deletedOldRepo = $this->delTree($pluginRepoPath); |
| 191 | + } |
| 192 | + |
| 193 | +// rename the plugin to the correct name |
| 194 | + if (is_dir($pluginRepoGeneratedName)) { |
| 195 | + rename($pluginRepoGeneratedName, $pluginRepoPath); |
| 196 | + } |
| 197 | + |
| 198 | + // removes the zip file |
| 199 | + unlink($destination_path); |
| 200 | + |
| 201 | + // generate autoload files |
| 202 | + $this->composer_dump_autoload($pluginRepoPath); |
| 203 | + } |
| 204 | + wp_redirect(wp_get_referer()); |
| 205 | + } |
| 206 | + |
| 207 | + private function getRepoResponse(string $repository): mixed |
| 208 | + { |
| 209 | + $username = 'Trizelos'; |
| 210 | + $authorize_token = get_option('repo-key'); |
| 211 | + $args = array(); |
| 212 | + $request_uri = sprintf('https://api.github.com/repos/%s/%s/releases', $username, $repository); // Build URI |
| 213 | + |
| 214 | + if ($authorize_token) { // Is there an access token? |
| 215 | + $args['headers']['Authorization'] = "bearer {$authorize_token}"; // Set the headers |
| 216 | + } |
| 217 | + |
| 218 | + $response = json_decode(wp_remote_retrieve_body(wp_remote_get($request_uri, $args)), true); // Get JSON and parse it |
| 219 | + |
| 220 | + if (is_array($response)) { // If it is an array |
| 221 | + $response = current($response); // Get the first item |
| 222 | + } |
| 223 | + |
| 224 | + return $response; |
| 225 | + } |
| 226 | + |
| 227 | + function downloadZipFile($url, $filepath): bool |
| 228 | + { |
| 229 | + $token = get_option('repo-key'); |
| 230 | + |
| 231 | + $ch = curl_init($url); |
| 232 | + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); |
| 233 | + curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763'); |
| 234 | + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: Bearer ' . $token)); |
| 235 | + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
| 236 | + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); |
| 237 | + curl_setopt($ch, CURLOPT_AUTOREFERER, true); |
| 238 | + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); |
| 239 | + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); |
| 240 | + |
| 241 | + $result = curl_exec($ch); |
| 242 | + $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); //get status code |
| 243 | + curl_close($ch); |
| 244 | + |
| 245 | + file_put_contents($filepath, $result); |
| 246 | + |
| 247 | + return (filesize($filepath) > 0) ? true : false; |
| 248 | + } |
| 249 | + |
| 250 | + private function delTree($dir): bool |
| 251 | + { |
| 252 | + $files = array_diff(scandir($dir), array('.', '..')); |
| 253 | + |
| 254 | + foreach ($files as $file) { |
| 255 | + |
| 256 | + (is_dir("$dir/$file")) ? $this->delTree("$dir/$file") : unlink("$dir/$file"); |
| 257 | + } |
| 258 | + |
| 259 | + return rmdir($dir); |
| 260 | + |
| 261 | + } |
| 262 | + |
| 263 | + private function composer_dump_autoload(string $filePath): void |
| 264 | + { |
| 265 | + exec("cd $filePath && composer dump-autoload -o"); |
| 266 | + |
| 267 | + prew('updated plugin: ' . $filePath); |
| 268 | + } |
| 269 | + |
| 270 | + public final function admin_post_cpm_settings(): void |
| 271 | + { |
| 272 | + $data = $_POST; |
| 273 | + if (!empty($data['repo-key'])) { |
| 274 | + update_option('repo-key', $data['repo-key']); |
| 275 | + } |
| 276 | + |
| 277 | + wp_redirect(wp_get_referer()); |
| 278 | + } |
114 | 279 | }
|
0 commit comments