PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / helpers / libraries / language / table.php
vikappointments / site / helpers / libraries / language Last commit date
tables 2 days ago index.html 2 days ago table.php 2 days ago translator.php 2 days ago
table.php
387 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 /**
15 * Concrete representation of a translatable table.
16 *
17 * @since 1.7
18 */
19 class VAPLanguageTable
20 {
21 /**
22 * The XML instance.
23 *
24 * @var SimpleXMLElement
25 */
26 protected $xml;
27
28 /**
29 * Translations pool.
30 *
31 * @var array
32 */
33 protected $data = array();
34
35 /**
36 * Class constructor.
37 *
38 * @param mixed $node Either the file path of the XML to load or
39 * a XML string or a SimpleXMLElement instance.
40 */
41 public function __construct($node)
42 {
43 if ($node instanceof SimpleXMLElement)
44 {
45 // assign XML instance
46 $this->xml = $node;
47 }
48 else if (is_file($node))
49 {
50 // load XML from file
51 $this->xml = @simplexml_load_file($node);
52 }
53 else
54 {
55 // load XML from given string
56 $this->xml = @simplexml_load_string($node);
57 }
58
59 // check if we received a string
60 if (!$this->xml)
61 {
62 throw new Exception(sprintf('Unable to parse the translation driver: %s', (string) $node), 500);
63 }
64 }
65
66 /**
67 * Sets the translation for the given record.
68 * The translation must be an object containing the
69 * ID property to identify the related record.
70 *
71 * @param array|object $translation The translated record.
72 *
73 * @return self This object to support chaining.
74 */
75 public function setTranslation($translation)
76 {
77 $translation = (object) $translation;
78
79 // make sure the ID and langtag are available
80 if (!empty($translation->id) && !empty($translation->langtag))
81 {
82 if (!isset($this->data[$translation->id]))
83 {
84 $this->data[$translation->id] = array();
85 }
86
87 $this->data[$translation->id][strtolower($translation->langtag)] = $translation;
88 }
89
90 return $this;
91 }
92
93 /**
94 * Returns the translation for the given record.
95 *
96 * @param integer $id The translated product ID.
97 * @param mixed $tag If specified, the translation must
98 * match the given one.
99 *
100 * @return mixed The translation if exists, null otherwise.
101 */
102 public function getTranslation($id, $tag = null)
103 {
104 if ($this->hasTranslation($id, $tag))
105 {
106 if ($tag)
107 {
108 // return specific tag translation
109 return $this->data[$id][strtolower($tag)];
110 }
111
112 // return all available translations
113 return $this->data[$id];
114 }
115
116 return null;
117 }
118
119 /**
120 * Checks whether the given product owns a translation.
121 *
122 * @param integer $id The product ID.
123 * @param mixed $tag If specified, the translation must
124 * match the given one.
125 *
126 * @return boolen True if exists, false otherwise.
127 */
128 public function hasTranslation($id, $tag = null)
129 {
130 if (!isset($this->data[$id]))
131 {
132 // missing translation
133 return false;
134 }
135
136 // if tag filter is specified but the translation doesn't
137 // match the given language, return false
138 if ($tag && !isset($this->data[$id][strtolower($tag)]))
139 {
140 return false;
141 }
142
143 return true;
144 }
145
146 /**
147 * Returns the table identifier.
148 *
149 * @return string
150 */
151 public function getID()
152 {
153 return (string) $this->xml->attributes()->id;
154 }
155
156 /**
157 * Returns the table name.
158 *
159 * @return string
160 */
161 public function getTableName()
162 {
163 return (string) $this->xml->attributes()->table;
164 }
165
166 /**
167 * Returns the original table linked to this translation table.
168 *
169 * @return string
170 */
171 public function getLinkedTable()
172 {
173 $link = (string) $this->xml->attributes()->link;
174
175 if (!$link)
176 {
177 // link not provided, use standard notation
178 $link = preg_replace("/#__vikappointments_lang_/i", '#__vikappointments_', $this->getTableName());
179 }
180
181 return $link;
182 }
183
184 /**
185 * Returns a list of supported columns.
186 *
187 * @return array
188 */
189 public function getColumns()
190 {
191 return $this->searchColumns('*');
192 }
193
194 /**
195 * Returns the primary key column.
196 *
197 * @return string The PK column.
198 */
199 public function getPrimaryKey()
200 {
201 $columns = $this->searchColumns('pk');
202
203 if ($columns)
204 {
205 return $columns[0];
206 }
207
208 // fallback to ID
209 return 'id';
210 }
211
212 /**
213 * Returns the primary key column of the linked table.
214 *
215 * @return string The PK column.
216 */
217 public function getLinkedPrimaryKey()
218 {
219 // search for LINK attribute in FK column
220 $columns = array_filter($this->searchColumns('fk', 'rule', 'link'));
221
222 if ($columns)
223 {
224 return $columns[0];
225 }
226
227 // fallback to ID
228 return 'id';
229 }
230
231 /**
232 * Returns the foreign key column linked to the original table.
233 *
234 * @return string The FK column if exists.
235 *
236 * @throws Exception
237 */
238 public function getForeignKey()
239 {
240 $columns = $this->searchColumns('fk');
241
242 if (!$columns)
243 {
244 throw new Exception(sprintf('Missing foreign key for [%s] table', __CLASS__), 400);
245 }
246
247 return $columns[0];
248 }
249
250 /**
251 * Returns the XML id of the parent table.
252 *
253 * @return mixed The table ID if exists, false otherwise.
254 */
255 public function getParentTable()
256 {
257 $columns = $this->searchColumns('parent', 'rule', 'link');
258
259 if ($columns)
260 {
261 return $columns[0];
262 }
263
264 return false;
265 }
266
267 /**
268 * Returns the foreign key column linked to the parent table.
269 *
270 * @return mixed The FK column if exists, false otherwise.
271 */
272 public function getParentKey()
273 {
274 $columns = $this->searchColumns('parent');
275
276 if ($columns)
277 {
278 return $columns[0];
279 }
280
281 return false;
282 }
283
284 /**
285 * Returns the foreign key column linked to the parent table
286 * of the original table.
287 *
288 * @return mixed The FK column if exists, false otherwise.
289 */
290 public function getLinkedParentKey()
291 {
292 $columns = $this->searchColumns('parent', 'rule', 'original');
293
294 if ($columns)
295 {
296 return $columns[0];
297 }
298
299 return false;
300 }
301
302 /**
303 * Returns the language tag column.
304 *
305 * @return string The lang column if exists.
306 *
307 * @throws Exception
308 */
309 public function getLangColumn()
310 {
311 $columns = $this->searchColumns('language');
312
313 if (!$columns)
314 {
315 throw new Exception(sprintf('Missing language tag for [%s] table', __CLASS__), 400);
316 }
317
318 return $columns[0];
319 }
320
321 /**
322 * Returns a list of translatable columns.
323 *
324 * @param boolean $link True to return an associative array containing
325 * the columns of the translation table (key) and the
326 * columns of the linked original table (value).
327 *
328 * @return array
329 */
330 public function getContentColumns($link = false)
331 {
332 // get content columns
333 $columns = $this->searchColumns('content');
334
335 if (!$link)
336 {
337 return $columns;
338 }
339
340 // get related columns of linked table
341 $link = $this->searchColumns('content', 'rule', 'link');
342
343 $assoc = array();
344
345 for ($i = 0; $i < count($columns); $i++)
346 {
347 $assoc[$columns[$i]] = $link[$i] ? $link[$i] : $columns[$i];
348 }
349
350 return $assoc;
351 }
352
353 /**
354 * Helper method used to scan the table columns information.
355 *
356 * @param string $search The term to search for. Use '*' to skip search.
357 * @param string $key The attribute in which to search the term.
358 * @param string $return The attribute to return.
359 *
360 * @return array A list of matching columns.
361 */
362 protected function searchColumns($search, $key = 'rule', $return = 'name')
363 {
364 $results = array();
365
366 foreach ($this->xml->columns->column as $column)
367 {
368 $attrs = $column->attributes();
369
370 if ($search == '*' || preg_match("/^{$search}$/i", $attrs->{$key}))
371 {
372 if ($return == '*')
373 {
374 $results[] = $attrs;
375 }
376 else
377 {
378 $results[] = (string) $attrs->{$return};
379 }
380 }
381 }
382
383 // do not return empty values
384 return $results;
385 }
386 }
387