Skip to content
Code-Schnipsel Gruppen Projekte
Manager.php 15,8 KiB
Newer Older
  • Learn to ignore specific revisions
  • Henning Leutz's avatar
    Henning Leutz committed
    /**
     * This file contains QUI\Ckeditor\Plugins\Manager
     */
    
    Henning Leutz's avatar
    Henning Leutz committed
    use QUI;
    
    use QUI\Exception;
    
    use QUI\System\Log;
    
    use QUI\Utils\Security\Orthos;
    use QUI\Utils\System\File;
    
    
    /**
     * Class Manager
     *
     * @package QUI\Ckeditor\Plugins
     */
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
         * @var string
         */
    
        protected $activePluginDir;
    
    Henning Leutz's avatar
    Henning Leutz committed
    
        /**
         * @var string
         */
    
        protected $installedPluginDir;
    
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
         * @var
         */
    
        protected $dependencies;
    
        /**
    
         * List of plugins which should not be installed
    
         * @var array
         */
        protected $blacklist = array(
    
            "copyformatting",
            "crossreference",
    
            "footnotes",
            "textselection"
    
        /**
         * Manager constructor.
         */
    
        public function __construct()
        {
    
    Henning Leutz's avatar
    Henning Leutz committed
            $Package = QUI::getPackage("quiqqer/ckeditor4");
    
    Henning Leutz's avatar
    Henning Leutz committed
            $this->activePluginDir    = $Package->getVarDir()."/plugins/bin";
            $this->installedPluginDir = $Package->getVarDir()."/plugins/installed";
    
    
            if (!is_dir($this->activePluginDir)) {
                mkdir($this->activePluginDir, 0755, true);
            }
    
            if (!is_dir($this->installedPluginDir)) {
                mkdir($this->installedPluginDir, 0755, true);
            }
        }
    
    
        #########################################
        #             Installation              #
        #########################################
    
    
         * Updates the plugins
    
        public function updatePlugins()
    
            $srcDirs = array(
    
    Henning Leutz's avatar
    Henning Leutz committed
                OPT_DIR."ckeditor/ckeditor/plugins",
                OPT_DIR."quiqqer/ckeditor4/plugins/quiqqer",
                OPT_DIR."quiqqer/ckeditor4/plugins/ckeditor4"
    
            foreach ($srcDirs as $srcDir) {
                if (!is_dir($srcDir)) {
                    return;
                }
    
                foreach (scandir($srcDir) as $entry) {
                    if ($entry == "." || $entry == "..") {
                        continue;
                    }
    
    Henning Leutz's avatar
    Henning Leutz committed
                    if (!is_dir($srcDir."/".$entry)) {
    
                    $pluginName = $entry;
                    // Special case, because gitlab gets confused with the dirctory named "codeTag"
                    if ($entry == "code") {
    
    Henning Leutz's avatar
    Henning Leutz committed
                        $pluginName = "codeTag";
    
    Henning Leutz's avatar
    Henning Leutz committed
    
    
                    # Check if/where the plugin is installed
    
    Henning Leutz's avatar
    Henning Leutz committed
                    $targetDir = $this->installedPluginDir."/".$pluginName;
    
                    if (is_dir($this->activePluginDir."/".$pluginName)) {
                        $targetDir = $this->activePluginDir."/".$pluginName;
    
                    if (is_dir($targetDir)) {
                        File::deleteDir($targetDir);
                    }
    
                    File::dircopy(
    
    Henning Leutz's avatar
    Henning Leutz committed
                        $srcDir."/".$entry,
    
         * Installs the plugins from the source packages quiqqer/ckeditor4 and ckeditor4/ckeditor4
    
        public function installPluginsFromSource()
    
            $srcDirs = array(
    
    Henning Leutz's avatar
    Henning Leutz committed
                OPT_DIR."ckeditor/ckeditor/plugins",
                OPT_DIR."quiqqer/ckeditor4/plugins/quiqqer",
                OPT_DIR."quiqqer/ckeditor4/plugins/ckeditor4"
    
    Henning Leutz's avatar
    Henning Leutz committed
            $defaultStateFile = dirname(dirname(dirname(dirname(dirname(__FILE__)))))."/plugins/activePlugins.json";
    
    
            if (file_exists($defaultStateFile)) {
                $json          = file_get_contents($defaultStateFile);
                $activePlugins = json_decode($json, true);
            }
    
    
            foreach ($srcDirs as $srcDir) {
                if (!is_dir($srcDir)) {
                    return;
                }
    
                foreach (scandir($srcDir) as $entry) {
    
    Henning Leutz's avatar
    Henning Leutz committed
    
    
                    // Special case, because gitlab gets confused with the directory named "codeTag"
    
    Henning Leutz's avatar
    Henning Leutz committed
                        $pluginName = "codeTag";
    
    Henning Leutz's avatar
    Henning Leutz committed
    
    
                    $targetDir = $this->installedPluginDir;
    
    Henning Leutz's avatar
    Henning Leutz committed
    
    
                    if (in_array($entry, $activePlugins)) {
                        $targetDir = $this->activePluginDir;
                    }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                    if (!is_dir($srcDir."/".$entry)) {
    
                    if (!is_dir($this->activePluginDir."/".$pluginName)) {
    
                        continue;
                    }
    
                    if (in_array($entry, $this->blacklist)) {
                        continue;
                    }
    
    
                    // vorher löschen, da sonst nicht kopiert werden kann
                    QUI::getTemp()->moveToTemp($targetDir."/".$pluginName);
    
    
                    $this->copyDir(
    
    Henning Leutz's avatar
    Henning Leutz committed
                        $srcDir."/".$entry,
                        $targetDir."/".$pluginName
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (file_exists(OPT_DIR."quiqqer/ckeditor4/plugins/dependencies.json")) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                    OPT_DIR."quiqqer/ckeditor4/plugins/dependencies.json",
                    $this->getPluginDir()."/dependencies.json"
    
    
            #File::deleteDir(OPT_DIR . "ckeditor/ckeditor/plugins");
    
         *
         * @return string[] - array of plugin names
         */
        public function getInstalledPlugins()
        {
            $result = array();
    
            $content = scandir($this->installedPluginDir);
    
    Henning Leutz's avatar
    Henning Leutz committed
    
    
            if ($content === false) {
                return array();
            }
    
            foreach ($content as $entry) {
                if ($entry == "." || $entry == "..") {
                    continue;
                }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                $fullpath = $this->installedPluginDir."/".$entry;
    
    
                if (!is_dir($fullpath)) {
                    continue;
                }
    
                $result[] = $entry;
            }
    
            return $result;
    
        /**
         * Installs a plugin zip file from the given path
         *
    
         * @param $pluginpath - path to the plugins zip file
    
         *
         * @throws Exception
         */
        public function installPlugin($pluginpath)
        {
            # Check if file exists
            if (!file_exists($pluginpath)) {
                throw new Exception(array("quiqqer/ckeditor4", "exception.install.file.not.found"));
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            $tmpDir = QUI::getTemp()->createFolder();
    
    
            copy(
                $pluginpath,
    
    Henning Leutz's avatar
    Henning Leutz committed
                $tmpDir."/archive.zip"
    
            );
    
            $Zip = new \ZipArchive();
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            if ($Zip->open($tmpDir."/archive.zip") === false) {
    
                throw new Exception(array("quiqqer/ckeditor4", "exception.install.file.invalid.format"));
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            if ($Zip->extractTo($tmpDir."/content") === false) {
    
                throw new Exception(array("quiqqer/ckeditor4", "exception.install.file.extract.failed"));
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            $contents = scandir($tmpDir."/content");
    
            foreach (array_keys($contents, ".", true) as $key) {
                unset($contents[$key]);
            }
    
            foreach (array_keys($contents, "..", true) as $key) {
                unset($contents[$key]);
            }
    
    
            // Check if the zip contains only one folder
            if (count($contents) !== 1) {
                throw new Exception(array(
                    "quiqqer/ckeditor4",
                    "exception.plugin.install.wrong.format"
                ));
            }
    
    
            // Process the content
            foreach ($contents as $entry) {
    
                if ($entry == "." || $entry == "..") {
                    continue;
                }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                if (is_dir($this->installedPluginDir."/".$entry)) {
    
                    throw new Exception(array("quiqqer/ckeditor4", "exception.install.file.exists"));
                }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                if (is_dir($this->activePluginDir."/".$entry)) {
    
                    throw new Exception(array("quiqqer/ckeditor4", "exception.install.file.exists"));
                }
    
                rename(
    
    Henning Leutz's avatar
    Henning Leutz committed
                    $tmpDir."/content/".$entry,
                    $this->installedPluginDir."/".$entry
    
                );
            }
    
            File::deleteDir($tmpDir);
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            QUI::getMessagesHandler()->addSuccess(
                QUI::getLocale()->get(
    
                    "quiqqer/ckeditor4",
                    "message.plugin.install.success"
                )
            );
        }
    
    
        #########################################
        #             Enable/Disable            #
        #########################################
    
        /**
         * Activates the given plugin name
         *
         * @param $pluginName
         *
         * @throws Exception
         */
        public function activate($pluginName)
        {
            $pluginName = Orthos::clearPath($pluginName);
            $pluginName = str_replace("/", "", $pluginName);
    
    
            if (in_array($pluginName, $this->blacklist)) {
                throw new Exception(array(
                    "quiqqer/ckeditor4",
                    "exception.plugin.activate.blacklisted"
                ));
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (!is_dir($this->installedPluginDir."/".$pluginName)) {
                throw new Exception(array(
                    "quiqqer/ckeditor4",
                    "exception.plugin.activate.plugin.not.found"
                ));
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (is_dir($this->activePluginDir."/".$pluginName)) {
                throw new Exception(array(
                    "quiqqer/ckeditor4",
                    "exception.plugin.already.active"
                ));
    
            }
    
            $deps = $this->getDependencies($pluginName);
    
    Henning Leutz's avatar
    Henning Leutz committed
    
    
            foreach ($deps as $dep) {
                try {
                    $this->activate($dep);
                } catch (\Exception $Exception) {
                }
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            rename(
                $this->installedPluginDir."/".$pluginName,
                $this->activePluginDir."/".$pluginName
            );
    
    Henning Leutz's avatar
    Henning Leutz committed
            QUI\Cache\Manager::clear("quiqqer/ckeditor/plugins/data");
    
        }
    
        /**
         * Deactivates the given plugin name
         *
         * @param $pluginName
         *
         * @throws Exception
         */
        public function deactivate($pluginName)
        {
            $pluginName = Orthos::clearPath($pluginName);
            $pluginName = str_replace("/", "", $pluginName);
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (!is_dir($this->activePluginDir."/".$pluginName)) {
                throw new Exception(array(
                    "quiqqer/ckeditor4",
                    "exception.plugin.activate.plugin.not.active"
                ));
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (is_dir($this->installedPluginDir."/".$pluginName)) {
                File::deleteDir($this->activePluginDir."/".$pluginName);
    
    
                return;
            }
    
            foreach ($this->getDependentPlugins($pluginName) as $depName) {
                try {
                    $this->deactivate($depName);
                } catch (\Exception $Exception) {
                }
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            rename(
                $this->activePluginDir."/".$pluginName,
                $this->installedPluginDir."/".$pluginName
            );
    
    Henning Leutz's avatar
    Henning Leutz committed
            QUI\Cache\Manager::clear("quiqqer/ckeditor/plugins/data");
    
        /**
         * Returns all active plugins
         *
         * @return string[] - Array of active plugin names
         */
        public function getActivePlugins()
        {
    
    Henning Leutz's avatar
    Henning Leutz committed
            $result  = array();
    
            $content = scandir($this->activePluginDir);
    
    Henning Leutz's avatar
    Henning Leutz committed
    
    
            if ($content === false) {
                return array();
            }
    
            foreach ($content as $entry) {
                if ($entry == "." || $entry == "..") {
                    continue;
                }
    
    Henning Leutz's avatar
    Henning Leutz committed
    
                $fullpath = $this->activePluginDir."/".$entry;
    
                if (!is_dir($fullpath)) {
                    continue;
                }
    
                $result[] = $entry;
            }
    
            return $result;
    
        #########################################
        #             Dependencies            #
        #########################################
    
    
         * Gets all dependencies for the given plugin.
         * Including dependencies fo dependencies
         * Returns false on error
    
         * @param $pluginName
         *
         * @return array|false
    
        public function getDependencies($pluginName)
    
            try {
                $this->loadDependencies();
            } catch (\Exception $Exception) {
                return false;
            }
    
            $result = array();
    
            if (!isset($this->dependencies[$pluginName])) {
                return array();
            }
    
            $deps = $this->dependencies[$pluginName];
    
    Henning Leutz's avatar
    Henning Leutz committed
    
    
            foreach ($deps as $dep) {
                $result[] = $dep;
    
                $subDeps = $this->getDependencies($dep);
    
    Henning Leutz's avatar
    Henning Leutz committed
                $result  = array_merge($result, $subDeps);
    
            $result = array_unique($result);
    
            return $result;
        }
    
        /**
         * Returns an array of packages that depend on the given plugin
         * Returns false on error
         *
         * @param $pluginName
         *
         * @return array|bool
         */
        public function getDependentPlugins($pluginName)
        {
            $result = array();
    
            try {
                $this->loadDependencies();
            } catch (\Exception $Exception) {
                return false;
            }
    
            foreach ($this->dependencies as $pkg => $deps) {
                if (in_array($pluginName, $deps)) {
                    $result[] = $pkg;
    
    
            $result = array_unique($result);
    
            return $result;
    
         * Loads the dependencies for the installed modules
         *
         * @throws Exception
    
        protected function loadDependencies()
    
            if (isset($this->dependencies) && !empty($this->dependencies)) {
                return;
            }
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (!file_exists($this->getPluginDir()."/dependencies.json")) {
                Log::addWarning("Missing dependency file: ".$this->getPluginDir()."/dependencies.json");
    
                throw new Exception("missing.dependency.file");
            }
    
    Henning Leutz's avatar
    Henning Leutz committed
            $json = file_get_contents($this->getPluginDir()."/dependencies.json");
    
            $deps = json_decode($json, true);
    
            if (json_last_error() !== JSON_ERROR_NONE) {
                throw new Exception(json_last_error_msg());
            }
    
            $this->dependencies = $deps;
        }
    
        #########################################
        #               Helper                  #
        #########################################
    
        /**
         * Returns a list of all plugins and their details
         * Format:
         * array(
         *  [0] => array(
         *      ["name"] => "pluginname",
         *      ["state"] => 0|1  (1 for active; 0 for inactive)
         *  )
         * )
         *
         * @return array
         */
        public function getAllPlugins()
        {
            $result = array();
    
            foreach ($this->getActivePlugins() as $plugin) {
                $result[] = array(
                    'name'  => $plugin,
                    'state' => 1
                );
            }
    
            foreach ($this->getInstalledPlugins() as $plugin) {
                $result[] = array(
                    'name'  => $plugin,
                    'state' => 0
                );
    
    
            return $result;
    
        /**
         * Returns the plugin dir
         *
         * @return string
         */
        public function getPluginDir()
        {
    
    Henning Leutz's avatar
    Henning Leutz committed
            return QUI::getPackage("quiqqer/ckeditor4")->getVarDir()."/plugins";
    
    
        /**
         * Recursively copies the target directory to the target location
         *
         * @param $src
         * @param $target
         */
        public function copyDir($src, $target)
        {
            if (!is_dir($target)) {
                mkdir($target, 0755);
            }
    
            $entries = scandir($src);
    
            foreach ($entries as $entry) {
                if ($entry == "." || $entry == "..") {
                    continue;
                }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                $fullpath = $src."/".$entry;
    
    Henning Leutz's avatar
    Henning Leutz committed
                    $this->copyDir($fullpath, $target."/".$entry);
    
    Henning Leutz's avatar
    Henning Leutz committed
                copy($fullpath, $target."/".$entry);
    
        public function getPluginUrlPath()
        {
            // Build the web reachable path for the plugin directory
    
    Henning Leutz's avatar
    Henning Leutz committed
            $pluginPath = QUI::getPackage("quiqqer/ckeditor4")->getVarDir()."plugins";
    
            $varParent  = dirname(VAR_DIR);
    
            # Parse the URL directory
            $pluginUrlPath = str_replace($varParent, "", $pluginPath);
    
            return $pluginUrlPath;
        }
    
    Florian Bogner's avatar
    Florian Bogner committed
    }