1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-03-24 09:30:34 +01:00

[ticket/11150] Add ACP gallery

PHPBB3-11150
This commit is contained in:
Tristan Darricau 2015-09-13 10:48:30 +02:00 committed by Tristan Darricau
parent c49cd29e96
commit adb8d30d98
No known key found for this signature in database
GPG Key ID: 817043C2E29DB881
8 changed files with 237 additions and 41 deletions

View File

@ -0,0 +1,57 @@
<!-- INCLUDE overall_header.html -->
<a id="maincontent"></a>
<h1>{{lang( 'EXTENSIONS_ADMIN') }}</h1>
<p>{{lang( 'EXTENSIONS_EXPLAIN') }}</p>
<fieldset class="quick">
<span class="small"><a href="https://www.phpbb.com/go/customise/extensions/3.1" target="_blank">{{ lang('BROWSE_EXTENSIONS_DATABASE') }}</a> &bull; <a href="javascript:phpbb.toggleDisplay('gallery_settings');">{{ lang('SETTINGS') }}</a></span>
</fieldset>
<form id="gallery_settings" method="post" action="{{ U_ACTION }}" style="display:none">
<fieldset>
<legend>{{ lang('EXTENSIONS_GALLERY_SETTINGS') }}</legend>
<dl>
<dt><label for="force_unstable">{L_FORCE_UNSTABLE}{L_COLON}</label></dt>
<dd>
<label><input type="radio" id="force_unstable" name="force_unstable" class="radio" value="1"<!-- IF FORCE_UNSTABLE --> checked="checked"<!-- ENDIF --> /> {L_YES}</label>
<label><input type="radio" name="force_unstable" class="radio" value="0"<!-- IF not FORCE_UNSTABLE --> checked="checked"<!-- ENDIF --> /> {L_NO}</label>
</dd>
</dl>
<p class="submit-buttons">
<input class="button1" type="submit" name="update" value="{{ lang('SUBMIT') }}" />&nbsp;
<input class="button2" type="reset" name="reset" value="{{ lang('RESET') }}" />
<input type="hidden" name="action" value="set_gallery_settings" />
{{ S_FORM_TOKEN }}
</p>
</fieldset>
</form>
<table class="table1">
<col class="row1" ><col class="row1" ><col class="row1" >
<thead>
<tr>
<th style="width: 20%;">{{ lang("EXTENSION_NAME") }}</th>
<th style="text-align: center; width: 10%;">{{ lang("VERSION") }}</th>
<th>{{ lang("DESCRIPTION") }}</th>
</tr>
</thead>
<tbody>
{% for extension in extensions %}
<tr>
<td>
<strong>{{ extension.name }}</strong><br />
<span><a href="{{ extension.url }}">{{ lang('DETAILS') }}</a> &bull; <a href="">{{ lang('INSTALL') }}</a></span>
</td>
<td>{{ extension.version }}</td>
<td>{{ extension.description }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- INCLUDE overall_footer.html -->

View File

@ -28,10 +28,13 @@ class acp_extensions
var $tpl_name;
var $page_title;
private $db;
private $config;
private $template;
private $user;
private $log;
/** @var \phpbb\request\request */
private $request;
private $phpbb_dispatcher;
private $ext_manager;
@ -39,8 +42,10 @@ class acp_extensions
function main()
{
// Start the page
global $config, $user, $template, $request, $phpbb_extension_manager, $phpbb_root_path, $phpbb_log, $phpbb_dispatcher;
global $config, $user, $template, $request, $phpbb_extension_manager, $db, $phpbb_root_path, $phpbb_log, $phpbb_dispatcher;
$this->db = $db;
$this->config = $config;
$this->template = $template;
$this->user = $user;
@ -49,7 +54,22 @@ class acp_extensions
$this->phpbb_dispatcher = $phpbb_dispatcher;
$this->ext_manager = $phpbb_extension_manager;
$this->user->add_lang(array('install', 'acp/extensions', 'migrator'));
$this->user->add_lang(['install', 'acp/extensions', 'migrator']);
switch ($mode)
{
case 'gallery':
$this->gallery_mode();
break;
default:
$this->main_mode();
break;
}
}
public function main_mode()
{
global $phpbb_extension_manager, $phpbb_root_path;
$this->page_title = 'ACP_EXTENSIONS';
@ -381,6 +401,20 @@ class acp_extensions
$this->tpl_name = $tpl_name;
}
public function gallery_mode()
{
global $phpbb_container;
/** @var \phpbb\composer\extension_manager $manager */
$manager = $phpbb_container->get('ext.composer.manager');
$this->page_title = 'ACP_EXTENSIONS_GALLERY';
$this->tpl_name = 'acp_ext_gallery';
$this->request->enable_super_globals();
$this->template->assign_var('extensions', $manager->get_available_packages());
$this->request->disable_super_globals();
}
/**
* Lists all the enabled extensions and dumps to the template
*

View File

@ -20,6 +20,7 @@ class acp_extensions_info
'title' => 'ACP_EXTENSION_MANAGEMENT',
'modes' => array(
'main' => array('title' => 'ACP_EXTENSIONS', 'auth' => 'acl_a_extensions', 'cat' => array('ACP_EXTENSION_MANAGEMENT')),
'gallery' => array('title' => 'ACP_EXTENSIONS_GALLERY', 'auth' => 'acl_a_extensions', 'cat' => array('ACP_EXTENSION_MANAGEMENT')),
),
);
}

View File

@ -88,6 +88,7 @@ $lang = array_merge($lang, array(
'ACP_EXTENSION_GROUPS' => 'Manage attachment extension groups',
'ACP_EXTENSION_MANAGEMENT' => 'Extension management',
'ACP_EXTENSIONS' => 'Manage extensions',
'ACP_EXTENSIONS_GALLERY' => 'Extensions gallery',
'ACP_FORUM_BASED_PERMISSIONS' => 'Forum based permissions',
'ACP_FORUM_LOGS' => 'Forum logs',

View File

@ -19,6 +19,8 @@ use Composer\IO\IOInterface;
use Composer\IO\NullIO;
use Composer\Json\JsonFile;
use Composer\Package\CompletePackage;
use Composer\Package\LinkConstraint\LinkConstraintInterface;
use Composer\Package\LinkConstraint\VersionConstraint;
use Composer\Package\PackageInterface;
use Composer\Repository\ComposerRepository;
use Composer\Repository\RepositoryInterface;
@ -198,62 +200,101 @@ class installer
$composer = Factory::create($io, $this->get_composer_ext_json_filename(), false);
/** @var LinkConstraintInterface $core_constraint */
$core_constraint = $composer->getPackage()->getRequires()['phpbb/phpbb']->getConstraint();
$available = [];
$compatible_packages = [];
$repositories = $composer->getRepositoryManager()->getRepositories();
/** @var RepositoryInterface $repository */
foreach ($repositories as $repository)
{
if ($repository instanceof ComposerRepository && $repository->hasProviders())
try
{
$r = new \ReflectionObject($repository);
$repo_url = $r->getProperty('url');
$repo_url->setAccessible(true);
if ($repo_url->getValue($repository) === 'http://packagist.org')
if ($repository instanceof ComposerRepository && $repository->hasProviders())
{
$url = 'https://packagist.org/packages/list.json?type=' . $type;
$rfs = new RemoteFilesystem($io);
$hostname = parse_url($url, PHP_URL_HOST) ?: $url;
$json = $rfs->getContents($hostname, $url, false);
// Special case for packagist which exposes an api to retrieve all packages of a given type.
// For the others composer repositories with providers we can't do anything. It would be too slow.
/** @var PackageInterface $package */
foreach (JsonFile::parseJson($json, $url)['packageNames'] as $package)
$r = new \ReflectionObject($repository);
$repo_url = $r->getProperty('url');
$repo_url->setAccessible(true);
if ($repo_url->getValue($repository) === 'http://packagist.org')
{
$packages = $repository->findPackages($package);
$package = array_pop($packages);
$url = 'https://packagist.org/packages/list.json?type=' . $type;
$rfs = new RemoteFilesystem($io);
$hostname = parse_url($url, PHP_URL_HOST) ?: $url;
$json = $rfs->getContents($hostname, $url, false);
if (isset($available[$package->getName()]))
/** @var PackageInterface $package */
foreach (JsonFile::parseJson($json, $url)['packageNames'] as $package)
{
continue;
$versions = $repository->findPackages($package);
$compatible_packages = $this->get_compatible_versions($compatible_packages, $core_constraint, $package, $versions);
}
$available[$package->getName()] = ['name' => $package->getPrettyName()];
if ($package instanceof CompletePackage)
}
}
else
{
// Pre-filter repo packages by their type
$packages = [];
/** @var PackageInterface $package */
foreach ($repository->getPackages() as $package)
{
if ($package->getType() === $type)
{
$available[$package->getName()]['description'] = $package->getDescription();
$available[$package->getName()]['url'] = $package->getHomepage();
$packages[$package->getName()][] = $package;
}
}
// Filter the compatibles versions
foreach ($packages as $package => $versions)
{
$compatible_packages = $this->get_compatible_versions($compatible_packages, $core_constraint, $package, $versions);
}
}
}
catch (\Exception $e)
{
// If a repo fails, just skip it.
continue;
}
}
foreach ($compatible_packages as $name => $versions)
{
// Determine the highest version of the package
/** @var CompletePackage $highest_version */
$highest_version = null;
/** @var CompletePackage $version */
foreach ($versions as $version)
{
if (!$highest_version || version_compare($version->getVersion(), $highest_version->getVersion(), '>'))
{
$highest_version = $version;
}
}
// Generates the entry
$available[$name] = [];
$available[$name]['name'] = $highest_version->getPrettyName();
$available[$name]['version'] = $highest_version->getPrettyVersion();
if ($version instanceof CompletePackage)
{
$available[$name]['description'] = $highest_version->getDescription();
$available[$name]['url'] = $highest_version->getHomepage();
$available[$name]['authors'] = $highest_version->getAuthors();
}
else
{
/** @var PackageInterface $package */
foreach ($repository->getPackages() as $package)
{
if ($package->getType() === $type)
{
$available[$package->getName()] = ['name' => $package->getPrettyName()];
if ($package instanceof CompletePackage)
{
$available[$package->getName()]['description'] = $package->getDescription();
$available[$package->getName()]['url'] = $package->getHomepage();
}
}
}
$available[$name]['description'] = '';
$available[$name]['url'] = '';
$available[$name]['authors'] = [];
}
}
@ -267,6 +308,38 @@ class installer
}
}
/**
* Updates $compatible_packages with the versions of $versions compatibles with the $core_constraint
*
* @param array $compatible_packages List of compatibles versions
* @param LinkConstraintInterface $core_constraint Constraint against the phpBB version
* @param string $package_name Considered package
* @param array $versions List of available versions
*
* @return array
*/
private function get_compatible_versions(array $compatible_packages, LinkConstraintInterface $core_constraint, $package_name, array $versions)
{
/** @var PackageInterface $version */
foreach ($versions as $version)
{
if (array_key_exists('phpbb/phpbb', $version->getRequires()))
{
/** @var LinkConstraintInterface $package_constraint */
$package_constraint = $version->getRequires()['phpbb/phpbb']->getConstraint();
if (!$package_constraint->matches($core_constraint))
{
continue;
}
}
$compatible_packages[$package_name][] = $version;
}
return $compatible_packages;
}
/**
* Generates and write the json file used to install the set of packages
*
@ -276,7 +349,7 @@ class installer
protected function generate_ext_json_file(array $packages)
{
$io = new NullIO();
$composer = Factory::create($io, null, false);
$composer = Factory::create($io, $this->root_path . 'composer.json', false);
$core_packages = $this->get_core_packages($composer);
$core_json_data = [
@ -314,6 +387,27 @@ class installer
return $core_deps;
}
/**
* Get the core installed packages
*
* @param Composer $composer Composer object to load the dependencies
* @return array The core packages with their version
*/
protected function get_core_version(Composer $composer)
{
$core_deps = [];
$packages = $composer->getRepositoryManager()->getLocalRepository()->getCanonicalPackages();
foreach ($packages as $package)
{
$core_deps[$package->getName()] = $package->getPrettyVersion();
}
$core_deps['phpbb/phpbb'] = $composer->getPackage()->getPrettyVersion();
return $core_deps;
}
/**
* Get the PHP version required by the core
*

View File

@ -187,7 +187,7 @@ class manager implements manager_interface
if ($this->available_packages === null)
{
$this->available_packages = $this->cache->get('_composer_' . $this->package_type . '_available');
if ($this->available_packages === false)
if (!$this->available_packages)
{
$this->available_packages = $this->installer->get_available_packages($this->package_type);
$this->cache->put('_composer_' . $this->package_type . '_available', $this->available_packages, 24*60*60);

View File

@ -66,7 +66,8 @@ class list_available extends \phpbb\console\command\command
foreach ($this->manager->get_available_packages() as $package)
{
$extensions[] = '<info>' . $package['name'] . '</info> <comment>' . $package['url'] . "</comment>\n" . $package['description'];
$extensions[] = '<info>' . $package['name'] . '</info> (<comment>' . $package['version'] . '</comment>) ' . $package['url'] .
($package['description'] ? "\n" . $package['description'] : '');
}
$io->listing($extensions);

View File

@ -22,6 +22,14 @@ class extensions_composer extends \phpbb\db\migration\migration
array('config.add', array('exts_composer_packagist', true)),
array('config.add', array('exts_composer_json_file', 'composer-ext.json')),
array('config.add', array('exts_composer_vendor_dir', 'vendor-ext/')),
array('module.add', array(
'acp',
'ACP_EXTENSION_MANAGEMENT',
array(
'module_basename' => 'acp_extensions',
'modes' => array('gallery'),
),
)),
);
}
}