Advertisement
cicklow

Untitled

Mar 1st, 2024
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.87 KB | None | 0 0
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. /**
  6.  * Update WordPress plugin from GitHub Private Repository.
  7.  */
  8. class GhPluginUpdater
  9. {
  10.     private $file;
  11.     private $plugin_data;
  12.     private $basename;
  13.     private $active = false;
  14.     private $github_response;
  15.     private $options;
  16.  
  17.     public function __construct($file, array $options)
  18.     {
  19.         $this->file = $file;
  20.         $this->basename = plugin_basename($this->file);
  21.         $this->options = $options;
  22.     }
  23.  
  24.     /**
  25.      * Init GitHub Plugin Updater.
  26.      */
  27.     public function init(): void
  28.     {
  29.         add_filter('pre_set_site_transient_update_plugins', [$this, 'modify_transient'], 10, 1);
  30.         add_filter('http_request_args', [$this, 'set_header_token'], 10, 2);
  31.         add_filter('plugins_api', [$this, 'plugin_popup'], 10, 3);
  32.         add_filter('upgrader_post_install', [$this, 'after_install'], 10, 3);
  33.     }
  34.  
  35.     /**
  36.      * If new version exists, update transient with GitHub info.
  37.      *
  38.      * @param object $transient Transient object with plugins information.
  39.      */
  40.     public function modify_transient(object $transient): object
  41.     {
  42.         if (!property_exists($transient, 'checked')) {
  43.             return $transient;
  44.         }
  45.  
  46.         $this->get_repository_info();
  47.         $this->get_plugin_data();
  48.  
  49.         // Check if tag_name is null
  50.         if ($this->github_response['tag_name'] === null) {
  51.             return $transient;
  52.         }
  53.  
  54.         if (version_compare($this->github_response['tag_name'], $transient->checked[$this->basename], 'gt')) {
  55.             $plugin = [
  56.                 'url' => $this->plugin_data['PluginURI'],
  57.                 'slug' => current(explode('/', $this->basename)),
  58.                 'package' => $this->github_response['zipball_url'],
  59.                 'new_version' => $this->github_response['tag_name'],
  60.             ];
  61.  
  62.             $transient->response[$this->basename] = (object)$plugin;
  63.         }
  64.  
  65.         return $transient;
  66.     }
  67.  
  68.     /**
  69.      * Complete details of new plugin version on popup.
  70.      *
  71.      * @param array|false|object $result The result object or array. Default false.
  72.      * @param string             $action The type of information being requested from the Plugin Installation API.
  73.      * @param object             $args   Plugin API arguments.
  74.      */
  75.     public function plugin_popup(bool $result, string $action, object $args)
  76.     {
  77.         if ('plugin_information' !== $action || empty($args->slug)) {
  78.             return false;
  79.         }
  80.  
  81.         if ($args->slug == current(explode('/', $this->basename))) {
  82.             $this->get_repository_info();
  83.             $this->get_plugin_data();
  84.  
  85.             $plugin = [
  86.                 'name' => $this->plugin_data['Name'],
  87.                 'slug' => $this->basename,
  88.                 'requires' => $this->plugin_data['RequiresWP'],
  89.                 'tested' => $this->plugin_data['TestedUpTo'],
  90.                 'version' => $this->github_response['tag_name'],
  91.                 'author' => $this->plugin_data['AuthorName'],
  92.                 'author_profile' => $this->plugin_data['AuthorURI'],
  93.                 'last_updated' => $this->github_response['published_at'],
  94.                 'homepage' => $this->plugin_data['PluginURI'],
  95.                 'short_description' => $this->plugin_data['Description'],
  96.                 'sections' => [
  97.                     'Description' => $this->plugin_data['Description'],
  98.                     'Updates' => $this->github_response['body'],
  99.                 ],
  100.                 'download_link' => $this->github_response['zipball_url'],
  101.             ];
  102.  
  103.             return (object)$plugin;
  104.         }
  105.  
  106.         return $result;
  107.     }
  108.  
  109.     /**
  110.      * Active plugin after install new version.
  111.      *
  112.      * @param bool  $response   Installation response.
  113.      * @param array $hook_extra Extra arguments passed to hooked filters.
  114.      * @param array $result     Installation result data.
  115.      */
  116.     public function after_install(bool $response, array $hook_extra, array $result): array
  117.     {
  118.         global $wp_filesystem;
  119.  
  120.         $install_directory = plugin_dir_path($this->file);
  121.         $wp_filesystem->move($result['destination'], $install_directory);
  122.         $result['destination'] = $install_directory;
  123.  
  124.         if ($this->active) {
  125.             activate_plugin($this->basename);
  126.         }
  127.  
  128.         return $result;
  129.     }
  130.  
  131.     /**
  132.      * GitHub access_token param was deprecated. We need to set header with token for requests.
  133.      *
  134.      * @param array  $args HTTP request arguments.
  135.      * @param string $url  The request URL.
  136.      */
  137.     public function set_header_token(array $parsed_args, string $url): array
  138.     {
  139.         $parsed_url = parse_url($url);
  140.  
  141.         if ('api.github.com' === ($parsed_url['host'] ?? null) && isset($parsed_url['query'])) {
  142.             parse_str($parsed_url['query'], $query);
  143.  
  144.             if (isset($query['access_token'])) {
  145.                 $parsed_args['headers']['Authorization'] = 'token ' . $query['access_token'];
  146.  
  147.                 $this->active = is_plugin_active($this->basename);
  148.             }
  149.         }
  150.  
  151.         return $parsed_args;
  152.     }
  153.  
  154.     /**
  155.      * Gets repository data from GitHub.
  156.      */
  157.     private function get_repository_info(): void
  158.     {
  159.         if (null !== $this->github_response) {
  160.             return;
  161.         }
  162.  
  163.         $args = [
  164.             'method' => 'GET',
  165.             'timeout' => 5,
  166.             'redirection' => 5,
  167.             'httpversion' => '1.0',
  168.             'headers' => [
  169.                 'Authorization' => 'token ' . $this->options['token'],
  170.             ],
  171.             'sslverify' => true,
  172.         ];
  173.         $request_uri = sprintf('https://api.github.com/repos/%s/%s/releases', $this->options['username'], $this->options['repository']);
  174.  
  175.         $request = wp_remote_get($request_uri, $args);
  176.         $response = json_decode(wp_remote_retrieve_body($request), true);
  177.  
  178.         if (is_array($response)) {
  179.             $response = current($response);
  180.         }
  181.  
  182.         if ($this->options['token']) {
  183.             $response['zipball_url'] = add_query_arg('access_token', $this->options['token'], $response['zipball_url']);
  184.         }
  185.  
  186.         $this->github_response = $response;
  187.     }
  188.  
  189.     /**
  190.      * Gets plugin data.
  191.      */
  192.     private function get_plugin_data(): void
  193.     {
  194.         if (null !== $this->plugin_data) {
  195.             return;
  196.         }
  197.  
  198.         $this->plugin_data = get_plugin_data($this->file);
  199.     }
  200. }
  201. /* Config plugin ----------------------------------------------- */
  202. /*
  203.     if (is_admin()) {
  204.         $updater_options = [
  205.             'username' => 'cicklow',
  206.             'repository' => 'ElPlugin1',
  207.             'token' => '1234'
  208.         ];
  209.  
  210.         $updater_identifier = 'ElPlugin1';
  211.  
  212.         include_once plugin_dir_path(__FILE__) . '/GhPluginUpdater.php';
  213.  
  214.         $updater = new GhPluginUpdater(__FILE__, $updater_options);
  215.         $updater->init();
  216.     }
  217. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement