Commit:    9531cd154db3a5e41b6e806226e9e371d2699f52
Author:    Pieter Hordijk <[email protected]>         Wed, 22 May 2019 
21:06:46 +0300
Committer: Peter Kokot <[email protected]>      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;
-- 
PHP Webmaster List Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to