diff --git a/admin/src/RepoInstaller.php b/admin/src/RepoInstaller.php new file mode 100644 index 0000000..f43ac12 --- /dev/null +++ b/admin/src/RepoInstaller.php @@ -0,0 +1,108 @@ +repoManager = new RepoManager(); + } + + public function downloadExtractRepo( string $repository ): void + { + $response = $this->repoManager->getRepoInfoByRepoName( $repository ); + + if ( ! isset( $response["zipball_url"] ) ) { + wp_redirect( wp_get_referer() ); + + return; + } + + $zip_url = $response["zipball_url"]; + $destination_path = WP_PLUGIN_DIR . '/' . $repository . ".zip"; + + if ( ! $this->downloadZipFile( $zip_url, $destination_path ) ) { + wp_redirect( wp_get_referer() ); + + return; + } + + $zip = new ZipArchive(); + if ( $zip->open( $destination_path ) === true ) { + $pluginDestination = WP_PLUGIN_DIR; + + $name = $zip->getNameIndex( 0 ); + + // extract the plugin + $success = $zip->extractTo( $pluginDestination ); + $zip->close(); + + $pluginRepoPath = $pluginDestination . '/' . $repository; + $pluginRepoGeneratedName = $pluginDestination . '/' . $name; + + // if old repo data exists delete it + if ( $success && is_dir( $pluginRepoPath ) ) { + $deletedOldRepo = $this->delTree( $pluginRepoPath ); + } + +// rename the plugin to the correct name + if ( is_dir( $pluginRepoGeneratedName ) ) { + rename( $pluginRepoGeneratedName, $pluginRepoPath ); + } + + // removes the zip file + unlink( $destination_path ); + + // generate autoload files + $this->composer_dump_autoload( $pluginRepoPath ); + } + } + + + private function downloadZipFile( $url, $filepath ): bool + { + $token = get_option( 'repo-key' ); + + $ch = curl_init( $url ); + curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 10 ); + 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' ); + curl_setopt( $ch, CURLOPT_HTTPHEADER, array( + 'Content-Type: application/json', + 'Authorization: Bearer ' . $token + ) ); + curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); + curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true ); + curl_setopt( $ch, CURLOPT_AUTOREFERER, true ); + curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, true ); + curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 ); + + $result = curl_exec( $ch ); + $status_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); //get status code + curl_close( $ch ); + + file_put_contents( $filepath, $result ); + + return ( filesize( $filepath ) > 0 ) ? true : false; + } + + private function delTree( $dir ): bool + { + $files = array_diff( scandir( $dir ), array( '.', '..' ) ); + foreach ( $files as $file ) { + ( is_dir( "$dir/$file" ) ) ? $this->delTree( "$dir/$file" ) : unlink( "$dir/$file" ); + } + + return rmdir( $dir ); + + } + + private function composer_dump_autoload( string $filePath ): void + { + exec( "cd $filePath && composer dump-autoload -o" ); + } +} diff --git a/admin/src/RepoManager.php b/admin/src/RepoManager.php new file mode 100644 index 0000000..d7120bc --- /dev/null +++ b/admin/src/RepoManager.php @@ -0,0 +1,83 @@ +username = 'Trizelos'; + $this->authorizeToken = get_option( 'repo-key' ); + } + + public function getRepoList(): array + { + $repos = []; + foreach ( $this->getRepos() as $repo ) { + $name = $repo['name']; + $repoInfos = $this->getRepoInfoByRepoName( $name ); + if ( empty( $repoInfos ) ) { + continue; + } + + $pluginFile = WP_PLUGIN_DIR . '/' . $name . '/' . $name . '.php'; + $pluginData = get_plugin_data( $pluginFile ); + + $repos[ $name . '/' . $name . '.php' ]['name'] = $name; + $repos[ $name . '/' . $name . '.php' ]['repoInfos'] = $repoInfos; + $repos[ $name . '/' . $name . '.php' ]['pluginData'] = $pluginData; + } + +// pre( $repos ); + + return $repos; + } + + private function getRepos(): array + { + $request_uri = sprintf( 'https://api.github.com/orgs/%s/repos', $this->username ); // Build URI + $responses = $this->getResponse( $request_uri ); + + if ( ! is_array( $responses ) || empty( $responses[0]['name'] ) ) { + return []; + } + + $repos = []; + foreach ( $responses as $response ) { + if ( ! str_contains( $response['name'], 'cerberus' ) ) { + continue; + } + $repos[] = $response; + } + + return $repos; + } + + private function getResponse( string $request_uri ): mixed + { + $args = array(); + + if ( $this->authorizeToken ) { // Is there an access token? + $args['headers']['Authorization'] = "bearer {$this->authorizeToken}"; // Set the headers + } + + $response = json_decode( wp_remote_retrieve_body( wp_remote_get( $request_uri, $args ) ), true ); // Get JSON and parse it + + return $response; + } + + public function getRepoInfoByRepoName( string $repoName ): array|bool + { + $request_uri = sprintf( 'https://api.github.com/repos/%s/%s/releases', $this->username, $repoName ); // Build URI + $response = $this->getResponse( $request_uri ); + + if ( is_array( $response ) ) { // If it is an array + $response = current( $response ); // Get the first item + } + + return $response; + } +} diff --git a/admin/src/SettingsPage.php b/admin/src/SettingsPage.php index 4da4026..b2ff1ab 100644 --- a/admin/src/SettingsPage.php +++ b/admin/src/SettingsPage.php @@ -2,8 +2,6 @@ namespace Cerberus\AdminPluginsManager; -use ZipArchive; - class SettingsPage { private $file_name; @@ -63,10 +61,8 @@ public final function settingsPage(): void getRepos( 'Trizelos', $repoKey ); - - $responses = apply_filters( 'cerberus-core-repos-settings', $repos ); + $repoManager = new RepoManager(); + $repoList = $repoManager->getRepoList(); ?>
@@ -86,17 +82,20 @@ public final function settingsPage(): void $data ) { - if ( $name == 'cerberus-plugins-manager/cerberus-plugins-manager.php' ) { + foreach ( $repoList as $name => $data ) { + if ( empty( $data ) || $name == 'cerberus-plugins-manager/cerberus-plugins-manager.php' ) { continue; } - $response = $data['response']; - $plugin_data = $data['plugin_data']; + $response = $data['repoInfos']; + $plugin_data = $data['pluginData']; $state = empty( $response ) ? 'install' : 'update'; if ( ! empty( $response['tag_name'] ) ) { $state = version_compare( $response['tag_name'], $plugin_data['Version'], 'gt' ) ? 'out-of-date' : $state; } + if ( empty( $plugin_data['Version'] ) ) { + $state = 'install'; + } ?> @@ -105,7 +104,7 @@ public final function settingsPage(): void - +