1<?php
2
3declare(strict_types=1);
4
5namespace PhpMyAdmin\Plugins\Export\Helpers;
6
7use PhpMyAdmin\Plugins\Export\ExportCodegen;
8use const ENT_COMPAT;
9use function htmlspecialchars;
10use function mb_strpos;
11use function mb_substr;
12use function str_replace;
13use function strlen;
14use function trim;
15
16/**
17 * PhpMyAdmin\Plugins\Export\Helpers\TableProperty class
18 */
19class TableProperty
20{
21    /**
22     * Name
23     *
24     * @var string
25     */
26    public $name;
27
28    /**
29     * Type
30     *
31     * @var string
32     */
33    public $type;
34
35    /**
36     * Whether the key is nullable or not
37     *
38     * @var string
39     */
40    public $nullable;
41
42    /**
43     * The key
44     *
45     * @var string
46     */
47    public $key;
48
49    /**
50     * Default value
51     *
52     * @var mixed
53     */
54    public $defaultValue;
55
56    /**
57     * Extension
58     *
59     * @var string
60     */
61    public $ext;
62
63    /**
64     * @param array $row table row
65     */
66    public function __construct(array $row)
67    {
68        $this->name = trim((string) $row[0]);
69        $this->type = trim((string) $row[1]);
70        $this->nullable = trim((string) $row[2]);
71        $this->key = trim((string) $row[3]);
72        $this->defaultValue = trim((string) $row[4]);
73        $this->ext = trim((string) $row[5]);
74    }
75
76    /**
77     * Gets the pure type
78     *
79     * @return string type
80     */
81    public function getPureType()
82    {
83        $pos = (int) mb_strpos($this->type, '(');
84        if ($pos > 0) {
85            return mb_substr($this->type, 0, $pos);
86        }
87
88        return $this->type;
89    }
90
91    /**
92     * Tells whether the key is null or not
93     *
94     * @return string true if the key is not null, false otherwise
95     */
96    public function isNotNull()
97    {
98        return $this->nullable === 'NO' ? 'true' : 'false';
99    }
100
101    /**
102     * Tells whether the key is unique or not
103     *
104     * @return string "true" if the key is unique, "false" otherwise
105     */
106    public function isUnique(): string
107    {
108        return $this->key === 'PRI' || $this->key === 'UNI' ? 'true' : 'false';
109    }
110
111    /**
112     * Gets the .NET primitive type
113     *
114     * @return string type
115     */
116    public function getDotNetPrimitiveType()
117    {
118        if (mb_strpos($this->type, 'int') === 0) {
119            return 'int';
120        }
121        if (mb_strpos($this->type, 'longtext') === 0) {
122            return 'string';
123        }
124        if (mb_strpos($this->type, 'long') === 0) {
125            return 'long';
126        }
127        if (mb_strpos($this->type, 'char') === 0) {
128            return 'string';
129        }
130        if (mb_strpos($this->type, 'varchar') === 0) {
131            return 'string';
132        }
133        if (mb_strpos($this->type, 'text') === 0) {
134            return 'string';
135        }
136        if (mb_strpos($this->type, 'tinyint') === 0) {
137            return 'bool';
138        }
139        if (mb_strpos($this->type, 'datetime') === 0) {
140            return 'DateTime';
141        }
142
143        return 'unknown';
144    }
145
146    /**
147     * Gets the .NET object type
148     *
149     * @return string type
150     */
151    public function getDotNetObjectType()
152    {
153        if (mb_strpos($this->type, 'int') === 0) {
154            return 'Int32';
155        }
156        if (mb_strpos($this->type, 'longtext') === 0) {
157            return 'String';
158        }
159        if (mb_strpos($this->type, 'long') === 0) {
160            return 'Long';
161        }
162        if (mb_strpos($this->type, 'char') === 0) {
163            return 'String';
164        }
165        if (mb_strpos($this->type, 'varchar') === 0) {
166            return 'String';
167        }
168        if (mb_strpos($this->type, 'text') === 0) {
169            return 'String';
170        }
171        if (mb_strpos($this->type, 'tinyint') === 0) {
172            return 'Boolean';
173        }
174        if (mb_strpos($this->type, 'datetime') === 0) {
175            return 'DateTime';
176        }
177
178        return 'Unknown';
179    }
180
181    /**
182     * Gets the index name
183     *
184     * @return string containing the name of the index
185     */
186    public function getIndexName()
187    {
188        if (strlen($this->key) > 0) {
189            return 'index="'
190                . htmlspecialchars($this->name, ENT_COMPAT, 'UTF-8')
191                . '"';
192        }
193
194        return '';
195    }
196
197    /**
198     * Tells whether the key is primary or not
199     *
200     * @return bool true if the key is primary, false otherwise
201     */
202    public function isPK(): bool
203    {
204        return $this->key === 'PRI';
205    }
206
207    /**
208     * Formats a string for C#
209     *
210     * @param string $text string to be formatted
211     *
212     * @return string formatted text
213     */
214    public function formatCs($text)
215    {
216        $text = str_replace(
217            '#name#',
218            ExportCodegen::cgMakeIdentifier($this->name, false),
219            $text
220        );
221
222        return $this->format($text);
223    }
224
225    /**
226     * Formats a string for XML
227     *
228     * @param string $text string to be formatted
229     *
230     * @return string formatted text
231     */
232    public function formatXml($text)
233    {
234        $text = str_replace(
235            [
236                '#name#',
237                '#indexName#',
238            ],
239            [
240                htmlspecialchars($this->name, ENT_COMPAT, 'UTF-8'),
241                $this->getIndexName(),
242            ],
243            $text
244        );
245
246        return $this->format($text);
247    }
248
249    /**
250     * Formats a string
251     *
252     * @param string $text string to be formatted
253     *
254     * @return string formatted text
255     */
256    public function format($text)
257    {
258        $text = str_replace(
259            [
260                '#ucfirstName#',
261                '#dotNetPrimitiveType#',
262                '#dotNetObjectType#',
263                '#type#',
264                '#notNull#',
265                '#unique#',
266            ],
267            [
268                ExportCodegen::cgMakeIdentifier($this->name),
269                $this->getDotNetPrimitiveType(),
270                $this->getDotNetObjectType(),
271                $this->getPureType(),
272                $this->isNotNull(),
273                $this->isUnique(),
274            ],
275            $text
276        );
277
278        return $text;
279    }
280}
281