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\SmartObj;
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 SmartObj {
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 * Instantiates the Locale handler
61 *
62 * @author Art <a.molcanovas@gmail.com>
63 *
64 * @param DB $db If not using Alo::$db you can supply the reference to the database connection here
65 *
66 * @throws LibraryException If the above reference is not supplied and Alo::$db is not instantiated
67 */
68 function __construct(DB &$db = null) {
69 if ($db) {
70 $this->db = &$db;
71 } elseif (Alo::$db && Alo::$db instanceof DB) {
72 $this->db = &Alo::$db;
73 } else {
74 throw new LibraryException('Alo::$db does not have a database connection assigned.',
75 LibraryException::E_REQUIRED_LIB_NOT_FOUND);
76 }
77
78 parent::__construct();
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->data[$row['key']] = $row['value'];
207 }
208 }
209
210 return $this;
211 }
212
213 /**
214 * Returns the fetched locale array
215 * @author Art <a.molcanovas@gmail.com>
216 * @return array
217 */
218 function getAll() {
219 return $this->data;
220 }
221 }
222 }
223