297 lines
12 KiB
PHP
297 lines
12 KiB
PHP
<?php
|
|
namespace App\Http\Controllers;
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
class NewsController extends Controller
|
|
{
|
|
private static $NEWS_CATEGORY = 1;
|
|
private static $CALENDAR_CATEGORY = 42;
|
|
private static $EXTERNAL_NEWS_CATEGORY = 0;
|
|
private static $BLOG_CATEGORY = 45;
|
|
|
|
private static $BASE_SQL = <<<QUERY
|
|
SELECT `news`.`id`, `content`.`title`, `content`.`content`, `news`.`podcast` AS `podcast_id`, `news`.`video`, `news`.`keywords`, `news`.`titlewithdate`,
|
|
`news`.`creationdt` AS `published`, `content`.`creator`, `news`.`pubupdatedt` AS `edited`,
|
|
`news`.`startdt` AS `starts`, `news`.`enddt` AS `ends`, `content`.`extref` AS `external_id`,
|
|
`content`.`showsource` AS `showsource`, `sources`.`title` AS `source`, `sources`.`url` AS `source_url`,
|
|
`themes`.`title` AS `theme`, `themes`.`thumbnail` AS `theme_thumbnail`, `themes`.`slug` AS `theme_slug`,
|
|
`regions`.`title` AS `region`, `regions`.`slug` as `region_slug`
|
|
FROM `news`
|
|
LEFT JOIN `news_target_content` AS `content` ON `content`.`news` = `news`.`id`
|
|
LEFT JOIN `news_regions` AS `regions` ON `regions`.`id` = `news`.`region`
|
|
LEFT JOIN `news_sources` AS `sources` ON `sources`.`id` = `news`.`source`
|
|
LEFT JOIN `news_themes` AS `themes` ON `themes`.`id` = `news`.`theme`
|
|
WHERE (`news`.`category` = :category OR `news`.`category` = :secondarycategory) AND `content`.`target` = 1 AND `news`.`active` = 1 AND `content`.`active` = 1 AND `content`.`published` = 1
|
|
QUERY;
|
|
|
|
private static $LOAD_IMAGES =
|
|
'SELECT `id`, `file`, `description` AS `title` FROM `news_pictures` WHERE `news` = :newsId AND `active` = 1';
|
|
|
|
/**
|
|
* Create a new controller instance.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function __construct()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* RSS-feed van alle podcasts
|
|
*/
|
|
public function rss(Request $request) {
|
|
$page = (int)$request->get('page', 1);
|
|
if($page <= 0) {
|
|
return abort(400);
|
|
}
|
|
|
|
$podcasts = $this->retrieveNewsItems($page, $count = 20, $filter = null, $params = []);
|
|
$view = view('rss.news')->with('news', $podcasts)->with('url', $request->url())->with('page', $page);
|
|
return response($view)->header('Content-Type', 'application/xml');
|
|
}
|
|
|
|
/**
|
|
* Lijst van alle nieuwsberichten
|
|
*/
|
|
public function newslist(Request $request, $filter = null) {
|
|
$count = (int)$request->get('aantal', 15);
|
|
$page = (int)$request->get('pagina', 1);
|
|
if($count <= 0 || $page <= 0) {
|
|
return abort(400);
|
|
}
|
|
|
|
$result = $this->retrieveNewsItems($page, $count, $filter, []);
|
|
return response()->json(['page' => $page, 'count' => $count, 'news' => $result]);
|
|
}
|
|
|
|
public function retrieveNewsItems($page, $count, $filter, $params) {
|
|
$filterSql = "";
|
|
$params = ['category' => self::$NEWS_CATEGORY, 'secondarycategory' => self::$EXTERNAL_NEWS_CATEGORY];
|
|
if($filter) {
|
|
foreach($filter as $field => $value) {
|
|
$paramName = preg_replace('/[^A-Za-z0-9]/', '', $field);
|
|
$filterSql .= " AND $field = :$paramName";
|
|
$params[$paramName] = $value;
|
|
}
|
|
}
|
|
|
|
$start = ($page - 1) * $count;
|
|
$newsItems = app('db')->select(self::$BASE_SQL
|
|
. $filterSql
|
|
. ' ORDER BY COALESCE(`news`.`pubupdatedt`, `news`.`creationdt`) DESC'
|
|
. ' LIMIT ' . (int)$start . ', ' . (int)$count, $params);
|
|
|
|
$result = array();
|
|
foreach($newsItems as $newsItem) {
|
|
// Note: content is stored in the database with an additional addslashes() - don't ask why, just remove it :)
|
|
$newsItem->content = $newsItem->content;
|
|
$pictures = app('db')->select(self::$LOAD_IMAGES, ['newsId' => $newsItem->id]);
|
|
$result[] = new \Model\NewsItem($newsItem, $pictures);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function regionlist(Request $request, $region) {
|
|
return $this->newslist($request, ['`regions`.`slug`' => $region]);
|
|
}
|
|
|
|
public function themelist(Request $request, $theme) {
|
|
return $this->newslist($request, ['`themes`.`slug`' => $theme]);
|
|
}
|
|
|
|
public function findnews(Request $request, $query) {
|
|
$page = (int)$request->get('pagina', 1);
|
|
$count = (int)$request->get('aantal', 15);
|
|
if($page <= 0) {
|
|
return abort(400);
|
|
}
|
|
|
|
$start = ($page - 1) * $count;
|
|
$query = strip_tags(urldecode($query));
|
|
$newsItems = app('db')->select($s=self::$BASE_SQL
|
|
. ' AND MATCH(`content`.`title`, `content`.`content`) AGAINST(:query IN NATURAL LANGUAGE MODE)'
|
|
. ' ORDER BY COALESCE(`news`.`pubupdatedt`, `news`.`creationdt`) DESC'
|
|
. ' LIMIT ' . $start . ', ' . $count, [
|
|
'category' => self::$NEWS_CATEGORY,
|
|
'secondarycategory' => self::$EXTERNAL_NEWS_CATEGORY,
|
|
'query' => $query
|
|
]);
|
|
|
|
$result = array();
|
|
foreach($newsItems as $newsItem) {
|
|
// Note: content is stored in the database with an additional addslashes() - don't ask why, just remove it :)
|
|
$newsItem->content = $newsItem->content;
|
|
$pictures = app('db')->select(self::$LOAD_IMAGES, ['newsId' => $newsItem->id]);
|
|
$newsItem = new \Model\NewsItem($newsItem, $pictures);
|
|
$newsItem->title = \Helpers::HighlightQuery($query, $newsItem->title);
|
|
$newsItem->content = \Helpers::HighlightQuery($query, $newsItem->content);
|
|
$result[] = $newsItem;
|
|
}
|
|
|
|
return response()->json(['page' => $page, 'count' => 0, 'news' => $result, 'query' => $query]);
|
|
}
|
|
|
|
/**
|
|
* Agendaberichten ophalen
|
|
*/
|
|
public function calendarlist(Request $request) {
|
|
$today = new \DateTime('today');
|
|
$agendaItems = app('db')->select(self::$BASE_SQL
|
|
. ' AND `news`.`enddt` >= :today '
|
|
. ' ORDER BY `news`.`startdt` ASC, `news`.`enddt` ASC', ['category' => self::$CALENDAR_CATEGORY, 'secondarycategory' => 0, 'today' => $today]);
|
|
|
|
$result = array();
|
|
foreach($agendaItems as $agendaItem) {
|
|
// Note: content is stored in the database with an additional addslashes() - don't ask why, just remove it :)
|
|
$agendaItem->content = $agendaItem->content;
|
|
$pictures = app('db')->select(self::$LOAD_IMAGES, ['newsId' => $agendaItem->id]);
|
|
$result[] = new \Model\CalendarEvent($agendaItem, $pictures);
|
|
}
|
|
|
|
return response()->json($result);
|
|
}
|
|
|
|
/**
|
|
* Blogitems ophalen
|
|
*/
|
|
public function bloglist(Request $request, $from, $to) {
|
|
$count = (int)$request->get('aantal', 15);
|
|
$page = (int)$request->get('pagina', 1);
|
|
if($count <= 0 || $page <= 0) {
|
|
return abort(400);
|
|
}
|
|
|
|
$startIndex = ($page - 1) * $count;
|
|
$start = new \DateTime($from);
|
|
$end = new \DateTime($to);
|
|
$blogItems = app('db')->select($sql = self::$BASE_SQL
|
|
. ' AND `news`.`startdt` >= :start AND `news`.`startdt` <= :end '
|
|
. ' ORDER BY `news`.`startdt` DESC'
|
|
. ' LIMIT ' . (int)$startIndex . ', ' . (int)$count,
|
|
['category' => self::$BLOG_CATEGORY, 'secondarycategory' => 0, 'start' => $from, 'end' => $to]);
|
|
|
|
$result = array();
|
|
foreach($blogItems as $blogItem) {
|
|
// Note: content is stored in the database with an additional addslashes() - don't ask why, just remove it :)
|
|
$blogItem->content = $blogItem->content;
|
|
$pictures = app('db')->select(self::$LOAD_IMAGES, ['newsId' => $blogItem->id]);
|
|
if($blogItem->podcast_id > 0)
|
|
{
|
|
$podcast = app('db')->select(PodcastController::$BASE_SQL . ' AND `podcast`.`id` = :podcastId', ['podcastId' => $blogItem->podcast_id]);
|
|
$podcast = count($podcast) ? $podcast[0] : null;
|
|
}
|
|
else
|
|
{
|
|
$podcast = null;
|
|
}
|
|
|
|
$result[] = new \Model\NewsItem($blogItem, $pictures, $podcast);
|
|
}
|
|
|
|
return response()->json(['page' => $page, 'count' => $count, 'items' => $result]);
|
|
}
|
|
|
|
|
|
/**
|
|
* Populaire berichten ophalen
|
|
*/
|
|
public function popularNews(Request $request) {
|
|
return $this->popularInCategory($request, self::$NEWS_CATEGORY, self::$EXTERNAL_NEWS_CATEGORY);
|
|
}
|
|
|
|
public function popularCalendar(Request $request) {
|
|
return $this->popularInCategory($request, self::$CALENDAR_CATEGORY);
|
|
}
|
|
|
|
protected function popularInCategory(Request $request, $category, $secondarycategory = -1) {
|
|
$count = (int)$request->get('aantal', 5);
|
|
$recent = app('db')->select(<<<QUERY
|
|
SELECT `news`.`id`, COUNT(DISTINCT pagestats.visitor_ip) AS visitors
|
|
FROM news
|
|
INNER JOIN pagestats ON pagestats.type = :type AND pagestats.item_id = news.id
|
|
INNER JOIN `news_target_content` AS `content` ON `content`.`news` = `news`.`id`
|
|
WHERE `news`.`startdt` >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL :interval DAY)
|
|
AND (`news`.`category` = :category OR `news`.`category` = :secondarycategory) AND `content`.`target` = 1 AND `news`.`active` = 1 AND `content`.`active` = 1
|
|
GROUP BY news.id ORDER BY visitors DESC
|
|
LIMIT 0, :count
|
|
QUERY
|
|
, [
|
|
'type' => $category == self::$NEWS_CATEGORY ? 'nieuws'
|
|
: ( $category == self::$EXTERNAL_NEWS_CATEGORY ? 'nieuws'
|
|
: ($category == self::$CALENDAR_CATEGORY ? 'agenda'
|
|
: ( "" ) ) ),
|
|
'interval' => $category == self::$NEWS_CATEGORY ? 30
|
|
: ($category == self::$EXTERNAL_NEWS_CATEGORY ? 30
|
|
: ($category == self::$CALENDAR_CATEGORY ? 0
|
|
: 30 ) ),
|
|
'category' => $category,
|
|
'secondarycategory' => $secondarycategory,
|
|
'count' => $count
|
|
]);
|
|
|
|
$result = array();
|
|
foreach($recent as $item)
|
|
{
|
|
$newsItem = app('db')->select(self::$BASE_SQL . ' AND `news`.`id` = :newsId', ['category' => $category, 'secondarycategory' => $secondarycategory, 'newsId' => $item->id])[0];
|
|
$pictures = app('db')->select(self::$LOAD_IMAGES, ['newsId' => $newsItem->id]);
|
|
$result[] = new \Model\NewsItem($newsItem, $pictures);
|
|
}
|
|
|
|
return response()->json($result);
|
|
}
|
|
|
|
/**
|
|
* Specifiek nieuwsbericht ophalen
|
|
*/
|
|
public function newsitem($id) {
|
|
$item = $this->itemFromCategory(array(self::$NEWS_CATEGORY, self::$EXTERNAL_NEWS_CATEGORY), $id);
|
|
if(!$item) {
|
|
return abort(404);
|
|
}
|
|
|
|
$data = array('version' => 1,
|
|
'news' => new \Model\NewsItem($item['data'], $item['images'], $item['podcast']));
|
|
|
|
return response()->json($data);
|
|
}
|
|
|
|
/**
|
|
* Specifiek agendaitem ophalen
|
|
*/
|
|
public function calendaritem($id) {
|
|
$item = $this->itemFromCategory(self::$CALENDAR_CATEGORY, $id);
|
|
return $item ? response()->json(new \Model\CalendarEvent($item['data'], $item['images'], $item['podcast'])) : abort(404);
|
|
}
|
|
|
|
private function itemFromCategory($category, $id) {
|
|
$params = ['id' => (int)$id];
|
|
if(is_array($category)) {
|
|
$params['category'] = $category[0];
|
|
$params['secondarycategory'] = $category[1];
|
|
} else {
|
|
$params['category'] = $category;
|
|
$params['secondarycategory'] = 0;
|
|
}
|
|
$newsItem = app('db')->select(self::$BASE_SQL
|
|
. ' AND `news`.`id` = :id LIMIT 0, 1', $params);
|
|
|
|
if(count($newsItem) != 1) {
|
|
return null;
|
|
} else {
|
|
// Note: content is stored in the database with an additional addslashes() - don't ask why, just remove it :)
|
|
$newsItem[0]->content = $newsItem[0]->content;
|
|
$images = app('db')->select(self::$LOAD_IMAGES, ['newsId' => $id]);
|
|
$podcast = null;
|
|
if($newsItem[0]->podcast_id > 0)
|
|
{
|
|
$podcast = app('db')->select(PodcastController::$BASE_SQL . ' AND `podcast`.`id` = :podcastId', ['podcastId' => $newsItem[0]->podcast_id]);
|
|
$podcast = count($podcast) ? $podcast[0] : null;
|
|
}
|
|
|
|
return ['data' => $newsItem[0], 'images' => $images, 'podcast' => $podcast];
|
|
}
|
|
}
|
|
}
|