*/ class action_plugin_newsfeed extends ActionPlugin { private static array $categories = [ 'fykos-blue', 'fykos-pink', 'fykos-line', 'fykos-purple', 'fykos-orange', 'fykos-green', ]; private helper_plugin_newsfeed $helper; public function __construct() { $this->helper = $this->loadHelper('newsfeed'); } public function register(EventHandler $controller): void { $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjax'); $controller->register_hook('ACTION_ACT_PREPROCESS', 'AFTER', $this, 'handleMetaData'); $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleActPreprocess'); $controller->register_hook('TPL_ACT_UNKNOWN', 'BEFORE', $this, 'handleActUnknown'); } public function handleActUnknown(Event $event): void { global $ACT; global $INPUT; if ($ACT !== helper_plugin_newsfeed::FORM_TARGET) { return; } if (auth_quickaclcheck('start') < AUTH_EDIT) { return; } $event->preventDefault(); $event->stopPropagation(); switch ($INPUT->param('news')['do']) { case'edit': case'create': $this->handleEditForm(); return; case 'preview': $this->handleStreamPreview(); return; } } public function handleActPreprocess(Event $event): void { global $INPUT; if ($event->data !== helper_plugin_newsfeed::FORM_TARGET) { return; } if (auth_quickaclcheck('start') < AUTH_EDIT) { return; } $event->preventDefault(); $event->stopPropagation(); switch ($INPUT->param('news')['do']) { case 'create': case 'edit': default: return; case'save': $this->handleNews(); return; case'priority': $this->handlePriority(); return; case'delete': $this->handleDelete(); return; case'purge': $this->handleCache(); return; } } public function handleAjax(Event $event): void { $payload = json_decode(file_get_contents('php://input'), true); if ($payload['target'] !== 'feed') { return; } header('Content-Type: application/json'); $event->stopPropagation(); $event->preventDefault(); echo json_encode($this->printStream((int)$payload['news']['offset'], (int)$payload['news']['length'], $payload['news']['stream'], $payload['page_id'])); } public function handleMetaData(): void { global $ID; global $INPUT; if (!$INPUT->str('news-id')) { return; } $newsId = $INPUT->str('news-id'); $news = $this->helper->serviceNews->getById($newsId); $this->helper->openGraphData->addMetaData('og', 'title', $news->title); $this->helper->openGraphData->addMetaData('og', 'url', $news->getToken($ID)); $text = $news->renderText(); $this->helper->openGraphData->addMetaData('og', 'description', $text); if ($news->hasImage()) { $this->helper->openGraphData->addMetaData('og', 'image', ml($news->image, null, true, '&', true)); } } private function printStream(int $start, int $length, string $streamId, string $pageId): array { $stream = $this->helper->serviceStream->findByName($streamId); $news = $stream->getNews(); $htmlNews = []; for ($i = $start; $i < min([$start + $length, (count($news))]); $i++) { $e = $i % 2 ? 'even' : 'odd'; $htmlNews[] = $news[$i]->render($e, $streamId, $pageId); } return ['html' => ['news' => $htmlNews]]; } private function handleNews(): void { global $INPUT; $file = ModelNews::getCacheFileById($INPUT->param('news')['id']); $cache = new Cache($file, ''); $cache->removeCache(); $data = []; foreach (helper_plugin_newsfeed::$fields as $field) { if ($field === 'text') { $data[$field] = cleanText($INPUT->str('text')); } else { $data[$field] = $INPUT->param($field); } } $data = [ 'title' => $data['title'], 'author_name' => $data['authorName'], 'author_email' => $data['authorEmail'], 'text' => $data['text'], 'news_date' => $data['newsDate'], 'image' => $data['image'] ?: null, 'category' => $data['category'], 'link_href' => $data['linkHref'] ?: null, 'link_title' => $data['linkTitle'] ?: null, ]; if (+$INPUT->param('news')['id'] === 0) { $this->helper->serviceNews->create($data); $this->saveIntoStreams($this->helper->serviceNews->getMaxId(), $INPUT->param('news')['stream']); } else { $news = $this->helper->serviceNews->getById($INPUT->param('news')['id']); $this->helper->serviceNews->update($news, $data); } header('Location: ' . $_SERVER['REQUEST_URI']); exit(); } private function saveIntoStreams(int $newsId, string $streamName): void { $stream = $this->helper->serviceStream->findByName($streamName); $streams = [$stream->streamId]; $this->helper->fullParentDependence($stream->streamId, $streams); foreach ($streams as $stream) { $this->helper->servicePriority->store($newsId, $stream); } } private function handlePriority(): void { global $INPUT; $file = ModelNews::getCacheFileById($INPUT->param('news')['id']); $cache = new cache($file, ''); $cache->removeCache(); $stream = $this->helper->serviceStream->findByName($INPUT->param('news')['stream']); $priority = $this->helper->servicePriority->findByNewsAndStream($INPUT->param('news')['id'], $stream->streamId); $data = $INPUT->param('priority'); $this->helper->servicePriority->update($priority, [ 'priority_from' => $data['from'], 'priority_to' => $data['to'], 'priority' => $data['value'], ]); header('Location: ' . $_SERVER['REQUEST_URI']); exit(); } private function handleDelete(): void { global $INPUT; $stream = $this->helper->serviceStream->findByName($INPUT->param('news')['stream']); $priority = $this->helper->servicePriority->findByNewsAndStream($INPUT->param('news')['id'], $stream->streamId); $priority->delete(); header('Location: ' . $_SERVER['REQUEST_URI']); exit(); } private function handleCache(): void { global $INPUT; if (!$INPUT->param('news')['id']) { $news = $this->helper->serviceNews->getAll(); foreach ($news as $new) { $f = $new->getCacheFile(); $cache = new Cache($f, ''); $cache->removeCache(); } } else { $f = ModelNews::getCacheFileById($INPUT->param('news')['id']); $cache = new Cache($f, ''); $cache->removeCache(); } header('Location: ' . $_SERVER['REQUEST_URI']); exit(); } private function handleStreamPreview(): void { global $INPUT; if ($INPUT->param('news')['stream']) { echo p_render('xhtml', p_get_instructions('{{news-stream>feed="5";stream="' . $INPUT->param('news')['stream'] . '"}}'), $info); } else { msg('Stream is required.', -1); } } private function handleEditForm(): void { global $INPUT; global $ID; $form = new Form(); if ($INPUT->param('news')['id'] !== 0) { $data = $this->helper->serviceNews->getById($INPUT->param('news')['id']); } else { $data = new ModelNews($this->helper->sqlite); $data->loadDefault(); } $form->setHiddenField('page_id', $ID); $form->setHiddenField('do', helper_plugin_newsfeed::FORM_TARGET); $form->setHiddenField('news[id]', $INPUT->param('news')['id']); $form->setHiddenField('news[do]', 'save'); $form->setHiddenField('news[stream]', $INPUT->param('news')['stream']); $form->addFieldsetOpen('Novinky na webu'); foreach (helper_plugin_newsfeed::$fields as $field) { $input = null; $form->addTagOpen('div')->addClass('form-group'); switch ($field) { case'text': $input = $form->addTextarea('text', $this->getLang($field), -1)->attrs([ 'class' => 'form-control', 'rows' => 10, ]); $input->val($data->text); break; case 'newsDate': $input = new DateTimeInputElement($field, $this->getLang($field)); $input->attr('class', 'form-control'); $input->setStep(1); $form->addElement($input); $input->val($data->newsDate ?: 'now'); break; case'category': $input = $form->addDropdown('category', static::$categories, $this->getLang($field))->attr('class', 'form-control'); $input->val($data->category); break; case'image': $input = $form->addTextInput($field, $this->getLang($field))->attr('class', 'form-control'); $input->val($data->image); break; case 'linkHref': $input = $form->addTextInput($field, $this->getLang($field))->attrs([ 'class' => 'form-control', ]); $input->val($data->linkHref); break; case 'linkTitle': $input = $form->addTextInput($field, $this->getLang($field))->attrs([ 'class' => 'form-control', ]); $input->val($data->linkTitle); break; case 'authorName': $input = $form->addTextInput($field, $this->getLang($field))->attrs([ 'pattern' => '\S.*', 'required' => 'required', 'class' => 'form-control', ]); $input->val($data->authorName); break; case 'authorEmail': $input = new InputElement('email', $field, $this->getLang($field)); $input->attr('class', 'form-control'); $form->addElement($input); $input->val($data->authorEmail); break; case 'title': $input = $form->addTextInput($field, $this->getLang($field))->attrs([ 'pattern' => '\S.*', 'required' => 'required', 'class' => 'form-control', ]); $input->val($data->title); break; default: msg('Not implement input field ' . $field, -1); } if ($note = $this->getLang($field . '_note')) { $form->addHTML('' . $note . ''); } $form->addTagClose('div'); } $form->addFieldsetClose(); $form->addButton('submit', $this->getLang('save'))->addClass('btn btn-success'); echo $form->toHTML(); } }