Issues (28)

src/Admin/Admin.php (6 issues)

1
<?php
2
3
namespace Lagdo\DbAdmin\Admin;
4
5
use Lagdo\DbAdmin\Driver\Utils\Utils;
6
use Lagdo\DbAdmin\Driver\DriverInterface;
7
use Lagdo\DbAdmin\Driver\Entity\TableEntity;
8
use Lagdo\DbAdmin\Driver\Entity\TableFieldEntity;
9
10
use function max;
11
use function preg_match;
12
use function strlen;
13
14
class Admin
15
{
16
    use Traits\AdminTrait;
0 ignored issues
show
The trait Lagdo\DbAdmin\Admin\Traits\AdminTrait requires the property $type which is not provided by Lagdo\DbAdmin\Admin\Admin.
Loading history...
17
    use Traits\SelectTrait;
0 ignored issues
show
The trait Lagdo\DbAdmin\Admin\Traits\SelectTrait requires some properties which are not provided by Lagdo\DbAdmin\Admin\Admin: $input, $values
Loading history...
18
    use Traits\QueryInputTrait;
0 ignored issues
show
The trait Lagdo\DbAdmin\Admin\Traits\QueryInputTrait requires some properties which are not provided by Lagdo\DbAdmin\Admin\Admin: $name, $onUpdate, $type, $autoIncrement
Loading history...
19
    use Traits\SelectInputTrait;
0 ignored issues
show
The trait Lagdo\DbAdmin\Admin\Traits\SelectInputTrait requires some properties which are not provided by Lagdo\DbAdmin\Admin\Admin: $columns, $values, $type, $input
Loading history...
20
    use Traits\QueryTrait;
0 ignored issues
show
The trait Lagdo\DbAdmin\Admin\Traits\QueryTrait requires some properties which are not provided by Lagdo\DbAdmin\Admin\Admin: $trans, $null, $values, $type, $autoIncrement, $input
Loading history...
21
    use Traits\DumpTrait;
0 ignored issues
show
The trait Lagdo\DbAdmin\Admin\Traits\DumpTrait requires the property $trans which is not provided by Lagdo\DbAdmin\Admin\Admin.
Loading history...
22
23
    /**
24
     * @var DriverInterface
25
     */
26
    public $driver;
27
28
    /**
29
     * @var Utils
30
     */
31
    protected $utils;
32
33
    /**
34
     * The constructor
35
     *
36
     * @param DriverInterface $driver
37
     * @param Utils $utils
38
     */
39
    public function __construct(DriverInterface $driver, Utils $utils)
40
    {
41
        $this->driver = $driver;
42
        $this->utils = $utils;
43
    }
44
45
    /**
46
     * Name in title and navigation
47
     *
48
     * @return string
49
     */
50
    public function name(): string
51
    {
52
        return '<span class="jaxon_dbadmin_name">Jaxon DbAdmin</span>';
53
    }
54
55
    /**
56
     * Get a target="_blank" attribute
57
     *
58
     * @return string
59
     */
60
    public function blankTarget(): string
61
    {
62
        return ' target="_blank" rel="noreferrer noopener"';
63
    }
64
65
    /**
66
     * Get escaped error message
67
     *
68
     * @return string
69
     */
70
    public function error(): string
71
    {
72
        return $this->utils->str->html($this->driver->error());
73
    }
74
75
    /**
76
     * Find unique identifier of a row
77
     *
78
     * @param array $row
79
     * @param array $indexes Result of indexes()
80
     *
81
     * @return array
82
     */
83
    public function uniqueIds(array $row, array $indexes): array
84
    {
85
        foreach ($indexes as $index) {
86
            if (preg_match('~PRIMARY|UNIQUE~', $index->type)) {
87
                $ids = [];
88
                foreach ($index->columns as $key) {
89
                    if (!isset($row[$key])) { // NULL is ambiguous
90
                        continue 2;
91
                    }
92
                    $ids[$key] = $row[$key];
93
                }
94
                return $ids;
95
            }
96
        }
97
        return [];
98
    }
99
100
    /**
101
     * Table caption used in navigation and headings
102
     *
103
     * @param TableEntity $table
104
     *
105
     * @return string
106
     */
107
    public function tableName(TableEntity $table): string
108
    {
109
        return $this->utils->str->html($table->name);
110
    }
111
112
    /**
113
     * Field caption used in select and edit
114
     *
115
     * @param TableFieldEntity $field Single field returned from fields()
116
     * @param int $order Order of column in select
117
     *
118
     * @return string
119
     */
120
    public function fieldName(TableFieldEntity $field, /** @scrutinizer ignore-unused */ int $order = 0): string
121
    {
122
        return '<span title="' . $this->utils->str->html($field->fullType) . '">' . $this->utils->str->html($field->name) . '</span>';
123
    }
124
125
    /**
126
     * Value printed in select table
127
     *
128
     * @param mixed $value HTML-escaped value to print
129
     * @param string $type Field type
130
     * @param mixed $original Original value before escaping
131
     *
132
     * @return string
133
     */
134
    private function getSelectFieldValue($value, string $type, $original): string
135
    {
136
        if ($value === null) {
137
            return '<i>NULL</i>';
138
        }
139
        if (preg_match('~char|binary|boolean~', $type) && !preg_match('~var~', $type)) {
140
            return "<code>$value</code>";
141
        }
142
        if (preg_match('~blob|bytea|raw|file~', $type) && !$this->utils->str->isUtf8($value)) {
143
            return '<i>' . $this->utils->trans->lang('%d byte(s)', strlen($original)) . '</i>';
144
        }
145
        if (preg_match('~json~', $type)) {
146
            return "<code>$value</code>";
147
        }
148
        if ($this->isMail($value)) {
149
            return '<a href="' . $this->utils->str->html("mailto:$value") . '">' . $value . '</a>';
150
        }
151
        elseif ($this->isUrl($value)) {
152
            // IE 11 and all modern browsers hide referrer
153
            return '<a href="' . $this->utils->str->html($value) . '"' . $this->blankTarget() . '>' . $value . '</a>';
154
        }
155
        return $value;
156
    }
157
158
    /**
159
     * Format value to use in select
160
     *
161
     * @param TableFieldEntity $field
162
     * @param mixed $value
163
     * @param int|string|null $textLength
164
     *
165
     * @return string
166
     */
167
    public function selectValue(TableFieldEntity $field, $value, $textLength): string
168
    {
169
        // if (\is_array($value)) {
170
        //     $expression = '';
171
        //     foreach ($value as $k => $v) {
172
        //         $expression .= '<tr>' . ($value != \array_values($value) ?
173
        //             '<th>' . $this->utils->str->html($k) :
174
        //             '') . '<td>' . $this->selectValue($field, $v, $textLength);
175
        //     }
176
        //     return "<table cellspacing='0'>$expression</table>";
177
        // }
178
        // if (!$link) {
179
        //     $link = $this->selectLink($value, $field);
180
        // }
181
        $expression = $value;
182
        if (!empty($expression)) {
183
            if (!$this->utils->str->isUtf8($expression)) {
184
                $expression = "\0"; // htmlspecialchars of binary data returns an empty string
185
            } elseif ($textLength != '' && $this->isShortable($field)) {
186
                // usage of LEFT() would reduce traffic but complicate query -
187
                // expected average speedup: .001 s VS .01 s on local network
188
                $expression = $this->utils->str->shortenUtf8($expression, max(0, +$textLength));
189
            } else {
190
                $expression = $this->utils->str->html($expression);
191
            }
192
        }
193
        return $this->getSelectFieldValue($expression, $field->type, $value);
194
    }
195
}
196