/**
  * 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);
 }
Esempio n. 2
0
 /**
  * Stores some bootstrap-handy information into a persistent file.
  *
  * Information is stored in `TMP/snapshot.php` file, it contains
  * useful information such as enabled languages, content types slugs, installed
  * plugins, etc.
  *
  * You can read this information using `Configure::read()` as follow:
  *
  * ```php
  * Configure::read('QuickApps.<option>');
  * ```
  *
  * Or using the `quickapps()` global function:
  *
  * ```php
  * quickapps('<option>');
  * ```
  *
  * @return void
  */
 function snapshot()
 {
     if (Cache::config('default')) {
         Cache::clear(false, 'default');
     }
     if (Cache::config('_cake_core_')) {
         Cache::clear(false, '_cake_core_');
     }
     if (Cache::config('_cake_model_')) {
         Cache::clear(false, '_cake_model_');
     }
     $versionPath = QUICKAPPS_CORE . 'VERSION.txt';
     $snapshot = ['version' => null, 'content_types' => [], 'plugins' => [], 'options' => [], 'languages' => [], 'aspects' => []];
     if (is_readable($versionPath)) {
         $versionFile = file($versionPath);
         $snapshot['version'] = trim(array_pop($versionFile));
     } else {
         die(sprintf('Missing file: %s', $versionPath));
     }
     if (ConnectionManager::config('default')) {
         if (!TableRegistry::exists('SnapshotPlugins')) {
             $PluginTable = TableRegistry::get('SnapshotPlugins', ['table' => 'plugins']);
         } else {
             $PluginTable = TableRegistry::get('SnapshotPlugins');
         }
         if (!TableRegistry::exists('SnapshotContentTypes')) {
             $ContentTypesTable = TableRegistry::get('SnapshotContentTypes', ['table' => 'content_types']);
         } else {
             $ContentTypesTable = TableRegistry::get('SnapshotContentTypes');
         }
         if (!TableRegistry::exists('SnapshotLanguages')) {
             $LanguagesTable = TableRegistry::get('SnapshotLanguages', ['table' => 'languages']);
         } else {
             $LanguagesTable = TableRegistry::get('SnapshotLanguages');
         }
         if (!TableRegistry::exists('SnapshotOptions')) {
             $OptionsTable = TableRegistry::get('SnapshotOptions', ['table' => 'options']);
         } else {
             $OptionsTable = TableRegistry::get('SnapshotOptions');
         }
         $PluginTable->schema(['value' => 'serialized']);
         $OptionsTable->schema(['value' => 'serialized']);
         $plugins = $PluginTable->find()->select(['name', 'package', 'status'])->order(['ordering' => 'ASC', 'name' => 'ASC'])->all();
         $contentTypes = $ContentTypesTable->find()->select(['slug'])->all();
         $languages = $LanguagesTable->find()->where(['status' => 1])->order(['ordering' => 'ASC'])->all();
         $options = $OptionsTable->find()->select(['name', 'value'])->where(['autoload' => 1])->all();
         foreach ($contentTypes as $contentType) {
             $snapshot['content_types'][] = $contentType->slug;
         }
         foreach ($options as $option) {
             $snapshot['options'][$option->name] = $option->value;
         }
         foreach ($languages as $language) {
             list($languageCode, $countryCode) = localeSplit($language->code);
             $snapshot['languages'][$language->code] = ['name' => $language->name, 'locale' => $language->code, 'code' => $languageCode, 'country' => $countryCode, 'direction' => $language->direction, 'icon' => $language->icon];
         }
     } else {
         $plugins = [];
         foreach (Plugin::scan() as $plugin => $path) {
             $plugins[] = new Entity(['name' => $plugin, 'status' => true, 'package' => 'quickapps-plugins']);
         }
     }
     $folder = new Folder(QUICKAPPS_CORE . 'src/Aspect/');
     foreach ($folder->read(false, false, true)[1] as $classFile) {
         $className = basename(preg_replace('/\\.php$/', '', $classFile));
         if (!in_array($className, ['AppAspect', 'Aspect'])) {
             $snapshot['aspects'][] = "CMS\\Aspect\\{$className}";
         }
     }
     foreach ($plugins as $plugin) {
         $pluginPath = false;
         if (isset(Plugin::scan()[$plugin->name])) {
             $pluginPath = Plugin::scan()[$plugin->name];
         }
         if ($pluginPath === false) {
             Debugger::log(sprintf('Plugin "%s" was found in DB but QuickAppsCMS was unable to locate its root directory.', $plugin->name));
             continue;
         }
         if (!Plugin::validateJson("{$pluginPath}/composer.json")) {
             Debugger::log(sprintf('Plugin "%s" has a corrupt "composer.json" file (%s).', $plugin->name, "{$pluginPath}/composer.json"));
             continue;
         }
         $aspectsPath = "{$pluginPath}/src/Aspect/";
         $eventsPath = "{$pluginPath}/src/Event/";
         $fieldsPath = "{$pluginPath}/src/Field/";
         $helpFiles = glob($pluginPath . '/src/Template/Element/Help/help*.ctp');
         $isTheme = str_ends_with($plugin->name, 'Theme');
         $status = (bool) $plugin->status;
         $humanName = '';
         $aspects = [];
         $eventListeners = [];
         $fields = [];
         $subspaces = [$aspectsPath => 'Aspect', $eventsPath => 'Event', $fieldsPath => 'Field'];
         $varnames = [$aspectsPath => 'aspects', $eventsPath => 'eventListeners', $fieldsPath => 'fields'];
         foreach ([$aspectsPath, $eventsPath, $fieldsPath] as $path) {
             if (is_dir($path)) {
                 $Folder = new Folder($path);
                 foreach ($Folder->read(false, false, true)[1] as $classFile) {
                     $className = basename(preg_replace('/\\.php$/', '', $classFile));
                     $subspace = $subspaces[$path];
                     $varname = $varnames[$path];
                     $namespace = "{$plugin->name}\\{$subspace}\\";
                     ${$varname}[] = $namespace . $className;
                 }
             }
         }
         if (is_readable("{$pluginPath}composer.json")) {
             $json = (array) json_decode(file_get_contents("{$pluginPath}composer.json"), true);
             if (!empty($json['extra']['human-name'])) {
                 $humanName = $json['extra']['human-name'];
             }
         }
         if (empty($humanName)) {
             $humanName = (string) Inflector::humanize((string) Inflector::underscore($plugin->name));
             if ($isTheme) {
                 $humanName = trim(str_replace_last('Theme', '', $humanName));
             }
         }
         $snapshot['plugins'][$plugin->name] = ['name' => $plugin->name, 'humanName' => $humanName, 'package' => $plugin->package, 'isTheme' => $isTheme, 'hasHelp' => !empty($helpFiles), 'hasSettings' => is_readable($pluginPath . '/src/Template/Element/settings.ctp'), 'aspects' => $aspects, 'eventListeners' => $eventListeners, 'fields' => $fields, 'status' => $status, 'path' => $pluginPath];
         if ($status) {
             $snapshot['aspects'] = array_merge($snapshot['aspects'], $aspects);
         }
     }
     Configure::write('QuickApps', $snapshot);
     if (!Configure::dump('snapshot', 'QuickApps', ['QuickApps'])) {
         die('QuickAppsCMS was unable to create a snapshot file, check that PHP have permission to write to the "/tmp" directory.');
     }
 }