Viewing File: /usr/local/cpanel/3rdparty/wpinstaller/src/WpInstaller/Installer.php

<?php
namespace WpInstaller;

class Installer {
    const LOCAL_CACHE_DIR = '/usr/local/cpanel/3rdparty/wpinstaller/files/';
    const PLUGINS_CACHE   = self::LOCAL_CACHE_DIR . 'plugins/';
    const CORE_CACHE      = self::LOCAL_CACHE_DIR . 'core/wordpress/';

    const PLUGINS_DIR          = 'wp-content/plugins/';
    const MU_PLUGINS_DIR       = 'wp-content/mu-plugins/';
    const CONFIG_TEMPLATE_FILE = 'wp-config-sample.php';
    const CONFIG_FILE          = 'wp-config.php';

    private $action_logger;
    private $finished_install;
    private $error;
    private $database;
    private $filemanager;
    private $site_info;

    private $caught_exception;

    function __construct() {
        $this->finished_install = false;
        $this->action_logger = new \Common\ActionLogger();
        $this->site;
    }

    function __invoke() {

        try {
            $this->run();
            $this->action_logger->action_end();
        }
        catch (\Exception $e) {
            $this->action_logger->action_end(false, $e);
            $this->caught_exception = true;
            $this->rollback();
            return [
                'trace'   => $this->action_logger->actions(),
                'success' => false,
            ];
        }

        return [
            'dbhost'          => $this->database->host,
            'dbname'          => $this->database->database_name,
            'dbuser'          => $this->database->user_name,
            'dbpass'          => $this->database->password,
            'db_table_prefix' => $this->database->table_prefix,
            'admin_pass'      => $this->site_info['admin_password'],
            'admin_user'      => $this->site_info['admin_user'],
            'admin_email'     => $this->site_info['admin_email'],
            'site_url'        => $this->site_info['site_url'],
            'path'            => $this->site_info['path'],
            'title'           => $this->site_info['title'],
            'trace'           => $this->action_logger->actions(),
            'success'         => true,
        ];
    }

    function run() {
        // Get parameters
        $this->action_logger->action_start('arg_parse');
        $args = Parameter::get();

        $username = $args['cpanel_user'];
        $path = $args['install_path'];

        $this->filemanager = new FileManager();

        // Check to see if WordPress is already installed at this location
        $this->action_logger->action_start('core_not_already_installed_check');
        $this->core = new Core(self::CONFIG_FILE);
        if ($this->core->is_installed()) {
            throw new \Exception('WordPress appears to already be installed');
        }

        // Perform database provisioning
        $this->action_logger->action_start('database_provision');
        $cpanel_api = new CpanelApi();
        $this->database = new Database($username, $cpanel_api);
        $this->database->provision();

        // If the core files are non-existent, go ahead and try to download them
        if (!file_exists(self::CORE_CACHE)) {
            $this->action_logger->action_start('core_files_fetch');
            \WpDownloader\Log::logErrors();
            \WpDownloader\Log::setLogToEcho(false);
            $update = new \WpDownloader\Update();
            $update->prepareNewVersion();
        }

        // Copy core files
        $this->action_logger->action_start('core_files_add');
        $this->filemanager->copy_dir(self::CORE_CACHE, getcwd(), true);

        // Generate the configuration file
        $this->action_logger->action_start('core_config_generate');
        $this->filemanager->copy_file(self::CONFIG_TEMPLATE_FILE, self::CONFIG_FILE);
        $constant_values = [
            'DB_NAME'              => $this->database->database_name,
            'DB_USER'              => $this->database->user_name,
            'DB_PASSWORD'          => $this->database->password,
            'DB_HOST'              => $this->database->host,
            'AUTH_KEY'             => $this->gen_key(),
            'SECURE_AUTH_KEY'      => $this->gen_key(),
            'LOGGED_IN_KEY'        => $this->gen_key(),
            'NONCE_KEY'            => $this->gen_key(),
            'AUTH_SALT'            => $this->gen_key(),
            'SECURE_AUTH_SALT'     => $this->gen_key(),
            'LOGGED_IN_SALT'       => $this->gen_key(),
            'NONCE_SALT'           => $this->gen_key(),
            'WP_CRON_LOCK_TIMEOUT' => 120,
            'AUTOSAVE_INTERVAL'    => 300,
            'WP_POST_REVISIONS'    => 20,
            'EMPTY_TRASH_DAYS'     => 7,
            'WP_AUTO_UPDATE_CORE'  => true,
        ];

        $config_transform_function = Core::conf_transform_function(
            $constant_values,
            $this->database->table_prefix
        );

        $this->filemanager->transform_file(self::CONFIG_FILE, $config_transform_function);

        // Perform core install
        $this->action_logger->action_start('core_install');
        $install_resp = $this->core->perform_install(
            $args['site_title'],
            $args['admin_user'],
            $args['admin_pass'],
            $args['admin_user_email']
        );

        // Set core options
        $this->action_logger->action_start('core_options_set');
        $core_options = array_merge(
            $args['options'],
            [ 'admin_email' => $args['admin_user_email']]
        );
        $this->core->set_options($core_options);

        // Save values for the install response
        $this->site_info = [
            'admin_user'     => $install_resp['admin_user'],
            'admin_password' => $install_resp['admin_password'],
            'admin_email'    => $args['admin_user_email'],
            'site_url'       => $args['options']['siteurl'],
            'path'           => $path,
            'title'          => $args['site_title'],
        ];

        // Create .htaccess file (NOTE: doesn't work in docker env)
        $this->action_logger->action_start('htaccess_create');
        $this->core->create_htaccess();

        // Plugin operations -- TODO factor out ... someday.
        $plugins = $args['plugins'];
        foreach ($plugins as $plugin => $plugin_info) {
            // Copy plugin files
            $this->action_logger->action_start("plugin_{$plugin}_install");

            // expecting one or the other of these to exist
            $plugins_cache_dir = self::PLUGINS_CACHE . $plugin;
            $plugin_cache_filename = "$plugins_cache_dir.php";

            $this->filemanager->mkdir(self::MU_PLUGINS_DIR);
            $dest_plugins_folder = @$plugin_info['must_use']
                ? self::MU_PLUGINS_DIR
                : self::PLUGINS_DIR;

            if (is_dir($plugins_cache_dir)) {
                $this->filemanager->copy_dir($plugins_cache_dir, $dest_plugins_folder . $plugin);
            }
            else if (file_exists($plugin_cache_filename)) {
                $this->filemanager->copy_file(
                    $plugin_cache_filename,
                    $dest_plugins_folder . "$plugin.php"
                );
            }
            else {
                // could someday auto-download it if we can find it?
                throw new \Exception("Failed to find plugin: $plugin in local cache.");
            }
            // Set options on each plugin that has them
            if (array_key_exists('options', $plugin_info) && count($plugin_info['options']) > 0) {
                $this->action_logger->action_start("plugin_{$plugin}_options_set");
                $this->core->set_options($plugin_info['options']);
            }

            // Activate each plugin
            if (!@$plugin_info['must_use']) {
                $this->action_logger->action_start("plugin_{$plugin}_activate");
                $this->core->activate_plugin($plugin);
            }
        }

        // Mark successful completion of the install
        $this->finished_install = true;
    }

    function __destruct() {
        // $this->finished_install is a sentinel to help us fail hard when a call to exit()
        // during the install would have otherwise caused us to report success (zero exit)
        // erroneously. Also allows us to use our rollback, and still throw any original error.
        if (!$this->finished_install && !$this->caught_exception) {
            $this->rollback();
            throw new \Exception('exit() was called sometime during the installation.');
        }
    }

    private function rollback() {
        if ( !empty($this->database) ) {
            $this->database->rollback();
        }

        if ( !empty($this->filemanager) ) {
            $this->filemanager->rollback();
        }
    }

    private function gen_key() {
        return bin2hex(openssl_random_pseudo_bytes(32));
    }
}
?>
Back to Directory File Manager