public static function defaultLocator() { $locator = new self(); $locator->addTestFolder(rex_path::core(self::TESTS_FOLDER)); foreach (rex_package::getAvailablePackages() as $package) { $locator->addTestFolder($package->getPath(self::TESTS_FOLDER)); } return $locator; }
/** * {@inheritdoc} */ public function execute() { $function = rex_request('function', 'string'); if (!in_array($function, ['install', 'uninstall', 'activate', 'deactivate', 'delete'])) { throw new rex_api_exception('Unknown package function "' . $function . '"!'); } $packageId = rex_request('package', 'string'); $package = rex_package::get($packageId); if ($function == 'uninstall' && !$package->isInstalled() || $function == 'activate' && $package->isAvailable() || $function == 'deactivate' && !$package->isAvailable() || $function == 'delete' && !rex_package::exists($packageId)) { throw new rex_api_exception('Illegal operation "' . $function . '" for package "' . $packageId . '"'); } if ($package instanceof rex_null_package) { throw new rex_api_exception('Package "' . $packageId . '" doesn\'t exists!'); } $reinstall = 'install' === $function && $package->isInstalled(); $manager = rex_package_manager::factory($package); $success = $manager->{$function}(); $message = $manager->getMessage(); $result = new rex_api_result($success, $message); if ($success && !$reinstall) { $result->setRequiresReboot(true); } return $result; }
private static function installAddons($uninstallBefore = false, $installDump = true) { $addonErr = ''; rex_package_manager::synchronizeWithFileSystem(); if ($uninstallBefore) { foreach (array_reverse(rex_package::getSystemPackages()) as $package) { $manager = rex_package_manager::factory($package); $state = $manager->uninstall($installDump); if ($state !== true) { $addonErr .= '<li>' . $package->getPackageId() . '<ul><li>' . $manager->getMessage() . '</li></ul></li>'; } } } foreach (rex::getProperty('system_addons') as $packageRepresentation) { $state = true; $package = rex_package::get($packageRepresentation); $manager = rex_package_manager::factory($package); if ($state === true && !$package->isInstalled()) { $state = $manager->install($installDump); } if ($state !== true) { $addonErr .= '<li>' . $package->getPackageId() . '<ul><li>' . $manager->getMessage() . '</li></ul></li>'; } if ($state === true && !$package->isAvailable()) { $state = $manager->activate(); if ($state !== true) { $addonErr .= '<li>' . $package->getPackageId() . '<ul><li>' . $manager->getMessage() . '</li></ul></li>'; } } } if ($addonErr != '') { $addonErr = '<ul class="rex-ul1"> <li> <h3 class="rex-hl3">' . rex_i18n::msg('setup_513', '<span class="rex-error">', '</span>') . '</h3> <ul>' . $addonErr . '</ul> </li> </ul>'; } return $addonErr; }
/** * Loads the properties of package.yml. */ private function loadProperties() { static $cache = null; if (is_null($cache)) { $cache = rex_file::getCache(rex_path::cache('packages.cache')); } $id = $this->getPackageId(); $file = $this->getPath(self::FILE_PACKAGE); if (!file_exists($file)) { $this->propertiesLoaded = true; return; } if (isset($cache[$id]) && (!rex::isBackend() || !($user = rex::getUser()) || !$user->isAdmin() || $cache[$id]['timestamp'] >= filemtime($file))) { $properties = $cache[$id]['data']; } else { $properties = rex_file::getConfig($file); $cache[$id]['timestamp'] = filemtime($file); $cache[$id]['data'] = $properties; static $registeredShutdown = false; if (!$registeredShutdown) { $registeredShutdown = true; register_shutdown_function(function () use(&$cache) { foreach ($cache as $package => $_) { if (!rex_package::exists($package)) { unset($cache[$package]); } } rex_file::putCache(rex_path::cache('packages.cache'), $cache); }); } } foreach ($properties as $key => $value) { if (!isset($this->properties[$key])) { $this->properties[$key] = rex_i18n::translateArray($value, false, [$this, 'i18n']); } } $this->propertiesLoaded = true; }
/** * @param string $temppath * @param string $version * @param rex_addon[] $addons * * @throws rex_functional_exception */ private function checkRequirements($temppath, $version, array $addons) { // ---- update "version", "requires" and "conflicts" properties $coreVersion = rex::getVersion(); rex::setProperty('version', $version); $versions = new SplObjectStorage(); $requirements = new SplObjectStorage(); $conflicts = new SplObjectStorage(); foreach ($addons as $addonkey => $config) { $addon = rex_addon::get($addonkey); $addonPath = $temppath . 'addons/' . $addonkey . '/'; if (isset($config['requires'])) { $requirements[$addon] = $addon->getProperty('requires'); $addon->setProperty('requires', $config['requires']); } if (isset($config['conflicts'])) { $conflicts[$addon] = $addon->getProperty('conflicts'); $addon->setProperty('conflicts', $config['conflicts']); } $versions[$addon] = $addon->getVersion(); $addon->setProperty('version', $config['version']); foreach ($addon->getAvailablePlugins() as $plugin) { if (is_dir($addonPath . 'plugins/' . $plugin->getName())) { $config = rex_file::getConfig($addonPath . 'plugins/' . $plugin->getName() . '/' . rex_package::FILE_PACKAGE); if (isset($config['requires'])) { $requirements[$plugin] = $plugin->getProperty('requires'); $plugin->setProperty('requires', $config['requires']); } if (isset($config['conflicts'])) { $conflicts[$plugin] = $plugin->getProperty('conflicts'); $plugin->setProperty('conflicts', $config['conflicts']); } if (isset($config['version'])) { $versions[$plugin] = $plugin->getProperty('version'); $plugin->setProperty('requires', $config['version']); } } } } // ---- check requirements $messages = []; foreach (rex_package::getAvailablePackages() as $package) { $manager = rex_package_manager::factory($package); if (!$manager->checkRequirements()) { $messages[] = $package->getPackageId() . ': ' . $manager->getMessage(); } elseif (!$manager->checkConflicts()) { $messages[] = $package->getPackageId() . ': ' . $manager->getMessage(); } } // ---- reset "version", "requires" and "conflicts" properties rex::setProperty('version', $coreVersion); foreach ($versions as $package) { $package->setProperty('version', $versions[$package]); } foreach ($requirements as $package) { $package->setProperty('requires', $requirements[$package]); } foreach ($conflicts as $package) { $package->setProperty('conflicts', $conflicts[$package]); } if (!empty($messages)) { throw new rex_functional_exception(implode('<br />', $messages)); } }
/** * Generates the package order. */ public static function generatePackageOrder() { $early = []; $normal = []; $late = []; $requires = []; $add = function ($id) use(&$add, &$normal, &$requires) { $normal[] = $id; unset($requires[$id]); foreach ($requires as $rp => &$ps) { unset($ps[$id]); if (empty($ps)) { $add($rp); } } }; foreach (rex_package::getAvailablePackages() as $package) { $id = $package->getPackageId(); $load = $package->getProperty('load'); if ($package instanceof rex_plugin && !in_array($load, ['early', 'normal', 'late']) && in_array($addonLoad = $package->getAddon()->getProperty('load'), ['early', 'late'])) { $load = $addonLoad; } if ($load === 'early') { $early[] = $id; } elseif ($load === 'late') { $late[] = $id; } else { $req = $package->getProperty('requires'); if ($package instanceof rex_plugin) { $req['packages'][$package->getAddon()->getPackageId()] = true; } if (isset($req['packages']) && is_array($req['packages'])) { foreach ($req['packages'] as $packageId => $reqP) { $package = rex_package::get($packageId); if (!in_array($package, $normal) && !in_array($package->getProperty('load'), ['early', 'late'])) { $requires[$id][$packageId] = true; } } } if (!isset($requires[$id])) { $add($id); } } } rex::setConfig('package-order', array_merge($early, $normal, array_keys($requires), $late)); }
// add package path for fragment loading if (is_readable($folder . 'fragments')) { rex_fragment::addDirectory($folder . 'fragments' . DIRECTORY_SEPARATOR); } // add addon path for class-loading if (is_readable($folder . 'lib')) { rex_autoload::addDirectory($folder . 'lib'); } if (is_readable($folder . 'vendor')) { rex_autoload::addDirectory($folder . 'vendor'); } $autoload = $package->getProperty('autoload'); if (is_array($autoload) && isset($autoload['classes']) && is_array($autoload['classes'])) { foreach ($autoload['classes'] as $dir) { $dir = $package->getPath($dir); if (is_readable($dir)) { rex_autoload::addDirectory($dir); } } } } // now we actually include the addons logic foreach ($packageOrder as $packageId) { $package = rex_package::get($packageId); // include the addon itself if (is_readable($package->getPath(rex_package::FILE_BOOT))) { $package->includeFile(rex_package::FILE_BOOT); } } // ----- all addons configs included rex_extension::registerPoint(new rex_extension_point('PACKAGES_INCLUDED'));
$content .= ' <table class="table table-hover"> <thead> <tr> <th class="rex-table-icon"> </th> <th>' . rex_i18n::msg('credits_name') . '</th> <th>' . rex_i18n::msg('credits_version') . '</th> <th class="rex-table-slim">' . rex_i18n::msg('credits_help') . '</th> <th>' . rex_i18n::msg('credits_author') . '</th> <th>' . rex_i18n::msg('credits_supportpage') . '</th> </tr> </thead> <tbody>'; foreach (rex_package::getAvailablePackages() as $package) { $content .= ' <tr class="rex-package-is-' . $package->getType() . '"> <td class="rex-table-icon"><i class="rex-icon rex-icon-package-' . $package->getType() . '"></i></td> <td data-title="' . rex_i18n::msg('credits_name') . '">' . $package->getName() . ' </td> <td data-title="' . rex_i18n::msg('credits_version') . '">' . $package->getVersion() . '</td> <td class="rex-table-slim" data-title="' . rex_i18n::msg('credits_help') . '"><a href="' . rex_url::backendPage('packages', ['subpage' => 'help', 'package' => $package->getPackageId()]) . '" title="' . rex_i18n::msg('credits_open_help_file') . ' ' . $package->getName() . '"><i class="rex-icon rex-icon-help"></i> <span class="sr-only">' . rex_i18n::msg('package_help') . ' ' . htmlspecialchars($package->getName()) . '</span></a></td> <td data-title="' . rex_i18n::msg('credits_author') . '">' . $package->getAuthor() . '</td> <td data-title="' . rex_i18n::msg('credits_supportpage') . '">'; if ($supportpage = $package->getSupportPage()) { $content .= '<a href="http://' . $supportpage . '" onclick="window.open(this.href); return false;"><i class="rex-icon rex-icon-external-link"></i> ' . $supportpage . '</a>'; } $content .= ' </td> </tr>'; }
/** * @param rex_be_page $page * @param rex_package $package * @param string $prefix */ private static function pageSetSubPaths(rex_be_page $page, rex_package $package, $prefix = '') { foreach ($page->getSubpages() as $subpage) { if (!$subpage->hasSubPath()) { $subpage->setSubPath($package->getPath('pages/' . $prefix . $subpage->getKey() . '.php')); } self::pageSetSubPaths($subpage, $package, $prefix . $subpage->getKey() . '.'); } }
$content .= ' <table class="table table-hover"> <thead> <tr> <th class="rex-table-icon"> </th> <th>' . rex_i18n::msg('credits_name') . '</th> <th>' . rex_i18n::msg('credits_version') . '</th> <th class="rex-table-slim">' . rex_i18n::msg('credits_help') . '</th> <th>' . rex_i18n::msg('credits_author') . '</th> <th>' . rex_i18n::msg('credits_supportpage') . '</th> </tr> </thead> <tbody>'; foreach (rex_package::getRegisteredPackages() as $package) { if ($package->isActivated()) { $content .= ' <tr class="rex-package-is-' . $package->getType() . '"> <td class="rex-table-icon"><i class="rex-icon rex-icon-package-' . $package->getType() . '"></i></td> <td data-title="' . rex_i18n::msg('credits_name') . '">' . $package->getName() . ' </td> <td data-title="' . rex_i18n::msg('credits_version') . '">' . $package->getVersion() . '</td> <td class="rex-table-slim" data-title="' . rex_i18n::msg('credits_help') . '"><a href="' . rex_url::backendPage('packages', ['subpage' => 'help', 'package' => $package->getPackageId()]) . '" title="' . rex_i18n::msg('credits_open_help_file') . ' ' . $package->getName() . '"><i class="rex-icon rex-icon-help"></i> <span class="sr-only">' . rex_i18n::msg('package_help') . ' ' . htmlspecialchars($package->getName()) . '</span></a></td> <td data-title="' . rex_i18n::msg('credits_author') . '">' . $package->getAuthor() . '</td> <td data-title="' . rex_i18n::msg('credits_supportpage') . '">'; if ($supportpage = $package->getSupportPage()) { $content .= '<a href="http://' . $supportpage . '" onclick="window.open(this.href); return false;"><i class="rex-icon rex-icon-external-link"></i> ' . $supportpage . '</a>'; } $content .= ' </td> </tr>';
/** * Loads the properties of package.yml. */ public function loadProperties() { static $cache = null; if (is_null($cache)) { $cache = rex_file::getCache(rex_path::coreCache('packages.cache')); } $id = $this->getPackageId(); $file = $this->getPath(self::FILE_PACKAGE); if (!file_exists($file)) { $this->propertiesLoaded = true; return; } if (isset($cache[$id]) && (!rex::isBackend() || !($user = rex::getUser()) || !$user->isAdmin() || $cache[$id]['timestamp'] >= filemtime($file))) { $properties = $cache[$id]['data']; } else { try { $properties = rex_file::getConfig($file); $cache[$id]['timestamp'] = filemtime($file); $cache[$id]['data'] = $properties; static $registeredShutdown = false; if (!$registeredShutdown) { $registeredShutdown = true; register_shutdown_function(function () use(&$cache) { foreach ($cache as $package => $_) { if (!rex_package::exists($package)) { unset($cache[$package]); } } rex_file::putCache(rex_path::coreCache('packages.cache'), $cache); }); } } catch (rex_yaml_parse_exception $exception) { if ($this->isInstalled()) { throw $exception; } $properties = []; } } $this->properties = array_intersect_key($this->properties, ['install' => null, 'status' => null]); if ($properties) { foreach ($properties as $key => $value) { if (isset($this->properties[$key])) { continue; } if ('supportpage' !== $key) { $value = rex_i18n::translateArray($value, false, [$this, 'i18n']); } elseif (!preg_match('@^https?://@i', $value)) { $value = 'http://' . $value; } $this->properties[$key] = $value; } } $this->propertiesLoaded = true; }
<?php /** * @package redaxo5 */ echo rex_view::title(rex_i18n::msg('addons'), ''); $content = ''; // -------------- RequestVars $subpage = rex_request('subpage', 'string'); // ----------------- HELPPAGE if ($subpage == 'help') { $package = rex_package::get(rex_request('package', 'string')); $name = $package->getPackageId(); $version = $package->getVersion(); $author = $package->getAuthor(); $supportPage = $package->getSupportPage(); if (!is_file($package->getPath('help.php'))) { $content .= rex_view::info(rex_i18n::msg('package_no_help_file')); } else { ob_start(); $package->includeFile('help.php'); $content .= ob_get_clean(); } $fragment = new rex_fragment(); $fragment->setVar('title', rex_i18n::msg('package_help') . ' ' . $name, false); $fragment->setVar('body', $content, false); echo $fragment->parse('core/page/section.php'); $credits = ''; $credits .= '<dl class="dl-horizontal">'; $credits .= '<dt>' . rex_i18n::msg('credits_name') . '</dt><dd>' . htmlspecialchars($name) . '</dd>'; if ($version) {
private function checkRequirements($config) { $temppath = rex_path::addon('.new.' . $this->addonkey); // ---- update "version", "requires" and "conflicts" properties $versions = new SplObjectStorage(); $requirements = new SplObjectStorage(); $conflicts = new SplObjectStorage(); if (isset($config['requires'])) { $requirements[$this->addon] = $this->addon->getProperty('requires'); $this->addon->setProperty('requires', $config['requires']); } if (isset($config['conflicts'])) { $conflicts[$this->addon] = $this->addon->getProperty('conflicts'); $this->addon->setProperty('conflicts', $config['conflicts']); } $versions[$this->addon] = $this->addon->getVersion(); $this->addon->setProperty('version', isset($config['version']) ? $config['version'] : $this->file['version']); $availablePlugins = $this->addon->getAvailablePlugins(); foreach ($availablePlugins as $plugin) { if (is_dir($temppath . '/plugins/' . $plugin->getName())) { $config = rex_file::getConfig($temppath . '/plugins/' . $plugin->getName() . '/' . rex_package::FILE_PACKAGE); if (isset($config['requires'])) { $requirements[$plugin] = $plugin->getProperty('requires'); $plugin->setProperty('requires', $config['requires']); } if (isset($config['conflicts'])) { $conflicts[$plugin] = $plugin->getProperty('conflicts'); $plugin->setProperty('conflicts', $config['conflicts']); } if (isset($config['version'])) { $versions[$plugin] = $plugin->getProperty('version'); $plugin->setProperty('requires', $config['version']); } } } // ---- check requirements $messages = []; $manager = rex_addon_manager::factory($this->addon); if (!$manager->checkRequirements()) { $messages[] = $manager->getMessage(); } if (!$manager->checkConflicts()) { $messages[] = $manager->getMessage(); } if (empty($messages)) { foreach ($availablePlugins as $plugin) { $manager = rex_plugin_manager::factory($plugin); if (!$manager->checkRequirements()) { $messages[] = $plugin->getPackageId() . ': ' . $manager->getMessage(); } if (!$manager->checkConflicts()) { $messages[] = $plugin->getPackageId() . ': ' . $manager->getMessage(); } } foreach (rex_package::getAvailablePackages() as $package) { if ($package->getAddon() === $this->addon) { continue; } $manager = rex_package_manager::factory($package); if (!$manager->checkPackageRequirement($this->addon->getPackageId())) { $messages[] = $package->getPackageId() . ': ' . $manager->getMessage(); } elseif (!$manager->checkPackageConflict($this->addon->getPackageId())) { $messages[] = $package->getPackageId() . ': ' . $manager->getMessage(); } else { foreach ($versions as $reqPlugin) { if (!$manager->checkPackageRequirement($reqPlugin->getPackageId())) { $messages[] = $package->getPackageId() . ': ' . $manager->getMessage(); } if (!$manager->checkPackageConflict($reqPlugin->getPackageId())) { $messages[] = $package->getPackageId() . ': ' . $manager->getMessage(); } } } } } // ---- reset "version", "requires" and "conflicts" properties foreach ($versions as $package) { $package->setProperty('version', $versions[$package]); } foreach ($requirements as $package) { $package->setProperty('requires', $requirements[$package]); } foreach ($conflicts as $package) { $package->setProperty('conflicts', $conflicts[$package]); } return empty($messages) ? true : implode('<br />', $messages); }
/** * {@inheritdoc} */ public function isAvailable() { return $this->getAddon()->isAvailable() && parent::isAvailable(); }