1+ <?php
2+
3+ namespace Arris \Database ;
4+
5+ use InvalidArgumentException ;
6+
7+ class Tables implements \ArrayAccess, TablesInterface
8+ {
9+ private string $ prefix ;
10+ private array $ tables ;
11+ private array $ havePrefix ;
12+ private array $ haveAlias ;
13+
14+ /**
15+ * Инициализируется репозиторий таблиц
16+ *
17+ * @param string $prefix
18+ * @param array $tables
19+ * @param array $havePrefix
20+ * @param array $haveAlias
21+ */
22+ public function __construct (
23+ string $ prefix = '' ,
24+ array $ tables = [],
25+ array $ havePrefix = [],
26+ array $ haveAlias = []
27+ ) {
28+ $ this ->prefix = $ prefix ;
29+ $ this ->tables = $ tables ;
30+ $ this ->havePrefix = $ havePrefix ;
31+ $ this ->haveAlias = $ haveAlias ;
32+
33+ // Если в конструктор переданы строки (не ассоциативный массив),
34+ // то каждая строка становится и ключом, и значением
35+ foreach ($ tables as $ key => $ value ) {
36+ if (is_int ($ key )) {
37+ // Это скалярный массив типа ['a', 'b']
38+ $ this ->addTable ($ value , $ value );
39+ } else {
40+ // Это ассоциативный массив типа ['users' => 'users_table']
41+ $ this ->addTable ($ key , $ value );
42+ }
43+ }
44+ }
45+
46+ /**
47+ * Добавляет таблицу в репозиторий
48+ *
49+ * @param string $key Ключ для обращения к таблице
50+ * @param string|null $tableName Имя таблицы в БД
51+ * @param string|null $replacement Если задан, будет использовано вместо tableName
52+ * @param bool $withPrefix Добавлять ли префикс (игнорируется если задан replacement)
53+ * @param string|null $alias Алиас для таблицы
54+ * @return Tables
55+ */
56+ public function addTable (
57+ string $ key ,
58+ ?string $ tableName = null ,
59+ ?string $ replacement = null ,
60+ bool $ withPrefix = false ,
61+ ?string $ alias = null
62+ ): self {
63+ if (empty ($ tableName )) {
64+ $ tableName = $ key ;
65+ }
66+
67+ $ this ->tables [$ key ] = $ tableName ;
68+
69+ if ($ replacement !== null ) {
70+ $ this ->havePrefix [$ key ] = $ replacement ;
71+ } elseif ($ withPrefix ) {
72+ $ this ->havePrefix [] = $ key ;
73+ }
74+
75+ if ($ alias !== null ) {
76+ $ this ->haveAlias [$ key ] = $ alias ;
77+ }
78+
79+ return $ this ; // Для цепочечных вызовов
80+ }
81+
82+ //
83+
84+ /**
85+ * Проверяет, существует ли ключ
86+ * (таблица в репозитории) *
87+ *
88+ * @param mixed $offset
89+ * @return bool
90+ */
91+ public function offsetExists (mixed $ offset ): bool
92+ {
93+ return isset ($ this ->tables [$ offset ]);
94+ }
95+
96+ /**
97+ * Возвращает значение по ключу с учетом логики префиксов и алиасов
98+ *
99+ * @param mixed $offset
100+ * @return string
101+ */
102+ public function offsetGet (mixed $ offset ): string
103+ {
104+ if (!$ this ->offsetExists ($ offset )) {
105+ throw new InvalidArgumentException ("Table ' $ offset' not found. " );
106+ }
107+
108+ $ tableName = $ this ->tables [$ offset ];
109+ $ result = $ tableName ;
110+
111+ // Если аргумент есть в таблице замен - подставляем значение из have_prefix
112+ if (isset ($ this ->havePrefix [$ offset ])) {
113+ $ result = $ this ->havePrefix [$ offset ];
114+ }
115+ // Иначе если есть в таблице have_prefix - ставим префикс
116+ elseif (in_array ($ offset , $ this ->havePrefix , true )) {
117+ $ result = $ this ->prefix . $ tableName ;
118+ }
119+ // Иначе ставим значение ключа (уже в $tableName)
120+
121+ // Если аргумент есть в таблице have_alias - добавляем AS alias
122+ if (isset ($ this ->haveAlias [$ offset ])) {
123+ $ alias = $ this ->haveAlias [$ offset ];
124+ $ result .= ' AS ' . $ alias ;
125+ }
126+
127+ return $ result ;
128+ }
129+
130+ /**
131+ * Устанавливает значение
132+ *
133+ * @param mixed $offset
134+ * @param mixed $value
135+ * @return void
136+ */
137+ public function offsetSet (mixed $ offset , mixed $ value ): void
138+ {
139+ if (is_null ($ offset )) {
140+ $ this ->tables [] = $ value ;
141+ } else {
142+ $ this ->tables [$ offset ] = $ value ;
143+ }
144+ }
145+
146+ /**
147+ * Удаляет значение по ключу
148+ *
149+ * @param mixed $offset
150+ * @return void
151+ */
152+ public function offsetUnset (mixed $ offset ): void
153+ {
154+ unset($ this ->tables [$ offset ]);
155+ unset($ this ->havePrefix [$ offset ]);
156+ unset($ this ->haveAlias [$ offset ]);
157+
158+ // Удаляем из массива скалярных значений, если есть
159+ $ key = array_search ($ offset , $ this ->havePrefix , true );
160+ if ($ key !== false ) {
161+ unset($ this ->havePrefix [$ key ]);
162+ }
163+ }
164+
165+
166+ }
167+
168+ # -eof- #
0 commit comments