summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhorus2020-04-11 19:44:37 +0200
committerhorus2020-04-11 19:44:37 +0200
commit3afd5b2fd1f217f12ecad465449524fe93cacf09 (patch)
tree0e495bb39f3f2c27b7bd2a53b5ffb1daab06057c
parent6bb11edffaa0850f741022b608a4c032986b45c4 (diff)
downloadcurious-3afd5b2fd1f217f12ecad465449524fe93cacf09.tar.gz
Adds RSS- and Atom-Feeds.
-rw-r--r--app/Http/Controllers/FeedController.php67
-rw-r--r--app/Libraries/Helper.php73
-rw-r--r--composer.json3
-rw-r--r--composer.lock68
-rw-r--r--public/img/rss-square.svg1
-rw-r--r--public/img/rss.svg1
-rw-r--r--resources/views/layouts/app.blade.php5
-rw-r--r--resources/views/list.blade.php14
-rw-r--r--routes/web.php6
9 files changed, 234 insertions, 4 deletions
diff --git a/app/Http/Controllers/FeedController.php b/app/Http/Controllers/FeedController.php
new file mode 100644
index 0000000..9fd73a5
--- /dev/null
+++ b/app/Http/Controllers/FeedController.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\DB;
+use App\Article;
+use App\Discussion;
+use App\Category;
+use App\Libraries\Helper;
+
+class FeedController extends Controller
+{
+
+ public function new()
+ {
+ // creating rss feed with our most recent 20 posts
+ $articles = Article::orderBy('created_at', 'desc')->take(20)->get();
+ return Helper::makeFeed($articles, "new");
+ }
+
+ public function popular()
+ {
+
+ $articles = new Article;
+ $articles = $articles->setTable('view_popular');
+ $articles = $articles->take(20)->get();
+ return Helper::makeFeed($articles, "popular");
+ }
+
+ public function search(Request $request) {
+ $search_unsafe = $request->input("q");
+
+ if ( "" == $search_unsafe ) {
+ $search_unsafe = "";
+ }
+
+ $search_unsafe = explode(",", $request->input("q"));
+
+ $articles = new Article;
+
+ if ( "on" == $request->input("onlypopular") ) {
+ $articles = $articles->setTable('view_popular');
+ }
+
+ foreach($search_unsafe as $q) {
+ $q = Helper::escapeLike($q);
+ $q = "%".$q."%";
+ $articles = $articles->where(function ($query) use ($q) {
+ $query->whereHas('getCategories', function ($query) use ($q){
+ $query->where('name', 'like', $q);
+ })
+ ->orWhere('title', 'like', $q)
+ ->orWhere('url', 'like', $q)
+ ->orWhere('excerpt_html', 'like', $q);
+ });
+ }
+ $count = $articles->count();
+
+ if ( "on" == $request->input("onlypopular") ) {
+ $articles = $articles->orderBy('impact', 'desc');
+ }
+ $articles = $articles->orderBy('created_at', 'desc');
+
+ return Helper::makeFeed($articles->take(20)->get(), $request->input("q"));
+ }
+}
diff --git a/app/Libraries/Helper.php b/app/Libraries/Helper.php
index d85d216..69e7de6 100644
--- a/app/Libraries/Helper.php
+++ b/app/Libraries/Helper.php
@@ -15,4 +15,77 @@ class Helper {
public static function formatTimestamp($timestamp) {
return Carbon::createFromTimestamp($timestamp)->format("Y-m-d");
}
+
+ public static function makeFeed($model, $title, $cache = 60) {
+
+ switch($title) {
+ case("new"):
+ $feed_title = 'Newest Articles';
+ $feed_description = 'Newest interesting articles from Wikipedia. Keep exploring.';
+ break;
+ case( "popular"):
+ $feed_title = 'Popular Articles';
+ $feed_description = 'The most popular articles. Keep exploring.';
+ break;
+ default:
+ $feed_title = 'Search for: ' . $title;
+ $feed_description = 'All articles for "' . $title . '".';
+ break;
+ }
+ // create new feed
+ $feed = \App::make("feed");
+
+ // multiple feeds are supported
+ // if you are using caching you should set different cache keys for your feeds
+
+ // cache the feed for $cache minutes (second parameter is optional)
+ $feed->setCache($cache, 'feed_' . $title);
+
+ // check if there is cached feed and build new only if is not
+ if (!$feed->isCached())
+ {
+
+ // set your feed's title, description, link, pubdate and language
+ $feed->title = $feed_title;
+ $feed->description = $feed_description;
+ #$feed->logo = 'http://yoursite.tld/logo.jpg';
+ $feed->link = url('feed/' . $title);
+ $feed->setDateFormat('datetime'); // 'datetime', 'timestamp' or 'carbon'
+ $feed->pubdate = $model[0]->created_at;
+ $feed->lang = 'en';
+ $feed->setShortening(true); // true or false
+ $feed->setTextLimit(100); // maximum length of description text
+
+ foreach ($model as $post)
+ {
+
+ $desc = ($post->excerpt_html);
+
+ $categories = "<br>";
+ foreach( $post->getCategories()->get() as $cat ) {
+ $categories .= "<a href='". \URL::to('/topic/' . $cat->name) ."'>". $cat->name . "</a> | ";
+ }
+ $categories = rtrim($categories, " | ");
+ $desc .= "<br>Topics:";
+ $desc .= $categories;
+
+ $discussions = "<br>";
+ foreach( $post->getDiscussions()->orderBy('comments', 'desc')->get() as $dis ) {
+ $discussions .= "<a href='" . $dis->source_url . "'>" . $dis->title . "</a> ";
+ $discussions .= $dis->upvotes . " Upvotes | " . $dis->comments . " Comments<br>";
+ }
+ $desc .= "<br><br>Discussions:";
+ $desc .= $discussions;
+
+ // set item's title, author, url, pubdate, description, content, enclosure (optional)*
+ $feed->add($post->title, env('APP_NAME'), \URL::to($post->url), $post->created_at, $desc, $desc);
+ }
+
+ }
+
+ // first param is the feed format
+ // optional: second param is cache duration (value of 0 turns off caching)
+ // optional: you can set custom cache key with 3rd param as string
+ return $feed->render('atom', $cache, 'feed_' . $title);
+ }
}
diff --git a/composer.json b/composer.json
index afb27a9..6952835 100644
--- a/composer.json
+++ b/composer.json
@@ -13,7 +13,8 @@
"fruitcake/laravel-cors": "^1.0",
"guzzlehttp/guzzle": "^6.3",
"laravel/framework": "^7.0",
- "laravel/tinker": "^2.0"
+ "laravel/tinker": "^2.0",
+ "laravelium/feed": "^7.0"
},
"require-dev": {
"facade/ignition": "^2.0",
diff --git a/composer.lock b/composer.lock
index df443cd..837d032 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "content-hash": "5cb6e369ed424d05439b41685b0d3441",
+ "content-hash": "d5d6501f3e93b2aa424fb9448c79439d",
"packages": [
{
"name": "asm89/stack-cors",
@@ -683,6 +683,7 @@
"email": "jakub.onderka@gmail.com"
}
],
+ "abandoned": "php-parallel-lint/php-console-color",
"time": "2018-09-29T17:23:10+00:00"
},
{
@@ -729,6 +730,7 @@
}
],
"description": "Highlight PHP code in terminal",
+ "abandoned": "php-parallel-lint/php-console-highlighter",
"time": "2018-09-29T18:48:56+00:00"
},
{
@@ -947,6 +949,70 @@
"time": "2020-03-17T15:34:59+00:00"
},
{
+ "name": "laravelium/feed",
+ "version": "v7.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://gitlab.com/Laravelium/Feed.git",
+ "reference": "e7f108f49abec3a3c836636a5c8fb1d3b8d3d1d7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://gitlab.com/api/v4/projects/Laravelium%2FFeed/repository/archive.zip?sha=e7f108f49abec3a3c836636a5c8fb1d3b8d3d1d7",
+ "reference": "e7f108f49abec3a3c836636a5c8fb1d3b8d3d1d7",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/filesystem": "^7.0",
+ "illuminate/support": "^7.0",
+ "php": ">=7.2.5"
+ },
+ "require-dev": {
+ "laravel/framework": "^7.0",
+ "orchestra/testbench-core": "^5.0",
+ "phpunit/phpunit": "^8.0"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Laravelium\\Feed\\FeedServiceProvider"
+ ],
+ "aliases": {
+ "Feed": "Laravelium\\Feed\\Feed"
+ }
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Laravelium\\Feed": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Rumen Damyanov",
+ "email": "r@alfamatter.com",
+ "homepage": "https://darumen.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "Laravelium Feed package for Laravel.",
+ "homepage": "https://gitlab.com/Laravelium",
+ "keywords": [
+ "atom",
+ "feed",
+ "generator",
+ "laravel",
+ "laravelium",
+ "rss"
+ ],
+ "time": "2020-03-28T12:53:42+00:00"
+ },
+ {
"name": "league/commonmark",
"version": "1.3.1",
"source": {
diff --git a/public/img/rss-square.svg b/public/img/rss-square.svg
new file mode 100644
index 0000000..ff9a15a
--- /dev/null
+++ b/public/img/rss-square.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM112 416c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm157.533 0h-34.335c-6.011 0-11.051-4.636-11.442-10.634-5.214-80.05-69.243-143.92-149.123-149.123-5.997-.39-10.633-5.431-10.633-11.441v-34.335c0-6.535 5.468-11.777 11.994-11.425 110.546 5.974 198.997 94.536 204.964 204.964.352 6.526-4.89 11.994-11.425 11.994zm103.027 0h-34.334c-6.161 0-11.175-4.882-11.427-11.038-5.598-136.535-115.204-246.161-251.76-251.76C68.882 152.949 64 147.935 64 141.774V107.44c0-6.454 5.338-11.664 11.787-11.432 167.83 6.025 302.21 141.191 308.205 308.205.232 6.449-4.978 11.787-11.432 11.787z"/></svg> \ No newline at end of file
diff --git a/public/img/rss.svg b/public/img/rss.svg
new file mode 100644
index 0000000..e6fa54c
--- /dev/null
+++ b/public/img/rss.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M128.081 415.959c0 35.369-28.672 64.041-64.041 64.041S0 451.328 0 415.959s28.672-64.041 64.041-64.041 64.04 28.673 64.04 64.041zm175.66 47.25c-8.354-154.6-132.185-278.587-286.95-286.95C7.656 175.765 0 183.105 0 192.253v48.069c0 8.415 6.49 15.472 14.887 16.018 111.832 7.284 201.473 96.702 208.772 208.772.547 8.397 7.604 14.887 16.018 14.887h48.069c9.149.001 16.489-7.655 15.995-16.79zm144.249.288C439.596 229.677 251.465 40.445 16.503 32.01 7.473 31.686 0 38.981 0 48.016v48.068c0 8.625 6.835 15.645 15.453 15.999 191.179 7.839 344.627 161.316 352.465 352.465.353 8.618 7.373 15.453 15.999 15.453h48.068c9.034-.001 16.329-7.474 16.005-16.504z"/></svg> \ No newline at end of file
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php
index a9cbf37..5671edb 100644
--- a/resources/views/layouts/app.blade.php
+++ b/resources/views/layouts/app.blade.php
@@ -22,6 +22,9 @@
<style>
@yield('styles')
</style>
+ @if ( "new" == Request::route()->getName() || "popular" == Request::route()->getName() )
+ {!! \Feed::link( url('feed/' . Request::route()->getName()), 'atom', 'RSS-Feed for ' . Request::route()->getName() . ' Articles'); !!}
+ @endif
</head>
<body>
<div id="app">
@@ -55,7 +58,7 @@
</li>
@endif
<li class="nav-item">
- <a class="nav-link" href="{{ route('newest') }}">{{ __('New') }}</a>
+ <a class="nav-link" href="{{ route('new') }}">{{ __('New') }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ route('popular') }}">{{ __('Popular') }}</a>
diff --git a/resources/views/list.blade.php b/resources/views/list.blade.php
index 5a5949a..f47c28a 100644
--- a/resources/views/list.blade.php
+++ b/resources/views/list.blade.php
@@ -13,6 +13,15 @@ html {
vertical-align: -.125em;
fill: #ff6600;
}
+
+.rss-link > svg {
+ display: inline-block;
+ font-size: inherit;
+ height: 1em;
+ overflow: visible;
+ vertical-align: -.125em;
+ fill: #f59436;
+}
@endif
@endsection
@@ -64,6 +73,11 @@ html {
@if ( "1" != $articles->currentPage() )
(Page {{ $articles->currentPage() }})
@endif
+ <div class="float-right">
+ <a class="rss-link" href="{{ route('feed_' . Request::route()->getName()) }}" title="RSS-Feed">
+ {!! file_get_contents(public_path() . "/img/rss-square.svg") !!}
+ </a>
+ </div>
</h1>
@endif
diff --git a/routes/web.php b/routes/web.php
index 745f9bb..79615a6 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -16,11 +16,15 @@ use Illuminate\Support\Facades\Route;
Route::get('/', 'IndexController@index')->name('index');
Route::get('/topic/{topic}', 'IndexController@topic')->name('topic')->where('topic', '(.+)');
Route::get('/topic/', 'IndexController@topicindex')->name('topic_index');
-Route::get('/new', 'IndexController@new')->name('newest');
+Route::get('/new', 'IndexController@new')->name('new');
Route::get('/search', 'IndexController@search')->name('search');
Route::get('/popular', 'IndexController@popular')->name('popular');
Route::get('/random', 'IndexController@random')->name('random');
+Route::get('/feed/new', 'FeedController@new')->name('feed_new');
+Route::get('/feed/popular', 'FeedController@popular')->name('feed_popular');
+Route::get('/feed/search', 'FeedController@search')->name('feed_search');
+
#Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');