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