Add Server\Plugin value object

Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
This commit is contained in:
Maurício Meneghini Fauth 2019-07-02 00:40:54 -03:00
parent 3fc92c60e4
commit b9ec5071fe
7 changed files with 389 additions and 60 deletions

View File

@ -13,6 +13,7 @@ namespace PhpMyAdmin\Controllers\Server;
use PhpMyAdmin\Controllers\AbstractController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Server\Plugins;
use PhpMyAdmin\Template;
/**
@ -23,21 +24,20 @@ use PhpMyAdmin\Template;
class PluginsController extends AbstractController
{
/**
* @var array plugin details
* @var Plugins
*/
private $plugins;
/**
* Constructs PluginsController
*
* @param Response $response Response object
* @param DatabaseInterface $dbi DatabaseInterface object
* @param Template $template Template object
* @param Plugins $plugins Plugins object
*/
public function __construct($response, $dbi, Template $template)
public function __construct($response, $dbi, Template $template, Plugins $plugins)
{
parent::__construct($response, $dbi, $template);
$this->setPlugins();
$this->plugins = $plugins;
}
/**
@ -54,43 +54,32 @@ class PluginsController extends AbstractController
$scripts->addFile('vendor/jquery/jquery.tablesorter.js');
$scripts->addFile('server/plugins.js');
$pluginsTypeClean = [];
foreach (array_keys($this->plugins) as $pluginType) {
$pluginsTypeClean[$pluginType] = preg_replace(
$plugins = [];
$serverPlugins = $this->plugins->getAll();
foreach ($serverPlugins as $plugin) {
$plugins[$plugin->getType()][] = [
'name' => $plugin->getName(),
'type' => $plugin->getType(),
'version' => $plugin->getVersion(),
'description' => $plugin->getDescription(),
'author' => $plugin->getAuthor(),
'license' => $plugin->getLicense(),
'status' => $plugin->getStatus(),
];
}
ksort($plugins);
$cleanTypes = [];
foreach (array_keys($plugins) as $type) {
$cleanTypes[$type] = preg_replace(
'/[^a-z]/',
'',
mb_strtolower($pluginType)
mb_strtolower($type)
);
}
return $this->template->render('server/plugins/index', [
'plugins' => $this->plugins,
'plugins_type_clean' => $pluginsTypeClean,
'plugins' => $plugins,
'clean_types' => $cleanTypes,
]);
}
/**
* Sets details about server plugins
*
* @return void
*/
private function setPlugins(): void
{
$sql = "SELECT plugin_name,
plugin_type,
(plugin_status = 'ACTIVE') AS is_active,
plugin_type_version,
plugin_author,
plugin_description,
plugin_license
FROM information_schema.plugins
ORDER BY plugin_type, plugin_name";
$res = $this->dbi->query($sql);
$this->plugins = [];
while ($row = $this->dbi->fetchAssoc($res)) {
$this->plugins[$row['plugin_type']][] = $row;
}
$this->dbi->freeResult($res);
ksort($this->plugins);
}
}

View File

@ -0,0 +1,252 @@
<?php
/**
* Server Plugin value object
* @package PhpMyAdmin\Server
*/
declare(strict_types=1);
namespace PhpMyAdmin\Server;
/**
* Server Plugin value object
* @package PhpMyAdmin\Server
*/
final class Plugin
{
/**
* @var string
*/
private $name;
/**
* @var string|null
*/
private $version;
/**
* @var string
*/
private $status;
/**
* @var string
*/
private $type;
/**
* @var string|null
*/
private $typeVersion;
/**
* @var string|null
*/
private $library;
/**
* @var string|null
*/
private $libraryVersion;
/**
* @var string|null
*/
private $author;
/**
* @var string|null
*/
private $description;
/**
* @var string
*/
private $license;
/**
* @var string|null
*/
private $loadOption;
/**
* @var string|null
*/
private $maturity;
/**
* @var string|null
*/
private $authVersion;
/**
* @param string $name Name of the plugin
* @param string|null $version Version from the plugin's general type descriptor
* @param string $status Plugin status
* @param string $type Type of plugin
* @param string|null $typeVersion Version from the plugin's type-specific descriptor
* @param string|null $library Plugin's shared object file name
* @param string|null $libraryVersion Version from the plugin's API interface
* @param string|null $author Author of the plugin
* @param string|null $description Description
* @param string $license Plugin's licence
* @param string|null $loadOption How the plugin was loaded
* @param string|null $maturity Plugin's maturity level
* @param string|null $authVersion Plugin's version as determined by the plugin author
*/
private function __construct(
string $name,
?string $version,
string $status,
string $type,
?string $typeVersion,
?string $library,
?string $libraryVersion,
?string $author,
?string $description,
string $license,
?string $loadOption,
?string $maturity,
?string $authVersion
) {
$this->name = $name;
$this->version = $version;
$this->status = $status;
$this->type = $type;
$this->typeVersion = $typeVersion;
$this->library = $library;
$this->libraryVersion = $libraryVersion;
$this->author = $author;
$this->description = $description;
$this->license = $license;
$this->loadOption = $loadOption;
$this->maturity = $maturity;
$this->authVersion = $authVersion;
}
/**
* @param array $state array with the properties
* @return self
*/
public static function fromState(array $state): self
{
return new self(
$state['name'] ?? '',
$state['version'] ?? null,
$state['status'] ?? '',
$state['type'] ?? '',
$state['typeVersion'] ?? null,
$state['library'] ?? null,
$state['libraryVersion'] ?? null,
$state['author'] ?? null,
$state['description'] ?? null,
$state['license'] ?? '',
$state['loadOption'] ?? null,
$state['maturity'] ?? null,
$state['authVersion'] ?? null
);
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @return string|null
*/
public function getVersion(): ?string
{
return $this->version;
}
/**
* @return string
*/
public function getStatus(): string
{
return $this->status;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @return string|null
*/
public function getTypeVersion(): ?string
{
return $this->typeVersion;
}
/**
* @return string|null
*/
public function getLibrary(): ?string
{
return $this->library;
}
/**
* @return string|null
*/
public function getLibraryVersion(): ?string
{
return $this->libraryVersion;
}
/**
* @return string|null
*/
public function getAuthor(): ?string
{
return $this->author;
}
/**
* @return string|null
*/
public function getDescription(): ?string
{
return $this->description;
}
/**
* @return string
*/
public function getLicense(): string
{
return $this->license;
}
/**
* @return string|null
*/
public function getLoadOption(): ?string
{
return $this->loadOption;
}
/**
* @return string|null
*/
public function getMaturity(): ?string
{
return $this->maturity;
}
/**
* @return string|null
*/
public function getAuthVersion(): ?string
{
return $this->authVersion;
}
}

View File

@ -0,0 +1,74 @@
<?php
/**
* Class Plugins
* @package PhpMyAdmin\Server
*/
declare(strict_types=1);
namespace PhpMyAdmin\Server;
use PhpMyAdmin\DatabaseInterface;
/**
* Class Plugins
* @package PhpMyAdmin\Server
*/
class Plugins
{
/**
* @var DatabaseInterface
*/
private $dbi;
/**
* @param DatabaseInterface $dbi DatabaseInterface instance
*/
public function __construct(DatabaseInterface $dbi)
{
$this->dbi = $dbi;
}
/**
* @return Plugin[]
*/
public function getAll(): array
{
global $cfg;
$sql = 'SHOW PLUGINS;';
if (! $cfg['Server']['DisableIS']) {
$sql = 'SELECT * FROM information_schema.PLUGINS ORDER BY PLUGIN_TYPE, PLUGIN_NAME;';
}
$result = $this->dbi->query($sql);
$plugins = [];
while ($row = $this->dbi->fetchAssoc($result)) {
$plugins[] = $this->mapRowToPlugin($row);
}
$this->dbi->freeResult($result);
return $plugins;
}
/**
* @param array $row Row fetched from database
* @return Plugin
*/
private function mapRowToPlugin(array $row): Plugin
{
return Plugin::fromState([
'name' => $row['PLUGIN_NAME'] ?? $row['Name'],
'version' => $row['PLUGIN_VERSION'] ?? null,
'status' => $row['PLUGIN_STATUS'] ?? $row['Status'],
'type' => $row['PLUGIN_TYPE'] ?? $row['Type'],
'typeVersion' => $row['PLUGIN_TYPE_VERSION'] ?? null,
'library' => $row['PLUGIN_LIBRARY'] ?? $row['Library'] ?? null,
'libraryVersion' => $row['PLUGIN_LIBRARY_VERSION'] ?? null,
'author' => $row['PLUGIN_AUTHOR'] ?? null,
'description' => $row['PLUGIN_DESCRIPTION'] ?? null,
'license' => $row['PLUGIN_LICENSE'] ?? $row['License'],
'loadOption' => $row['LOAD_OPTION'] ?? null,
'maturity' => $row['PLUGIN_MATURITY'] ?? null,
'authVersion' => $row['PLUGIN_AUTH_VERSION'] ?? null,
]);
}
}

View File

@ -103,6 +103,10 @@ services:
response:
factory: 'PhpMyAdmin\Response::getInstance'
server_plugins:
class: 'PhpMyAdmin\Server\Plugins'
arguments: ['@dbi']
server_privileges:
class: 'PhpMyAdmin\Server\Privileges'
arguments: ['@template', '@dbi', '@relation', '@relation_cleanup']

View File

@ -128,6 +128,7 @@ services:
response: '@response'
dbi: '@dbi'
template: '@template'
plugins: '@server_plugins'
PhpMyAdmin\Controllers\Server\ReplicationController:
class: 'PhpMyAdmin\Controllers\Server\ReplicationController'

View File

@ -5,18 +5,17 @@
<div id="plugins_plugins">
<div id="sectionlinks">
{% for plugin_type in plugins|keys %}
<a class="btn btn-primary" href="#plugins-{{- plugins_type_clean[plugin_type] }}">
{{ plugin_type }}
{% for type in plugins|keys %}
<a class="btn btn-primary" href="#plugins-{{ clean_types[type] }}">
{{ type }}
</a>
{% endfor %}
</div>
{% for plugin_type, plugin_list in plugins %}
{% for type, list in plugins %}
<div class="responsivetable">
<table class="data_full_width" id="plugins-
{{- plugins_type_clean[plugin_type] }}">
<table class="data_full_width" id="plugins-{{ clean_types[type] }}">
<caption class="tblHeaders">
{{ plugin_type }}
{{ type }}
</caption>
<thead>
<tr>
@ -28,20 +27,28 @@
</tr>
</thead>
<tbody>
{% for plugin in plugin_list %}
{% for plugin in list %}
<tr class="noclick">
<th>
{{ plugin.plugin_name }}
{% if not plugin.is_active %}
{{ plugin.name }}
{% if plugin.status != 'ACTIVE' %}
<small class="attention">
{% trans 'disabled' %}
{% if plugin.status == 'INACTIVE' %}
{% trans 'inactive' %}
{% elseif plugin.status == 'DISABLED' %}
{% trans 'disabled' %}
{% elseif plugin.status == 'DELETING' %}
{% trans 'deleting' %}
{% elseif plugin.status == 'DELETED' %}
{% trans 'deleted' %}
{% endif %}
</small>
{% endif %}
</th>
<td>{{ plugin.plugin_description }}</td>
<td>{{ plugin.plugin_type_version }}</td>
<td>{{ plugin.plugin_author }}</td>
<td>{{ plugin.plugin_license }}</td>
<td>{{ plugin.description }}</td>
<td>{{ plugin.version }}</td>
<td>{{ plugin.author }}</td>
<td>{{ plugin.license }}</td>
</tr>
{% endfor %}
</tbody>

View File

@ -13,6 +13,7 @@ use PhpMyAdmin\Config;
use PhpMyAdmin\Controllers\Server\PluginsController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Server\Plugins;
use PhpMyAdmin\Template;
use PHPUnit\Framework\TestCase;
@ -51,13 +52,13 @@ class PluginsControllerTest extends TestCase
* Prepare plugin list
*/
$row = [
'plugin_name' => 'plugin_name1',
'plugin_type' => 'plugin_type1',
'plugin_type_version' => 'plugin_version1',
'plugin_author' => 'plugin_author1',
'plugin_license' => 'plugin_license1',
'plugin_description' => 'plugin_description1',
'is_active' => true,
'PLUGIN_NAME' => 'plugin_name1',
'PLUGIN_TYPE' => 'plugin_type1',
'PLUGIN_VERSION' => 'plugin_version1',
'PLUGIN_AUTHOR' => 'plugin_author1',
'PLUGIN_LICENSE' => 'plugin_license1',
'PLUGIN_DESCRIPTION' => 'plugin_description1',
'PLUGIN_STATUS' => 'ACTIVE',
];
$dbi = $this->getMockBuilder(DatabaseInterface::class)
@ -79,7 +80,8 @@ class PluginsControllerTest extends TestCase
$controller = new PluginsController(
Response::getInstance(),
$dbi,
new Template()
new Template(),
new Plugins($dbi)
);
$actual = $controller->index();