1 <?php
2
3 namespace Alo;
4
5 use Alo;
6 use Alo\Db\AbstractDb as DB;
7 use Alo\Exception\LibraryException;
8
9 if (!defined('GEN_START')) {
10 http_response_code(404);
11 } else {
12
13 Alo::loadConfig('locale');
14
15 /**
16 * Locale handler
17 *
18 * @author Arturas Molcanovas <a.molcanovas@gmail.com>
19 */
20 class Locale {
21
22 /**
23 * Static reference to the last instance of this class
24 *
25 * @var Locale
26 */
27 static $this;
28 /**
29 * prepQuery settings
30 *
31 * @var array
32 */
33 protected static $querySettings = [DB::V_CACHE => true,
34 DB::V_TIME => ALO_LOCALE_CACHE_TIME];
35 /**
36 * Reference to the database connection
37 *
38 * @var DB
39 */
40 protected $db;
41 /**
42 * Fetched items
43 *
44 * @var array
45 */
46 protected $fetched = [];
47 /**
48 * Raw fetched array
49 *
50 * @var array
51 */
52 protected $raw;
53 /**
54 * Whether the initial fetch has been done
55 *
56 * @var bool
57 */
58 protected $firstFetchDone = false;
59
60 /**
61 * Instantiates the Locale handler
62 *
63 * @author Art <a.molcanovas@gmail.com>
64 *
65 * @param DB $db If not using Alo::$db you can supply the reference to the database connection here
66 *
67 * @throws LibraryException If the above reference is not supplied and Alo::$db is not instantiated
68 */
69 function __construct(DB &$db = null) {
70 if ($db) {
71 $this->db = &$db;
72 } elseif (Alo::$db && Alo::$db instanceof DB) {
73 $this->db = &Alo::$db;
74 } else {
75 throw new LibraryException('Alo::$db does not have a database connection assigned.',
76 LibraryException::E_REQUIRED_LIB_NOT_FOUND);
77 }
78
79 self::$this = &$this;
80 }
81
82 /**
83 * Instantiates the Locale handler
84 *
85 * @author Art <a.molcanovas@gmail.com>
86 *
87 * @param DB $db If not using Alo::$db you can supply the reference to the database connection here
88 *
89 * @throws LibraryException If the above reference is not supplied and Alo::$db is not instantiated
90 * @return Locale
91 */
92 static function locale(DB &$db = null) {
93 return new Locale($db);
94 }
95
96 /**
97 * Performs a locale fetch
98 *
99 * @author Art <a.molcanovas@gmail.com>
100 *
101 * @param array $pages Pages to fetch.
102 * @param string $primaryLocale The main locale - will be used as a fallback if a string is unavailable
103 * for the secondary locale
104 * @param string $secondaryLocale If you're fetching for the secondary locale, input it here.
105 *
106 * @return Locale
107 */
108 function fetch(array $pages = null, $primaryLocale = null, $secondaryLocale = null) {
109 $arrGlobal = ['global'];
110 if (!$primaryLocale) {
111 $primaryLocale = ALO_LOCALE_DEFAULT;
112 }
113
114 if (!$this->firstFetchDone) {
115 $pages = is_array($pages) ? array_merge($arrGlobal, $pages) : $arrGlobal;
116 $this->firstFetchDone = true;
117 }
118
119 if ($pages !== null) {
120 if (!is_array($pages)) {
121 $pages = $arrGlobal;
122 }
123
124 if ($secondaryLocale && $secondaryLocale !== $primaryLocale) {
125 $this->fetchTwo($pages, $primaryLocale, $secondaryLocale);
126 } else {
127 $this->fetchOne($pages, $primaryLocale);
128 }
129
130 $this->formatRaw();
131 }
132
133 return $this;
134 }
135
136 /**
137 * Fetches a raw dual-locale resultset (primary being a fallback)
138 *
139 * @author Art <a.molcanovas@gmail.com>
140 *
141 * @param array $pages Pages to fetch
142 * @param string $primaryLocale The primary locale
143 * @param string $secondaryLocale The secondary locale
144 */
145 protected function fetchTwo(array $pages, $primaryLocale, $secondaryLocale) {
146 $params = [':first' => $primaryLocale,
147 ':second' => $secondaryLocale];
148
149 $sql = 'SELECT DISTINCT `default`.`key`,' . 'IFNULL(`loc`.`value`,`default`.`value`) AS `value` ' .
150 'FROM `alo_locale` `default` ' . 'LEFT JOIN `alo_locale` `loc` ' . 'ON `loc`.`lang`=:second ' .
151 'AND `loc`.`page` = `default`.`page` ' . 'AND `loc`.`key`=`default`.`key` ' .
152 'WHERE `default`.`lang`=:first';
153
154 if (!ALO_LOCALE_FETCH_ALL) {
155 $sql .= ' AND `default`.`page` IN (';
156 foreach ($pages as $i => $p) {
157 $sql .= ':p' . $i . ',';
158 $params[':p' . $i] = $p;
159 }
160
161 $sql = rtrim($sql, ',') . ')';
162 }
163
164 $sql .= ' ORDER BY NULL';
165
166 $this->raw = $this->db->prepQuery($sql, $params, self::$querySettings);
167 }
168
169 /**
170 * Fetches a raw single-locale resultset
171 *
172 * @author Art <a.molcanovas@gmail.com>
173 *
174 * @param array $pages pages to fetch
175 * @param string $locale Locale to fetch
176 */
177 protected function fetchOne(array $pages, $locale) {
178 $params = [':first' => $locale];
179
180 $sql = 'SELECT `key`,' . '`value` ' . 'FROM `alo_locale` ' . 'WHERE `lang`=:first';
181
182 if (!ALO_LOCALE_FETCH_ALL) {
183 $sql .= ' AND `page` IN (';
184 foreach ($pages as $i => $p) {
185 $sql .= ':p' . $i . ',';
186 $params[':p' . $i] = $p;
187 }
188
189 $sql = rtrim($sql, ',') . ')';
190 }
191
192 $sql .= ' ORDER BY NULL';
193
194 $this->raw = $this->db->prepQuery($sql, $params, self::$querySettings);
195 }
196
197 /**
198 * Formats raw data
199 *
200 * @author Art <a.molcanovas@gmail.com>
201 * @return Locale
202 */
203 protected function formatRaw() {
204 if ($this->raw) {
205 foreach ($this->raw as $row) {
206 $this->fetched[$row['key']] = $row['value'];
207 }
208 }
209
210 return $this;
211 }
212
213 /**
214 * Returns a localised string
215 *
216 * @author Art <a.molcanovas@gmail.com>
217 *
218 * @param string $key String key
219 *
220 * @return string|null
221 */
222 function __get($key) {
223 return get($this->fetched[$key]);
224 }
225
226 /**
227 * Returns the fetched locale array
228 * @author Art <a.molcanovas@gmail.com>
229 * @return array
230 */
231 function getAll() {
232 return $this->fetched;
233 }
234 }
235 }
236