balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

Plugin.php (10246B)


      1 <?php
      2 // phpcs:ignoreFile
      3 // This class was copied from JetPack (mostly)
      4 // so will be a bit of work to refactor
      5 /**
      6  * Manage plugin dependencies
      7  */
      8 
      9 namespace Extendify\ExtendifySdk;
     10 
     11 class Plugin
     12 {
     13     /**
     14      * Install and activate a plugin.
     15      *
     16      * @param string $slug Plugin slug.
     17      *
     18      * @return bool|WP_Error True if installation succeeded, error object otherwise.
     19      */
     20     public static function install_and_activate_plugin($slug)
     21     {
     22         $plugin_id = self::get_plugin_id_by_slug($slug);
     23         if (! $plugin_id) {
     24             $installed = self::install_plugin($slug);
     25             if (is_wp_error($installed)) {
     26                 return $installed;
     27             }
     28             $plugin_id = self::get_plugin_id_by_slug($slug);
     29         } elseif (is_plugin_active($plugin_id)) {
     30             return true; // Already installed and active.
     31         }
     32 
     33         if (! current_user_can('activate_plugins')) {
     34             return new \WP_Error('not_allowed', __('You are not allowed to activate plugins on this site.', 'templates_sdk'));
     35         }
     36 
     37         $activated = \activate_plugin($plugin_id);
     38         if (\is_wp_error($activated)) {
     39             return $activated;
     40         }
     41 
     42         return true;
     43     }
     44 
     45     /**
     46      * Install a plugin.
     47      *
     48      * @param string $slug Plugin slug.
     49      *
     50      * @return bool|WP_Error True if installation succeeded, error object otherwise.
     51      */
     52     public static function install_plugin($slug)
     53     {
     54         if (\is_multisite() && !\current_user_can('manage_network')) {
     55             return new \WP_Error('not_allowed', __('You are not allowed to install plugins on this site.', 'templates_sdk'));
     56         }
     57         require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
     58         require_once ABSPATH . 'wp-admin/includes/plugin.php';
     59         require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
     60         require_once ABSPATH . 'wp-admin/includes/file.php';
     61         require_once ABSPATH . 'wp-admin/includes/misc.php';
     62         $installer = new \Plugin_Upgrader(new Skin());
     63         $zip_url  = self::generate_wordpress_org_plugin_download_link($slug);
     64 
     65         $result = $installer->install($zip_url);
     66 
     67         if (is_wp_error($result)) {
     68             return $result;
     69         }
     70 
     71         $plugin     = self::get_plugin_id_by_slug($slug);
     72         $error_code = 'install_error';
     73         if (! $plugin) {
     74             $error = __('There was an error installing your plugin', 'templates_sdk');
     75         }
     76 
     77         if (! $result) {
     78             $error_code = $installer->skin->get_main_error_code();
     79             $message    = $installer->skin->get_main_error_message();
     80             $error      = $message ? $message : __('An unknown error occurred during installation', 'templates_sdk');
     81         }
     82 
     83         if (! empty($error)) {
     84             return new \WP_Error($error_code, $error, 400);
     85         }
     86 
     87         return (array) $installer->skin->get_upgrade_messages();
     88     }
     89 
     90     /**
     91      * Get WordPress.org zip download link from a plugin slug
     92      *
     93      * @param string $plugin_slug Plugin slug.
     94      */
     95     protected static function generate_wordpress_org_plugin_download_link($plugin_slug)
     96     {
     97         return "https://downloads.wordpress.org/plugin/$plugin_slug.latest-stable.zip";
     98     }
     99 
    100     /**
    101      * Get the plugin ID (composed of the plugin slug and the name of the main plugin file) from a plugin slug.
    102      *
    103      * @param string $slug Plugin slug.
    104      */
    105     public static function get_plugin_id_by_slug($slug)
    106     {
    107         // Check if get_plugins() function exists. This is required on the front end of the
    108         // site, since it is in a file that is normally only loaded in the admin.
    109         if (! function_exists('get_plugins')) {
    110             require_once ABSPATH . 'wp-admin/includes/plugin.php';
    111         }
    112 
    113         /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
    114         $plugins = apply_filters('all_plugins', get_plugins());
    115         if (! is_array($plugins)) {
    116             return false;
    117         }
    118 
    119         foreach ($plugins as $plugin_file => $plugin_data) {
    120             if (self::get_slug_from_file_path($plugin_file) === $slug) {
    121                 return $plugin_file;
    122             }
    123         }
    124 
    125         return false;
    126     }
    127 
    128     /**
    129      * Get the plugin slug from the plugin ID (composed of the plugin slug and the name of the main plugin file)
    130      *
    131      * @param string $plugin_file Plugin file (ID -- e.g. hello-dolly/hello.php).
    132      */
    133     protected static function get_slug_from_file_path($plugin_file)
    134     {
    135         // Similar to get_plugin_slug() method.
    136         $slug = dirname($plugin_file);
    137         if ('.' === $slug) {
    138             $slug = preg_replace('/(.+)\.php$/', '$1', $plugin_file);
    139         }
    140 
    141         return $slug;
    142     }
    143 
    144     /**
    145      * Get the activation status for a plugin.
    146      *
    147      * @since 8.9.0
    148      *
    149      * @param string $plugin_file The plugin file to check.
    150      * @return string Either 'network-active', 'active' or 'inactive'.
    151      */
    152     public static function get_plugin_status($plugin_file)
    153     {
    154         if (is_plugin_active_for_network($plugin_file)) {
    155             return 'network-active';
    156         }
    157 
    158         if (is_plugin_active($plugin_file)) {
    159             return 'active';
    160         }
    161 
    162         return 'inactive';
    163     }
    164 
    165     /**
    166      * Returns a list of all plugins in the site.
    167      *
    168      * @since 8.9.0
    169      * @uses get_plugins()
    170      *
    171      * @return array
    172      */
    173     public static function get_plugins()
    174     {
    175         if (! function_exists('get_plugins')) {
    176             require_once ABSPATH . 'wp-admin/includes/plugin.php';
    177         }
    178         /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
    179         $plugins = apply_filters('all_plugins', get_plugins());
    180 
    181         if (is_array($plugins) && ! empty($plugins)) {
    182             foreach ($plugins as $plugin_slug => $plugin_data) {
    183                 $plugins[ $plugin_slug ]['active'] = in_array(
    184                     self::get_plugin_status($plugin_slug),
    185                     array( 'active', 'network-active' ),
    186                     true
    187                 );
    188             }
    189             return $plugins;
    190         }
    191 
    192         return array();
    193     }
    194 
    195     /**
    196      * Will return info about a plugin
    197      *
    198      * @param string $identifier The key of the plugin info.
    199      * @param string $plugin_id The plugin identifier string 'editorplus-sdk.
    200      * @return string
    201      */
    202     public static function getPluginInfo($identifier, $plugin_id)
    203     {
    204         if (!function_exists('get_plugins')) {
    205             include_once ABSPATH . 'wp-admin/includes/plugin.php';
    206         }
    207 
    208         foreach (get_plugins() as $plugin => $data) {
    209             if ($data[$identifier] === $plugin_id) {
    210                 return $plugin;
    211             }
    212         }
    213 
    214         return false;
    215     }
    216 }
    217 
    218 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    219 require_once ABSPATH . 'wp-admin/includes/file.php';
    220 
    221 /**
    222  * Allows us to capture that the site doesn't have proper file system access.
    223  * In order to update the plugin.
    224  */
    225 class Skin extends \Automatic_Upgrader_Skin
    226 {
    227     /**
    228      * Stores the last error key;
    229      **/
    230     protected $main_error_code = 'install_error';
    231 
    232     /**
    233      * Stores the last error message.
    234      **/
    235     protected $main_error_message = 'An unknown error occurred during installation';
    236 
    237     /**
    238      * Overwrites the set_upgrader to be able to tell if we e ven have the ability to write to the files.
    239      *
    240      * @param WP_Upgrader $upgrader
    241      *
    242      */
    243     public function set_upgrader(&$upgrader)
    244     {
    245         parent::set_upgrader($upgrader);
    246 
    247         // Check if we even have permission to.
    248         $result = $upgrader->fs_connect(array( WP_CONTENT_DIR, WP_PLUGIN_DIR ));
    249         if (! $result) {
    250             // set the string here since they are not available just yet
    251             $upgrader->generic_strings();
    252             $this->feedback('fs_unavailable');
    253         }
    254     }
    255 
    256     /**
    257      * Overwrites the error function
    258      */
    259     public function error($error)
    260     {
    261         if (is_wp_error($error)) {
    262             $this->feedback($error);
    263         }
    264     }
    265 
    266     private function set_main_error_code($code)
    267     {
    268         // Don't set the process_failed as code since it is not that helpful unless we don't have one already set.
    269         $this->main_error_code = ($code === 'process_failed' && $this->main_error_code ? $this->main_error_code : $code);
    270     }
    271 
    272     private function set_main_error_message($message, $code)
    273     {
    274         // Don't set the process_failed as message since it is not that helpful unless we don't have one already set.
    275         $this->main_error_message = ($code === 'process_failed' && $this->main_error_code ? $this->main_error_code : $message);
    276     }
    277 
    278     public function get_main_error_code()
    279     {
    280         return $this->main_error_code;
    281     }
    282 
    283     public function get_main_error_message()
    284     {
    285         return $this->main_error_message;
    286     }
    287 
    288     /**
    289      * Overwrites the feedback function
    290      *
    291      * @param string|array|WP_Error $data    Data.
    292      * @param mixed                 ...$args Optional text replacements.
    293      */
    294     public function feedback($data, ...$args)
    295     {
    296         $current_error = null;
    297         if (is_wp_error($data)) {
    298             $this->set_main_error_code($data->get_error_code());
    299             $string = $data->get_error_message();
    300         } elseif (is_array($data)) {
    301             return;
    302         } else {
    303             $string = $data;
    304         }
    305 
    306         if (! empty($this->upgrader->strings[$string])) {
    307             $this->set_main_error_code($string);
    308 
    309             $current_error = $string;
    310             $string        = $this->upgrader->strings[$string];
    311         }
    312 
    313         if (strpos($string, '%') !== false) {
    314             if (! empty($args)) {
    315                 $string = vsprintf($string, $args);
    316             }
    317         }
    318 
    319         $string = trim($string);
    320         $string = wp_kses(
    321             $string,
    322             array(
    323             'a'      => array(
    324                 'href' => true
    325             ),
    326             'br'     => true,
    327             'em'     => true,
    328             'strong' => true,
    329         )
    330         );
    331 
    332         $this->set_main_error_message($string, $current_error);
    333         $this->messages[] = $string;
    334     }
    335 }