Add Server\Plugin value object
Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
This commit is contained in:
parent
3fc92c60e4
commit
b9ec5071fe
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
252
libraries/classes/Server/Plugin.php
Normal file
252
libraries/classes/Server/Plugin.php
Normal 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;
|
||||
}
|
||||
}
|
||||
74
libraries/classes/Server/Plugins.php
Normal file
74
libraries/classes/Server/Plugins.php
Normal 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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -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']
|
||||
|
||||
@ -128,6 +128,7 @@ services:
|
||||
response: '@response'
|
||||
dbi: '@dbi'
|
||||
template: '@template'
|
||||
plugins: '@server_plugins'
|
||||
|
||||
PhpMyAdmin\Controllers\Server\ReplicationController:
|
||||
class: 'PhpMyAdmin\Controllers\Server\ReplicationController'
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user