com web/bugs: Converted the current admin pages (/admin) to use proper templates and repositories: config/container.php
src/Repository/DatabaseStatusRepository.php src/Repository/PhpInfoRepository.php src/Repository/ReasonRepository.php
templates/pages/admin/database_status.php templates/pages /admin/mailing_lists.php templates/pages/admin/menu.php templates/pages/admin/phpinfo.php
templates/pages/admin/ quick_responses.php www/admin/index.php www/

From: Date: Thu, 23 May 2019 00:46:24 +0000
Subject: com web/bugs: Converted the current admin pages (/admin) to use proper templates and repositories: config/container.php
src/Repository/DatabaseStatusRepository.php src/Repository/PhpInfoRepository.php src/Repository/ReasonRepository.php
templates/pages/admin/database_status.php templates/pages /admin/mailing_lists.php templates/pages/admin/menu.php templates/pages/admin/phpinfo.php
templates/pages/admin/ quick_responses.php www/admin/index.php www/
Groups: php.webmaster 
Request: Send a blank email to php-webmaster+get-28068@lists.php.net to get a copy of this message
Commit: 9531cd154db3a5e41b6e806226e9e371d2699f52 Author: Pieter Hordijk <info@pieterhordijk.com> Wed, 22 May 2019 21:06:46 +0300 Committer: Peter Kokot <peterkokot@gmail.com> Thu, 23 May 2019 02:46:24 +0200 Parents: e8bab3538a9d05d0da584c2ff8b18c7d9eea2fdd Branches: master Link: http://git.php.net/?p=web/bugs.git;a=commitdiff;h=9531cd154db3a5e41b6e806226e9e371d2699f52 Log: Converted the current admin pages (/admin) to use proper templates and repositories Changed paths: M config/container.php A src/Repository/DatabaseStatusRepository.php A src/Repository/PhpInfoRepository.php M src/Repository/ReasonRepository.php A templates/pages/admin/database_status.php A templates/pages/admin/mailing_lists.php A templates/pages/admin/menu.php A templates/pages/admin/phpinfo.php A templates/pages/admin/quick_responses.php M www/admin/index.php M www/css/style.css

diff --git a/config/container.php b/config/container.php index 59e3045..d869f44 100644 --- a/config/container.php +++ b/config/container.php @@ -33,6 +33,10 @@ $container->set(App\Repository\CommentRepository::class, function ($c) { return new App\Repository\CommentRepository($c->get(\PDO::class)); }); +$container->set(App\Repository\DatabaseStatusRepository::class, function ($c) { + return new App\Repository\DatabaseStatusRepository($c->get(\PDO::class)); +}); + $container->set(App\Repository\ObsoletePatchRepository::class, function ($c) { return new App\Repository\ObsoletePatchRepository($c->get(\PDO::class)); }); @@ -45,6 +49,10 @@ $container->set(App\Repository\PatchRepository::class, function ($c) { return new App\Repository\PatchRepository($c->get(\PDO::class), $c->get('uploads_dir')); }); +$container->set(App\Repository\PhpInfoRepository::class, function ($c) { + return new App\Repository\PhpInfoRepository(); +}); + $container->set(App\Repository\PullRequestRepository::class, function ($c) { return new App\Repository\PullRequestRepository($c->get(\PDO::class)); }); diff --git a/src/Repository/DatabaseStatusRepository.php b/src/Repository/DatabaseStatusRepository.php new file mode 100644 index 0000000..971ba42 --- /dev/null +++ b/src/Repository/DatabaseStatusRepository.php @@ -0,0 +1,60 @@ +<?php + +namespace App\Repository; + +/** + * Repository class for fetching database status data presented under /admin + */ +class DatabaseStatusRepository +{ + /** + * Database handler. + * @var \PDO + */ + private $dbh; + + /** + * Class constructor. + */ + public function __construct(\PDO $dbh) + { + $this->dbh = $dbh; + } + + public function getMysqlVersion(): string + { + return $this->dbh->query('SELECT version() mysql_version')->fetchColumn(0); + } + + /** + * @return string[] + */ + public function findAllTables(): array + { + return $this->dbh->query('SHOW TABLES')->fetchAll(\PDO::FETCH_COLUMN); + } + + /** + * @return array<int,string> + */ + public function getNumberOfRowsInTables(): array + { + $numberOfRowsPerTable = []; + + foreach ($this->findAllTables() as $tableName) { + $sql = sprintf('SELECT COUNT(*) FROM `%s`', $tableName); + + $numberOfRowsPerTable[$tableName] = $this->dbh->query($sql)->fetchColumn(0); + } + + return $numberOfRowsPerTable; + } + + /** + * @return array<int,array<string,mixed>> + */ + public function getStatusOfTables(): array + { + return $this->dbh->query('SHOW TABLE STATUS')->fetchAll(); + } +} diff --git a/src/Repository/PhpInfoRepository.php b/src/Repository/PhpInfoRepository.php new file mode 100644 index 0000000..6542357 --- /dev/null +++ b/src/Repository/PhpInfoRepository.php @@ -0,0 +1,46 @@ +<?php + +namespace App\Repository; + +/** + * Repository class for fetching information about PHP's configuration + */ +class PhpInfoRepository +{ + public function getInfo(): string + { + ob_start(); + phpinfo(); + + $phpInfo = $this->replaceSensitiveInformation(ob_get_clean()); + $phpInfo = $this->cleanHtml($phpInfo); + + return $phpInfo; + } + + private function replaceSensitiveInformation(string $phpInfo): string + { + return str_replace([ + getenv('AUTH_TOKEN'), + getenv('USER_TOKEN'), + getenv('USER_PWD_SALT'), + ], '&lt;hidden&gt;', $phpInfo); + } + + /** + * This method unwrap the information from the body tag, removes zend and php logos and fixes sizes + * for presentation purposes + * + * We might want to do it proper at some point using DOM methods + */ + private function cleanHtml(string $phpInfo): string + { + preg_match('!<body.*?>(.*)</body>!ims', $phpInfo, $m); + + $m[1] = preg_replace('!<a href="http://www.php.net/"><img.*?></a>!ims', '', $m[1]); + $m[1] = preg_replace('!<a href="http://www.zend.com/"><img.*?></a>!ims', '', $m[1]); + $m[1] = str_replace(' width="600"', ' width="80%"', $m[1]); + + return $m[1]; + } +} diff --git a/src/Repository/ReasonRepository.php b/src/Repository/ReasonRepository.php index fd4f411..b33d60a 100644 --- a/src/Repository/ReasonRepository.php +++ b/src/Repository/ReasonRepository.php @@ -52,4 +52,14 @@ class ReasonRepository return [$resolves, $variations]; } + + /** + * @return array<int,array<string,mixed>> + */ + public function findAll(): array + { + $sql = 'SELECT * FROM bugdb_resolves'; + + return $this->dbh->query($sql)->fetchAll(); + } } diff --git a/templates/pages/admin/database_status.php b/templates/pages/admin/database_status.php new file mode 100644 index 0000000..a1237ce --- /dev/null +++ b/templates/pages/admin/database_status.php @@ -0,0 +1,75 @@ +<?php $this->extends('layout.php', ['title' => 'Admin :: Database status']) ?> + +<?php $this->start('content') ?> + +<?php $this->include('pages/admin/menu.php', ['action' => $action]); ?> + +<p>Running MySQL <b><?= $this->e($mysqlVersion); ?></b></p> + +<h3>Number of rows:</h3> + +<table> + <tbody> + <tr class="bug_header"> + <th>Table</th> + <th>Rows</th> + </tr> + <?php foreach ($numberOfRowsPerTable as $tableName => $numberOfRows): ?> + <tr> + <td class="bug_bg0"><?= $this->e($tableName); ?></td> + <td class="bug_bg1"><?= $this->e($numberOfRows); ?></td> + </tr> + <?php endforeach ?> + </tbody> +</table> + +<h3>Table status:</h3> + +<table> + <tbody> + <tr class="bug_header"> + <th>Name</th> + <th>Engine</th> + <th>Version</th> + <th>Row_format</th> + <th>Rows</th> + <th>Avg_row_length</th> + <th>Data_length</th> + <th>Max_data_length</th> + <th>Index_length</th> + <th>Data_free</th> + <th>Auto_increment</th> + <th>Create_time</th> + <th>Update_time</th> + <th>Check_time</th> + <th>Collation</th> + <th>Checksum</th> + <th>Create_options</th> + <th>Comment</th> + </tr> + <?php foreach ($statusPerTable as $tableStatus): ?> + <tr> + <td class="bug_bg0"><?= $this->e($tableStatus['Name']); ?></td> + <td class="bug_bg1"><?= $this->e($tableStatus['Engine']); ?></td> + <td class="bug_bg0"><?= $tableStatus['Version']; ?></td> + <td class="bug_bg1"><?= $this->e($tableStatus['Row_format']); ?></td> + <td class="bug_bg0"><?= $tableStatus['Rows']; ?></td> + <td class="bug_bg1"><?= $tableStatus['Avg_row_length']; ?></td> + <td class="bug_bg0"><?= $tableStatus['Data_length']; ?></td> + <td class="bug_bg1"><?= $tableStatus['Max_data_length']; ?></td> + <td class="bug_bg0"><?= $tableStatus['Index_length']; ?></td> + <td class="bug_bg1"><?= $tableStatus['Data_free']; ?></td> + <td class="bug_bg0"><?= $tableStatus['Auto_increment']; ?></td> + <td class="bug_bg1"><?= $this->e($tableStatus['Create_time']); ?></td> + <td class="bug_bg0"><?= $this->e($tableStatus['Update_time']); ?></td> + <td class="bug_bg1"><?php echo $tableStatus['Check_time'] ? $this->e($tableStatus['Check_time']) : ''; ?></td> + <td class="bug_bg0"><?= $this->e($tableStatus['Collation']); ?></td> + <td class="bug_bg1"><?php echo $tableStatus['Checksum'] ? $this->e($tableStatus['Checksum']) : ''; ?></td> + <td class="bug_bg0"><?= $this->e($tableStatus['Create_options']); ?></td> + <td class="bug_bg1"><?= $this->e($tableStatus['Comment']); ?></td> + </tr> + <?php endforeach ?> + </tbody> +</table> + +<?php $this->end('content') ?> diff --git a/templates/pages/admin/mailing_lists.php b/templates/pages/admin/mailing_lists.php new file mode 100644 index 0000000..e0e307d --- /dev/null +++ b/templates/pages/admin/mailing_lists.php @@ -0,0 +1,18 @@ +<?php $this->extends('layout.php', ['title' => 'Admin :: Package mailing lists']) ?> + +<?php $this->start('content') ?> + +<?php $this->include('pages/admin/menu.php', ['action' => $action]); ?> + +<dl> + <?php foreach ($lists as $list): ?> + <dt><?= $this->e($list['name']); ?>: </dt> + <dd> + <a href="mailto:<?= $this->noHtml($list['list_email']); ?>"> + <?= $this->e($list['list_email']); ?> + </a> + </dd> + <?php endforeach ?> +</dl> + +<?php $this->end('content') ?> diff --git a/templates/pages/admin/menu.php b/templates/pages/admin/menu.php new file mode 100644 index 0000000..7d716f7 --- /dev/null +++ b/templates/pages/admin/menu.php @@ -0,0 +1,17 @@ +<p> + <a href="/admin/?action=phpinfo" <?= ('phpinfo' === $action) ? 'class="active"' : ''; ?>> + phpinfo() + </a> + | + <a href="/admin/?action=list_lists" <?= ('list_lists' === $action) ? 'class="active"' : ''; ?>> + Package mailing lists + </a> + | + <a href="/admin/?action=list_responses" <?= ('list_responses' === $action) ? 'class="active"' : ''; ?>> + Quick fix responses + </a> + | + <a href="/admin/?action=mysql" <?= ('mysql' === $action) ? 'class="active"' : ''; ?>> + Database status + </a> +</p> diff --git a/templates/pages/admin/phpinfo.php b/templates/pages/admin/phpinfo.php new file mode 100644 index 0000000..c04b33e --- /dev/null +++ b/templates/pages/admin/phpinfo.php @@ -0,0 +1,9 @@ +<?php $this->extends('layout.php', ['title' => 'Admin :: phpinfo()']) ?> + +<?php $this->start('content') ?> + +<?php $this->include('pages/admin/menu.php', ['action' => $action]); ?> + +<?= $info; ?> + +<?php $this->end('content') ?> diff --git a/templates/pages/admin/quick_responses.php b/templates/pages/admin/quick_responses.php new file mode 100644 index 0000000..64dde7a --- /dev/null +++ b/templates/pages/admin/quick_responses.php @@ -0,0 +1,38 @@ +<?php $this->extends('layout.php', ['title' => 'Admin :: Quick fix responses']) ?> + +<?php $this->start('content') ?> + +<?php $this->include('pages/admin/menu.php', ['action' => $action]); ?> + +<h3>List Responses</h3> + +<table> + <tbody> + <tr class="bug_header"> + <th>id</th> + <th>name</th> + <th>status</th> + <th>title</th> + <th>message</th> + <th>project</th> + <th>package_name</th> + <th>webonly</th> + </tr> + <?php foreach ($responses as $response): ?> + <tr> + <td class="bug_bg0"><?= $response['id']; ?></td> + <td class="bug_bg1"><?= $this->e($response['name']); ?></td> + <td class="bug_bg0"><?php echo $response['status'] ? $this->e($response['status']) : ''; ?></td> + <td class="bug_bg1"><?= $this->e($response['title']); ?></td> + <td class="bug_bg0 tbl-row-message"> + <?= nl2br($this->e($response['message'])); ?> + </td> + <td class="bug_bg1"><?= $this->e($response['project']); ?></td> + <td class="bug_bg0"><?php echo $response['package_name'] ? $this->e($response['package_name']) : ''; ?></td> + <td class="bug_bg1"><?= $response['webonly']; ?></td> + </tr> + <?php endforeach ?> + </tbody> +</table> + +<?php $this->end('content') ?> diff --git a/www/admin/index.php b/www/admin/index.php index 3d3affd..43dd0b6 100644 --- a/www/admin/index.php +++ b/www/admin/index.php @@ -1,11 +1,15 @@ <?php +use App\Repository\DatabaseStatusRepository; use App\Repository\PackageRepository; +use App\Repository\PhpInfoRepository; +use App\Repository\ReasonRepository; +// Application bootstrap require_once '../../include/prepend.php'; -session_start(); -bugs_authenticate($user, $pw, $logged_in, $user_flags); +// Authentication +require_once __DIR__.'/../../include/auth.php'; if (!$logged_in) { response_header("Bugs admin suite"); @@ -13,102 +17,37 @@ if (!$logged_in) { exit; } -$actions = [ - 'phpinfo' => 'phpinfo()', - 'list_lists' => 'Package mailing lists', - 'list_responses' => 'Quick fix responses', - 'mysql' => 'Database status', -]; - -$action = !empty($_GET['action']) && isset($actions[$_GET['action']]) ? $_GET['action'] : 'list_lists'; - -response_header("Bugs admin suite"); -inline_content_menu('/admin/', $action, $actions); - -if ($action === 'phpinfo') { - ob_start(); - phpinfo(); - - $phpinfo = ob_get_clean(); - - // Attempt to hide certain ENV vars - $vars = [ - getenv('AUTH_TOKEN'), - getenv('USER_TOKEN'), - getenv('USER_PWD_SALT') - ]; - - $phpinfo = str_replace($vars, '&lt;hidden&gt;', $phpinfo); - - // Semi stolen from php-web - $m = []; - - preg_match('!<body.*?>(.*)</body>!ims', $phpinfo, $m); - - $m[1] = preg_replace('!<a href="http://www.php.net/"><img.*?></a>!ims', '', $m[1]); - $m[1] = preg_replace('!<a href="http://www.zend.com/"><img.*?></a>!ims', '', $m[1]); - $m[1] = str_replace(' width="600"', ' width="80%"', $m[1]); - - echo $m[1]; - -} elseif ($action === 'list_lists') { - echo "<dl>\n"; - foreach ($container->get(PackageRepository::class)->findLists() as $row) { - echo "<dt>", $row['name'], ": </dt>\n<dd>", mailto_list(explode(',', $row['list_email'])), "</dd>\n"; - } - echo "</dl>\n"; -} elseif ($action === 'list_responses') { - - $res = $dbh->query(" - SELECT * - FROM bugdb_resolves - "); - - echo "<h3>List Responses</h3>\n"; - - $rows = []; - while ($row = $res->fetch()) { - // This is ugly but works (tm) - $row['message'] = nl2br($row['message']); - - $rows[] = $row; - } - - admin_table_dynamic($rows); -} elseif ($action === 'mysql') { - $res = $dbh->query("SHOW TABLES"); - - $sql = "SELECT version() mysql_version\n"; - - while ($row = $res->fetch(\PDO::FETCH_NUM)) { - $table = $row[0]; - $sql .= "\t, (SELECT COUNT(*) FROM `$table`) `cnt_$table`\n"; - } - - $res = $dbh->query($sql); - $row = $res->fetch(); - - echo "<p>Running MySQL <b>".$row['mysql_version']."</b></p>"; - unset($row['mysql_version']); - - echo "<h3>Number of rows:</h3>\n"; - - $rows = []; - - foreach($row as $key => $value) { - $rows[] = [str_replace('cnt_', '', $key), $value]; - } - - admin_table_static(['Table', 'Rows'], $rows); - - $rows = []; - $res = $dbh->query("SHOW TABLE STATUS"); - echo "<h3>Table status:</h3>\n"; - while ($row = $res->fetch()) { - $rows[] = $row; - } - - admin_table_dynamic($rows); +$action = $_GET['action'] ?? 'list_lists'; + +switch ($action) { + case 'phpinfo': + echo $template->render('pages/admin/phpinfo.php', [ + 'action' => $action, + 'info' => $container->get(PhpInfoRepository::class)->getInfo(), + ]); + break; + + case 'list_responses': + echo $template->render('pages/admin/quick_responses.php', [ + 'action' => $action, + 'responses' => $container->get(ReasonRepository::class)->findAll(), + ]); + break; + + case 'mysql': + echo $template->render('pages/admin/database_status.php', [ + 'action' => $action, + 'mysqlVersion' => $container->get(DatabaseStatusRepository::class)->getMysqlVersion(), + 'numberOfRowsPerTable' => $container->get(DatabaseStatusRepository::class)->getNumberOfRowsInTables(), + 'statusPerTable' => $container->get(DatabaseStatusRepository::class)->getStatusOfTables(), + ]); + break; + + case 'list_lists': + default: + echo $template->render('pages/admin/mailing_lists.php', [ + 'action' => $action, + 'lists' => $container->get(PackageRepository::class)->findLists(), + ]); + break; } - -response_footer(); diff --git a/www/css/style.css b/www/css/style.css index a9b07b5..743ea14 100644 --- a/www/css/style.css +++ b/www/css/style.css @@ -676,6 +676,13 @@ td.tbl-row-message { text-align: left; } +/* menu */ +a.active { + font-weight: bold; + color: black; + text-decoration: none; +} + /* phpinfo() */ div.center { margin: 0px auto;
« previous php.webmaster (#28068) next »