/** * Constructor. * * @param string $package Package name as string. e.g. `vendor-name/package-name` * @param string $path Full path to package's root directory * @param string $version Package version number */ public function __construct($package, $path, $version = null) { $this->_packageName = $package; list($this->_vendor, $this->_name) = packageSplit($this->_packageName); $this->_version = $version; $this->_path = $path; if (strtolower($this->_packageName) === 'cakephp/cakephp') { $this->_version = Configure::version(); } elseif (strtolower($this->_packageName) === 'quickapps/cms') { $this->_version = quickapps('version'); } }
/** * Checks if there is any active plugin that depends of $plugin. * * @param string|CMS\Package\PluginPackage $plugin Plugin name, package * name (as `vendor/package`) or plugin package object result of * `static::get()` * @return array A list of all plugin names that depends on $plugin, an empty * array means that no other plugins depends on $pluginName, so $plugin can be * safely deleted or turned off. * @throws \Cake\Error\FatalErrorException When requested plugin was not found * @see \CMS\Core\Plugin::get() */ public static function checkReverseDependency($plugin) { if (!$plugin instanceof PluginPackage) { list(, $pluginName) = packageSplit($plugin, true); $plugin = static::get($pluginName); } return $plugin->requiredBy()->toArray(); }
/** * Validates the content of working directory. * * @return bool True on success */ protected function _validateContent() { if (!$this->_workingDir) { return false; } $errors = []; if (!is_readable("{$this->_workingDir}src") || !is_dir("{$this->_workingDir}src")) { $errors[] = __d('installer', 'Invalid package, missing "src" directory.'); } if (!is_readable("{$this->_workingDir}composer.json")) { $errors[] = __d('installer', 'Invalid package, missing "composer.json" file.'); } else { $jsonErrors = Plugin::validateJson("{$this->_workingDir}composer.json", true); if (!empty($jsonErrors)) { $errors[] = __d('installer', 'Invalid "composer.json".'); $errors = array_merge($errors, (array) $jsonErrors); } else { $json = (new File("{$this->_workingDir}composer.json"))->read(); $json = json_decode($json, true); list(, $pluginName) = packageSplit($json['name'], true); if ($this->params['theme'] && !str_ends_with($pluginName, 'Theme')) { $this->err(__d('installer', 'The given package is not a valid theme.')); return false; } elseif (!$this->params['theme'] && str_ends_with($pluginName, 'Theme')) { $this->err(__d('installer', 'The given package is not a valid plugin.')); return false; } $this->_plugin = ['name' => $pluginName, 'packageName' => $json['name'], 'type' => str_ends_with($pluginName, 'Theme') ? 'theme' : 'plugin', 'composer' => $json]; if (Plugin::exists($this->_plugin['name'])) { $exists = plugin($this->_plugin['name']); if ($exists->status) { $errors[] = __d('installer', '{0} "{1}" is already installed.', [$this->_plugin['type'] == 'plugin' ? __d('installer', 'The plugin') : __d('installer', 'The theme'), $this->_plugin['name']]); } else { $errors[] = __d('installer', '{0} "{1}" is already installed but disabled, maybe you want try to enable it?.', [$this->_plugin['type'] == 'plugin' ? __d('installer', 'The plugin') : __d('installer', 'The theme'), $this->_plugin['name']]); } } if ($this->_plugin['type'] == 'theme' && !is_readable("{$this->_workingDir}webroot/screenshot.png")) { $errors[] = __d('installer', 'Missing "screenshot.png" file.'); } if (isset($json['require'])) { $checker = new RuleChecker($json['require']); if (!$checker->check()) { $errors[] = __d('installer', '{0} "{1}" depends on other packages, plugins or libraries that were not found: {2}', [$this->_plugin['type'] == 'plugin' ? __d('installer', 'The plugin') : __d('installer', 'The theme'), $this->_plugin['name'], $checker->fail(true)]); } } } } if (!file_exists(ROOT . '/plugins') || !is_dir(ROOT . '/plugins') || !is_writable(ROOT . '/plugins')) { $errors[] = __d('installer', 'Write permissions required for directory: {0}.', [ROOT . '/plugins/']); } foreach ($errors as $message) { $this->err($message); } return empty($errors); }
/** * Tries to get package that represents a third party library. * * - Package must exists on `VENDOR_PATH/vendor-name/package-name/`. * - Its composer.json file must exists as well. * - Package must be registered on Composer's "installed.json" file. * * @param string $package Full package name * @return bool|\CMS\Core\Package\ThirdPartyPackage */ protected static function _getThirdParty($package) { list($vendor, $packageName) = packageSplit($package); $packageJson = normalizePath(VENDOR_INCLUDE_PATH . "/{$vendor}/{$packageName}/composer.json"); if (is_readable($packageJson)) { $installedJson = normalizePath(VENDOR_INCLUDE_PATH . "composer/installed.json"); if (is_readable($installedJson)) { $json = (array) json_decode(file_get_contents($installedJson), true); foreach ($json as $pkg) { if (strtolower($pkg['name']) === strtolower($package)) { return new ThirdPartyPackage($package, dirname($packageJson), $pkg['version']); } } } } return false; }
/** * Gets a collection list of plugin that depends on this plugin. * * @return \Cake\Collection\Collection List of plugins */ public function requiredBy() { if ($cache = $this->config('required_by')) { return collection($cache); } Plugin::dropCache(); $out = []; $plugins = Plugin::get()->filter(function ($v, $k) { return $v->name() !== $this->name(); }); foreach ($plugins as $plugin) { if ($dependencies = $plugin->dependencies($plugin->name)) { $packages = array_map(function ($item) { list(, $package) = packageSplit($item, true); return strtolower($package); }, array_keys($dependencies)); if (in_array(strtolower($this->name()), $packages)) { $out[] = $plugin; } } } $this->config('required_by', $out); return collection($out); }