1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Importing the dependencies. |
||
5 | */ |
||
6 | use \Punic\Language; |
||
7 | |||
8 | /** |
||
9 | * WebController is an extension of the Controller that handles all |
||
10 | * the requests originating from the view of the website. |
||
11 | */ |
||
12 | class WebController extends Controller |
||
13 | { |
||
14 | /** |
||
15 | * Provides access to the templating engine. |
||
16 | * @property object $twig the twig templating engine. |
||
17 | */ |
||
18 | public $twig; |
||
19 | public $honeypot; |
||
20 | |||
21 | /** |
||
22 | * Constructor for the WebController. |
||
23 | * @param Model $model |
||
24 | */ |
||
25 | public function __construct($model) |
||
26 | { |
||
27 | parent::__construct($model); |
||
28 | |||
29 | // initialize Twig templates |
||
30 | $tmpDir = $model->getConfig()->getTemplateCache(); |
||
31 | |||
32 | // check if the cache pointed by config.ttl exists, if not we create it. |
||
33 | if (!file_exists($tmpDir)) { |
||
34 | mkdir($tmpDir); |
||
35 | } |
||
36 | |||
37 | // specify where to look for templates and cache |
||
38 | $loader = new Twig_Loader_Filesystem('view'); |
||
39 | // initialize Twig environment |
||
40 | $this->twig = new Twig_Environment($loader, array('cache' => $tmpDir,'auto_reload' => true)); |
||
41 | $this->twig->addExtension(new Twig_Extensions_Extension_I18n()); |
||
42 | // used for setting the base href for the relative urls |
||
43 | $this->twig->addGlobal("BaseHref", $this->getBaseHref()); |
||
44 | |||
45 | // pass the GlobalConfig object to templates so they can access configuration |
||
46 | $this->twig->addGlobal("GlobalConfig", $this->model->getConfig()); |
||
47 | |||
48 | // setting the list of properties to be displayed in the search results |
||
49 | $this->twig->addGlobal("PreferredProperties", array('skos:prefLabel', 'skos:narrower', 'skos:broader', 'skosmos:memberOf', 'skos:altLabel', 'skos:related')); |
||
50 | |||
51 | // register a Twig filter for generating URLs for vocabulary resources (concepts and groups) |
||
52 | $this->twig->addFilter(new Twig_SimpleFilter('link_url', array($this, 'linkUrlFilter'))); |
||
53 | |||
54 | // register a Twig filter for generating strings from language codes with CLDR |
||
55 | $langFilter = new Twig_SimpleFilter('lang_name', function ($langcode, $lang) { |
||
56 | return Language::getName($langcode, $lang); |
||
57 | }); |
||
58 | $this->twig->addFilter($langFilter); |
||
59 | |||
60 | // create the honeypot |
||
61 | $this->honeypot = new \Honeypot(); |
||
62 | if (!$this->model->getConfig()->getHoneypotEnabled()) { |
||
63 | $this->honeypot->disable(); |
||
64 | } |
||
65 | $this->twig->addGlobal('honeypot', $this->honeypot); |
||
66 | } |
||
67 | |||
68 | /** |
||
69 | * Guess the language of the user. Return a language string that is one |
||
70 | * of the supported languages defined in the $LANGUAGES setting, e.g. "fi". |
||
71 | * @param Request $request HTTP request |
||
72 | * @param string $vocid identifier for the vocabulary eg. 'yso'. |
||
73 | * @return string returns the language choice as a numeric string value |
||
74 | */ |
||
75 | public function guessLanguage($request, $vocid = null) |
||
76 | { |
||
77 | // 1. select language based on SKOSMOS_LANGUAGE cookie |
||
78 | $languageCookie = $request->getCookie('SKOSMOS_LANGUAGE'); |
||
79 | if ($languageCookie) { |
||
80 | return $languageCookie; |
||
81 | } |
||
82 | |||
83 | // 2. if vocabulary given, select based on the default language of the vocabulary |
||
84 | if ($vocid !== null && $vocid !== '') { |
||
85 | try { |
||
86 | $vocab = $this->model->getVocabulary($vocid); |
||
87 | return $vocab->getConfig()->getDefaultLanguage(); |
||
88 | } catch (Exception $e) { |
||
89 | // vocabulary id not found, move on to the next selection method |
||
90 | } |
||
91 | } |
||
92 | |||
93 | // 3. select language based on Accept-Language header |
||
94 | header('Vary: Accept-Language'); // inform caches that a decision was made based on Accept header |
||
95 | $this->negotiator = new \Negotiation\LanguageNegotiator(); |
||
96 | $langcodes = array_keys($this->languages); |
||
97 | // using a random language from the configured UI languages when there is no accept language header set |
||
98 | $acceptLanguage = $request->getServerConstant('HTTP_ACCEPT_LANGUAGE') ? $request->getServerConstant('HTTP_ACCEPT_LANGUAGE') : $langcodes[0]; |
||
99 | |||
100 | $bestLang = $this->negotiator->getBest($acceptLanguage, $langcodes); |
||
101 | if (isset($bestLang) && in_array($bestLang->getValue(), $langcodes)) { |
||
102 | return $bestLang->getValue(); |
||
103 | } |
||
104 | |||
105 | // show default site or prompt for language |
||
106 | return $langcodes[0]; |
||
107 | } |
||
108 | |||
109 | /** |
||
110 | * Determines a css class that controls width and positioning of the vocabulary list element. |
||
111 | * The layout is wider if the left/right box templates have not been provided. |
||
112 | * @return string css class for the container eg. 'voclist-wide' or 'voclist-right' |
||
113 | */ |
||
114 | private function listStyle() { |
||
115 | $left = file_exists('view/left.inc'); |
||
116 | $right = file_exists('view/right.inc'); |
||
117 | $ret = 'voclist'; |
||
118 | if (!$left && !$right) { |
||
119 | $ret .= '-wide'; |
||
120 | } else if (!($left && $right) && ($right || $left)) { |
||
121 | $ret .= ($right) ? '-left' : '-right'; |
||
122 | } |
||
123 | return $ret; |
||
124 | } |
||
125 | |||
126 | /** |
||
127 | * Loads and renders the view containing all the vocabularies. |
||
128 | * @param Request $request |
||
129 | */ |
||
130 | public function invokeVocabularies($request) |
||
131 | { |
||
132 | // set language parameters for gettext |
||
133 | $this->setLanguageProperties($request->getLang()); |
||
134 | // load template |
||
135 | $template = $this->twig->loadTemplate('landing.twig'); |
||
136 | // set template variables |
||
137 | $categoryLabel = $this->model->getClassificationLabel($request->getLang()); |
||
138 | $sortedVocabs = $this->model->getVocabularyList(false, true); |
||
139 | $langList = $this->model->getLanguages($request->getLang()); |
||
140 | $listStyle = $this->listStyle(); |
||
141 | |||
142 | // render template |
||
143 | echo $template->render( |
||
144 | array( |
||
145 | 'sorted_vocabs' => $sortedVocabs, |
||
146 | 'category_label' => $categoryLabel, |
||
147 | 'languages' => $this->languages, |
||
148 | 'lang_list' => $langList, |
||
149 | 'request' => $request, |
||
150 | 'list_style' => $listStyle |
||
151 | )); |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * Invokes the concept page of a single concept in a specific vocabulary. |
||
156 | * |
||
157 | * @param Request $request |
||
158 | */ |
||
159 | public function invokeVocabularyConcept(Request $request) |
||
160 | { |
||
161 | $lang = $request->getLang(); |
||
162 | $this->setLanguageProperties($lang); |
||
163 | $vocab = $request->getVocab(); |
||
164 | |||
165 | $langcodes = $vocab->getConfig()->getShowLangCodes(); |
||
166 | $uri = $vocab->getConceptURI($request->getUri()); // make sure it's a full URI |
||
167 | |||
168 | $results = $vocab->getConceptInfo($uri, $request->getContentLang()); |
||
169 | if (!$results) { |
||
0 ignored issues
–
show
|
|||
170 | $this->invokeGenericErrorPage($request); |
||
171 | return; |
||
172 | } |
||
173 | if ($this->notModified($results[0])) { |
||
174 | return; |
||
175 | } |
||
176 | $customLabels = $vocab->getConfig()->getPropertyLabelOverrides(); |
||
177 | |||
178 | $pluginParameters = json_encode($vocab->getConfig()->getPluginParameters()); |
||
179 | $template = (in_array('skos:Concept', $results[0]->getType()) || in_array('skos:ConceptScheme', $results[0]->getType())) ? $this->twig->loadTemplate('concept-info.twig') : $this->twig->loadTemplate('group-contents.twig'); |
||
180 | |||
181 | $crumbs = $vocab->getBreadCrumbs($request->getContentLang(), $uri); |
||
182 | echo $template->render(array( |
||
183 | 'search_results' => $results, |
||
184 | 'vocab' => $vocab, |
||
185 | 'concept_uri' => $uri, |
||
186 | 'languages' => $this->languages, |
||
187 | 'explicit_langcodes' => $langcodes, |
||
188 | 'bread_crumbs' => $crumbs['breadcrumbs'], |
||
189 | 'combined' => $crumbs['combined'], |
||
190 | 'request' => $request, |
||
191 | 'plugin_params' => $pluginParameters, |
||
192 | 'custom_labels' => $customLabels) |
||
193 | ); |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * Invokes the feedback page with information of the users current vocabulary. |
||
198 | */ |
||
199 | public function invokeFeedbackForm($request) |
||
200 | { |
||
201 | $template = $this->twig->loadTemplate('feedback.twig'); |
||
202 | $this->setLanguageProperties($request->getLang()); |
||
203 | $vocabList = $this->model->getVocabularyList(false); |
||
204 | $vocab = $request->getVocab(); |
||
205 | |||
206 | $feedbackSent = false; |
||
207 | if ($request->getQueryParamPOST('message')) { |
||
208 | $feedbackSent = true; |
||
209 | $feedbackMsg = $request->getQueryParamPOST('message'); |
||
210 | $feedbackName = $request->getQueryParamPOST('name', 255); |
||
211 | $feedbackEmail = $request->getQueryParamPOST('email', 255); |
||
212 | $msgSubject = $request->getQueryParamPOST('msgsubject', 255); |
||
213 | $feedbackVocab = $request->getQueryParamPOST('vocab'); |
||
214 | $feedbackVocabEmail = ($feedbackVocab !== null && $feedbackVocab !== '') ? |
||
215 | $this->model->getVocabulary($feedbackVocab)->getConfig()->getFeedbackRecipient() : null; |
||
216 | // if the hidden field has been set a value we have found a spam bot |
||
217 | // and we do not actually send the message. |
||
218 | if ($this->honeypot->validateHoneypot($request->getQueryParamPOST('item-description')) && |
||
219 | $this->honeypot->validateHoneytime($request->getQueryParamPOST('user-captcha'), $this->model->getConfig()->getHoneypotTime())) { |
||
220 | $this->sendFeedback($request, $feedbackMsg, $msgSubject, $feedbackName, $feedbackEmail, $feedbackVocab, $feedbackVocabEmail); |
||
221 | } |
||
222 | } |
||
223 | echo $template->render( |
||
224 | array( |
||
225 | 'languages' => $this->languages, |
||
226 | 'vocab' => $vocab, |
||
227 | 'vocabList' => $vocabList, |
||
228 | 'feedback_sent' => $feedbackSent, |
||
229 | 'request' => $request, |
||
230 | )); |
||
231 | } |
||
232 | |||
233 | private function createFeedbackHeaders($fromName, $fromEmail, $toMail, $sender) |
||
234 | { |
||
235 | $headers = "MIME-Version: 1.0" . "\r\n"; |
||
236 | $headers .= "Content-type: text/html; charset=UTF-8" . "\r\n"; |
||
237 | if (!empty($toMail)) { |
||
238 | $headers .= "Cc: " . $this->model->getConfig()->getFeedbackAddress() . "\r\n"; |
||
239 | } |
||
240 | if (!empty($fromEmail)) { |
||
241 | $headers .= "Reply-To: $fromName <$fromEmail>\r\n"; |
||
242 | } |
||
243 | $service = $this->model->getConfig()->getServiceName(); |
||
244 | return $headers . "From: $fromName via $service <$sender>"; |
||
245 | } |
||
246 | |||
247 | /** |
||
248 | * Sends the user entered message through the php's mailer. |
||
249 | * @param string $message content given by user. |
||
250 | * @param string $messageSubject subject line given by user. |
||
251 | * @param string $fromName senders own name. |
||
252 | * @param string $fromEmail senders email address. |
||
253 | * @param string $fromVocab which vocabulary is the feedback related to. |
||
254 | */ |
||
255 | public function sendFeedback($request, $message, $messageSubject, $fromName = null, $fromEmail = null, $fromVocab = null, $toMail = null) |
||
256 | { |
||
257 | $toAddress = ($toMail) ? $toMail : $this->model->getConfig()->getFeedbackAddress(); |
||
258 | $messageSubject = "[" . $this->model->getConfig()->getServiceName() . "] " . $messageSubject; |
||
259 | if ($fromVocab !== null && $fromVocab !== '') { |
||
260 | $message = 'Feedback from vocab: ' . strtoupper($fromVocab) . "<br />" . $message; |
||
261 | } |
||
262 | $envelopeSender = $this->model->getConfig()->getFeedbackEnvelopeSender(); |
||
263 | // determine the sender address of the message |
||
264 | $sender = $this->model->getConfig()->getFeedbackSender(); |
||
265 | if (empty($sender)) $sender = $envelopeSender; |
||
266 | if (empty($sender)) $sender = $this->model->getConfig()->getFeedbackAddress(); |
||
267 | |||
268 | // determine sender name - default to "anonymous user" if not given by user |
||
269 | if (empty($fromName)) $fromName = "anonymous user"; |
||
270 | $headers = $this->createFeedbackHeaders($fromName, $fromEmail, $toMail, $sender); |
||
271 | $params = empty($envelopeSender) ? '' : "-f $envelopeSender"; |
||
272 | // adding some information about the user for debugging purposes. |
||
273 | $message = $message . "<br /><br /> Debugging information:" |
||
274 | . "<br />Timestamp: " . date(DATE_RFC2822) |
||
275 | . "<br />User agent: " . $request->getServerConstant('HTTP_USER_AGENT') |
||
276 | . "<br />Referer: " . $request->getServerConstant('HTTP_REFERER'); |
||
277 | |||
278 | try { |
||
279 | mail($toAddress, $messageSubject, $message, $headers, $params); |
||
280 | } catch (Exception $e) { |
||
281 | header("HTTP/1.0 404 Not Found"); |
||
282 | $template = $this->twig->loadTemplate('error-page.twig'); |
||
283 | if ($this->model->getConfig()->getLogCaughtExceptions()) { |
||
284 | error_log('Caught exception: ' . $e->getMessage()); |
||
285 | } |
||
286 | |||
287 | echo $template->render( |
||
288 | array( |
||
289 | 'languages' => $this->languages, |
||
290 | )); |
||
291 | |||
292 | return; |
||
293 | } |
||
294 | } |
||
295 | |||
296 | /** |
||
297 | * Invokes the about page for the Skosmos service. |
||
298 | */ |
||
299 | public function invokeAboutPage($request) |
||
300 | { |
||
301 | $template = $this->twig->loadTemplate('about.twig'); |
||
302 | $this->setLanguageProperties($request->getLang()); |
||
303 | $url = $request->getServerConstant('HTTP_HOST'); |
||
304 | |||
305 | echo $template->render( |
||
306 | array( |
||
307 | 'languages' => $this->languages, |
||
308 | 'server_instance' => $url, |
||
309 | 'request' => $request, |
||
310 | )); |
||
311 | } |
||
312 | |||
313 | /** |
||
314 | * Invokes the search for concepts in all the available ontologies. |
||
315 | */ |
||
316 | public function invokeGlobalSearch($request) |
||
317 | { |
||
318 | $lang = $request->getLang(); |
||
319 | $template = $this->twig->loadTemplate('vocab-search-listing.twig'); |
||
320 | $this->setLanguageProperties($lang); |
||
321 | |||
322 | $parameters = new ConceptSearchParameters($request, $this->model->getConfig()); |
||
323 | |||
324 | $vocabs = $request->getQueryParam('vocabs'); # optional |
||
325 | // convert to vocids array to support multi-vocabulary search |
||
326 | $vocids = ($vocabs !== null && $vocabs !== '') ? explode(' ', $vocabs) : null; |
||
327 | $vocabObjects = array(); |
||
328 | if ($vocids) { |
||
329 | foreach($vocids as $vocid) { |
||
330 | try { |
||
331 | $vocabObjects[] = $this->model->getVocabulary($vocid); |
||
332 | } catch (ValueError $e) { |
||
333 | // fail fast with an error page if the vocabulary cannot be found |
||
334 | if ($this->model->getConfig()->getLogCaughtExceptions()) { |
||
335 | error_log('Caught exception: ' . $e->getMessage()); |
||
336 | } |
||
337 | header("HTTP/1.0 400 Bad Request"); |
||
338 | $this->invokeGenericErrorPage($request, $e->getMessage()); |
||
339 | return; |
||
340 | } |
||
341 | } |
||
342 | } |
||
343 | $parameters->setVocabularies($vocabObjects); |
||
344 | |||
345 | $counts = null; |
||
346 | $searchResults = null; |
||
347 | $errored = false; |
||
348 | |||
349 | try { |
||
350 | $countAndResults = $this->model->searchConceptsAndInfo($parameters); |
||
351 | $counts = $countAndResults['count']; |
||
352 | $searchResults = $countAndResults['results']; |
||
353 | } catch (Exception $e) { |
||
354 | $errored = true; |
||
355 | header("HTTP/1.0 500 Internal Server Error"); |
||
356 | if ($this->model->getConfig()->getLogCaughtExceptions()) { |
||
357 | error_log('Caught exception: ' . $e->getMessage()); |
||
358 | } |
||
359 | } |
||
360 | $vocabList = $this->model->getVocabularyList(); |
||
361 | $sortedVocabs = $this->model->getVocabularyList(false, true); |
||
362 | $langList = $this->model->getLanguages($lang); |
||
363 | |||
364 | echo $template->render( |
||
365 | array( |
||
366 | 'search_count' => $counts, |
||
367 | 'languages' => $this->languages, |
||
368 | 'search_results' => $searchResults, |
||
369 | 'rest' => $parameters->getOffset()>0, |
||
370 | 'global_search' => true, |
||
371 | 'search_failed' => $errored, |
||
372 | 'term' => $request->getQueryParamRaw('q'), |
||
373 | 'lang_list' => $langList, |
||
374 | 'vocabs' => str_replace(' ', '+', $vocabs), |
||
375 | 'vocab_list' => $vocabList, |
||
376 | 'sorted_vocabs' => $sortedVocabs, |
||
377 | 'request' => $request, |
||
378 | 'parameters' => $parameters |
||
379 | )); |
||
380 | } |
||
381 | |||
382 | /** |
||
383 | * Invokes the search for a single vocabs concepts. |
||
384 | */ |
||
385 | public function invokeVocabularySearch($request) |
||
386 | { |
||
387 | $template = $this->twig->loadTemplate('vocab-search-listing.twig'); |
||
388 | $this->setLanguageProperties($request->getLang()); |
||
389 | $vocab = $request->getVocab(); |
||
390 | $searchResults = null; |
||
391 | try { |
||
392 | $vocabTypes = $this->model->getTypes($request->getVocabid(), $request->getLang()); |
||
393 | } catch (Exception $e) { |
||
394 | header("HTTP/1.0 500 Internal Server Error"); |
||
395 | if ($this->model->getConfig()->getLogCaughtExceptions()) { |
||
396 | error_log('Caught exception: ' . $e->getMessage()); |
||
397 | } |
||
398 | |||
399 | echo $template->render( |
||
400 | array( |
||
401 | 'languages' => $this->languages, |
||
402 | 'vocab' => $vocab, |
||
403 | 'request' => $request, |
||
404 | 'search_results' => $searchResults |
||
405 | )); |
||
406 | |||
407 | return; |
||
408 | } |
||
409 | |||
410 | $langcodes = $vocab->getConfig()->getShowLangCodes(); |
||
411 | $parameters = new ConceptSearchParameters($request, $this->model->getConfig()); |
||
412 | |||
413 | try { |
||
414 | $countAndResults = $this->model->searchConceptsAndInfo($parameters); |
||
415 | $counts = $countAndResults['count']; |
||
416 | $searchResults = $countAndResults['results']; |
||
417 | } catch (Exception $e) { |
||
418 | header("HTTP/1.0 404 Not Found"); |
||
419 | if ($this->model->getConfig()->getLogCaughtExceptions()) { |
||
420 | error_log('Caught exception: ' . $e->getMessage()); |
||
421 | } |
||
422 | |||
423 | echo $template->render( |
||
424 | array( |
||
425 | 'languages' => $this->languages, |
||
426 | 'vocab' => $vocab, |
||
427 | 'term' => $request->getQueryParam('q'), |
||
428 | 'search_results' => $searchResults |
||
429 | )); |
||
430 | return; |
||
431 | } |
||
432 | echo $template->render( |
||
433 | array( |
||
434 | 'languages' => $this->languages, |
||
435 | 'vocab' => $vocab, |
||
436 | 'search_results' => $searchResults, |
||
437 | 'search_count' => $counts, |
||
438 | 'rest' => $parameters->getOffset()>0, |
||
439 | 'limit_parent' => $parameters->getParentLimit(), |
||
440 | 'limit_type' => $request->getQueryParam('type') ? explode('+', $request->getQueryParam('type')) : null, |
||
441 | 'limit_group' => $parameters->getGroupLimit(), |
||
442 | 'limit_scheme' => $request->getQueryParam('scheme') ? explode('+', $request->getQueryParam('scheme')) : null, |
||
443 | 'group_index' => $vocab->listConceptGroups($request->getContentLang()), |
||
444 | 'parameters' => $parameters, |
||
445 | 'term' => $request->getQueryParamRaw('q'), |
||
446 | 'types' => $vocabTypes, |
||
447 | 'explicit_langcodes' => $langcodes, |
||
448 | 'request' => $request, |
||
449 | )); |
||
450 | } |
||
451 | |||
452 | /** |
||
453 | * Invokes the alphabetical listing for a specific vocabulary. |
||
454 | */ |
||
455 | public function invokeAlphabeticalIndex($request) |
||
456 | { |
||
457 | $lang = $request->getLang(); |
||
458 | $this->setLanguageProperties($lang); |
||
459 | $template = $this->twig->loadTemplate('alphabetical-index.twig'); |
||
460 | $vocab = $request->getVocab(); |
||
461 | |||
462 | $offset = ($request->getQueryParam('offset') && is_numeric($request->getQueryParam('offset')) && $request->getQueryParam('offset') >= 0) ? $request->getQueryParam('offset') : 0; |
||
463 | if ($request->getQueryParam('limit')) { |
||
464 | $count = $request->getQueryParam('limit'); |
||
465 | } else { |
||
466 | $count = ($offset > 0) ? null : 250; |
||
467 | } |
||
468 | |||
469 | $contentLang = $request->getContentLang(); |
||
470 | |||
471 | $allAtOnce = $vocab->getConfig()->getAlphabeticalFull(); |
||
472 | if (!$allAtOnce) { |
||
473 | $letters = $vocab->getAlphabet($contentLang); |
||
474 | $letter = $request->getLetter(); |
||
475 | if ($letter === '' && isset($letters[0])) { |
||
476 | $letter = $letters[0]; |
||
477 | } |
||
478 | $searchResults = $vocab->searchConceptsAlphabetical($letter, $count, $offset, $contentLang); |
||
479 | } else { |
||
480 | $letters = null; |
||
481 | $searchResults = $vocab->searchConceptsAlphabetical('*', null, null, $contentLang); |
||
482 | } |
||
483 | |||
484 | $request->setContentLang($contentLang); |
||
485 | |||
486 | echo $template->render( |
||
487 | array( |
||
488 | 'languages' => $this->languages, |
||
489 | 'vocab' => $vocab, |
||
490 | 'alpha_results' => $searchResults, |
||
491 | 'letters' => $letters, |
||
492 | 'all_letters' => $allAtOnce, |
||
493 | 'request' => $request, |
||
494 | )); |
||
495 | } |
||
496 | |||
497 | /** |
||
498 | * Invokes the vocabulary group index page template. |
||
499 | * @param boolean $stats set to true to get vocabulary statistics visible. |
||
500 | */ |
||
501 | public function invokeGroupIndex($request, $stats = false) |
||
502 | { |
||
503 | $lang = $request->getLang(); |
||
504 | $this->setLanguageProperties($lang); |
||
505 | $template = $this->twig->loadTemplate('group-index.twig'); |
||
506 | $vocab = $request->getVocab(); |
||
507 | |||
508 | echo $template->render( |
||
509 | array( |
||
510 | 'languages' => $this->languages, |
||
511 | 'stats' => $stats, |
||
512 | 'vocab' => $vocab, |
||
513 | 'request' => $request, |
||
514 | )); |
||
515 | } |
||
516 | |||
517 | /** |
||
518 | * Loads and renders the view containing a specific vocabulary. |
||
519 | */ |
||
520 | public function invokeVocabularyHome($request) |
||
521 | { |
||
522 | $lang = $request->getLang(); |
||
523 | // set language parameters for gettext |
||
524 | $this->setLanguageProperties($lang); |
||
525 | $vocab = $request->getVocab(); |
||
526 | |||
527 | $defaultView = $vocab->getConfig()->getDefaultSidebarView(); |
||
528 | // load template |
||
529 | if ($defaultView === 'groups') { |
||
530 | $this->invokeGroupIndex($request, true); |
||
531 | return; |
||
532 | } else if ($defaultView === 'new') { |
||
533 | $this->invokeChangeList($request); |
||
534 | } |
||
535 | $pluginParameters = json_encode($vocab->getConfig()->getPluginParameters()); |
||
536 | |||
537 | $template = $this->twig->loadTemplate('vocab.twig'); |
||
538 | |||
539 | echo $template->render( |
||
540 | array( |
||
541 | 'languages' => $this->languages, |
||
542 | 'vocab' => $vocab, |
||
543 | 'search_letter' => 'A', |
||
544 | 'active_tab' => $defaultView, |
||
545 | 'request' => $request, |
||
546 | 'plugin_params' => $pluginParameters |
||
547 | )); |
||
548 | } |
||
549 | |||
550 | /** |
||
551 | * Invokes a very generic errorpage. |
||
552 | */ |
||
553 | public function invokeGenericErrorPage($request, $message = null) |
||
554 | { |
||
555 | $this->setLanguageProperties($request->getLang()); |
||
556 | header("HTTP/1.0 404 Not Found"); |
||
557 | $template = $this->twig->loadTemplate('error-page.twig'); |
||
558 | echo $template->render( |
||
559 | array( |
||
560 | 'languages' => $this->languages, |
||
561 | 'request' => $request, |
||
562 | 'vocab' => $request->getVocab(), |
||
563 | 'message' => $message, |
||
564 | 'requested_page' => filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_FULL_SPECIAL_CHARS), |
||
565 | )); |
||
566 | } |
||
567 | |||
568 | /** |
||
569 | * Loads and renders the view containing a list of recent changes in the vocabulary. |
||
570 | * @param Request $request |
||
571 | */ |
||
572 | public function invokeChangeList($request, $prop='dc:created') |
||
573 | { |
||
574 | $offset = ($request->getQueryParam('offset') && is_numeric($request->getQueryParam('offset')) && $request->getQueryParam('offset') >= 0) ? $request->getQueryParam('offset') : 0; |
||
575 | $limit = ($request->getQueryParam('limit') && is_numeric($request->getQueryParam('limit')) && $request->getQueryParam('limit') >= 0) ? $request->getQueryParam('limit') : 200; |
||
576 | |||
577 | $changeList = $this->getChangeList($request, $prop, $offset, $limit); |
||
578 | $bydate = $this->formatChangeList($changeList, $request->getLang()); |
||
579 | |||
580 | // load template |
||
581 | $template = $this->twig->loadTemplate('changes.twig'); |
||
582 | |||
583 | // render template |
||
584 | echo $template->render( |
||
585 | array( |
||
586 | 'vocab' => $request->getVocab(), |
||
587 | 'languages' => $this->languages, |
||
588 | 'request' => $request, |
||
589 | 'changeList' => $bydate) |
||
590 | ); |
||
591 | } |
||
592 | /** |
||
593 | * Gets the list of newest concepts for a vocabulary according to timestamp indicated by a property |
||
594 | * @param Request $request |
||
595 | * @param string $prop the name of the property eg. 'dc:modified'. |
||
596 | * @param int $offset starting index offset |
||
597 | * @param int $limit maximum number of concepts to return |
||
598 | * @return Array list of concepts |
||
599 | */ |
||
600 | public function getChangeList($request, $prop, $offset=0, $limit=200) |
||
601 | { |
||
602 | // set language parameters for gettext |
||
603 | $this->setLanguageProperties($request->getLang()); |
||
604 | |||
605 | return $request->getVocab()->getChangeList($prop, $request->getContentLang(), $offset, $limit); |
||
606 | } |
||
607 | |||
608 | /** |
||
609 | * Formats the list of concepts as labels arranged by modification month |
||
610 | * @param Array $changeList |
||
611 | * @param string $lang the language for displaying dates in the change list |
||
612 | * @return array list of concepts as labels by month |
||
613 | */ |
||
614 | public function formatChangeList($changeList, $lang) |
||
615 | { |
||
616 | $formatByDate = array(); |
||
617 | foreach($changeList as $concept) { |
||
618 | $concept['datestring'] = Punic\Calendar::formatDate($concept['date'], 'medium', $lang); |
||
619 | $formatByDate[Punic\Calendar::getMonthName($concept['date'], 'wide', $lang, true) . Punic\Calendar::format($concept['date'], ' y', $lang) ][strtolower($concept['prefLabel'])] = $concept; |
||
620 | } |
||
621 | return $formatByDate; |
||
622 | } |
||
623 | |||
624 | } |
||
625 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.