PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/app/Http/Controllers/ArticlesController.php

https://gitlab.com/forby/Trace
PHP | 476 lines | 233 code | 81 blank | 162 comment | 25 complexity | 6cf9e4d46e52207e814a0c9c5845b643 MD5 | raw file
  1. <?php namespace App\Http\Controllers;
  2. use App;
  3. use Auth;
  4. use File;
  5. use Mail;
  6. use App\Tag;
  7. use App\User;
  8. //use Request;
  9. use Response;
  10. use App\Article;
  11. use App\Category;
  12. use App\Http\Requests;
  13. use App\Http\Controllers\Controller;
  14. use App\Http\Requests\ArticleRequest;
  15. use Illuminate\Http\Request;
  16. class ArticlesController extends Controller {
  17. public function __construct()
  18. {
  19. // limit public view
  20. $this->middleware('auth');
  21. }
  22. /**
  23. * Display the archive of articles, 10 to a page
  24. *
  25. * @return Response
  26. */
  27. public function index()
  28. {
  29. // Get the articles
  30. $articles = Article::published()->latest()->paginate(10);
  31. // Get top tags
  32. $top_tags = Tag::getTopTags()->take(10);
  33. return view('articles.index', compact('articles', 'top_tags'));
  34. }
  35. /**
  36. * Show the form for creating a new resource.
  37. *
  38. * @return Response
  39. */
  40. public function create()
  41. {
  42. // Get the user
  43. $user = Auth::user();
  44. // Make a list of users for the select box
  45. $users = User::get()->lists('name', 'id');
  46. // Get the list of tags
  47. $tags = Tag::lists('name', 'id')->all();
  48. // Get the list of categories
  49. $categories = Category::lists('name', 'id')->all();
  50. // Show the view
  51. return view('articles.create', compact('tags', 'categories', 'user', 'users'));
  52. }
  53. /**
  54. * Store a newly created resource in storage.
  55. *
  56. * @return Response
  57. */
  58. public function store( ArticleRequest $request )
  59. {
  60. $user = '';
  61. // Get the user
  62. // If not live, allow admins to post as other users
  63. if ( App::environment('local', 'staging') && $request->has('post_as') ) {
  64. $user = User::find( $request->get('post_as') );
  65. } else {
  66. $user = Auth::user();
  67. }
  68. // Create and Save a new article
  69. $this->createArticle( $request, $user );
  70. // Reindex Tags
  71. Tag::reindex();
  72. // TODO: send email to editors?
  73. // show the pending response
  74. return redirect()->action('ArticlesController@pending');
  75. }
  76. /**
  77. * Display the specified resource.
  78. * Article is injected through Route Model Binding
  79. *
  80. * @param int $id
  81. * @return Response
  82. */
  83. public function show( $article )
  84. {
  85. // Get a list of this article's tags
  86. $tag_ids = $article->tags()->lists('id')->all();
  87. // Find articles in those tags, except for this tag
  88. // Sort them randomly
  89. $relatedArticles = Article::published()->where('id', '!=', $article->id)
  90. ->whereHas('tags', function($q) use ($tag_ids) {
  91. $q->whereIn('id', $tag_ids);
  92. })
  93. ->orderByRaw('RAND()')
  94. ->take(3)
  95. ->get();
  96. $user = Auth::user();
  97. return view('articles.show', compact('article', 'relatedArticles', 'user'));
  98. }
  99. /**
  100. * Show the form for editing the specified resource.
  101. *
  102. * @param int $id
  103. * @return Response
  104. */
  105. public function edit( Article $article )
  106. {
  107. // Get the tags of the article
  108. $tags = Tag::lists('name', 'id')->all();
  109. // Get the categories
  110. $categories = Category::lists('name', 'id')->all();
  111. // Get the currently logged in user
  112. $user = Auth::user();
  113. // Show the edit view
  114. return view ('articles.edit', compact('article', 'tags', 'categories', 'user'));
  115. }
  116. /**
  117. * Update the specified resource in storage.
  118. *
  119. * @param int $id
  120. * @return Response
  121. */
  122. public function update( Article $article, ArticleRequest $request )
  123. {
  124. // Save the image
  125. $this->savePhoto( $request, $article);
  126. // Unpublish the article
  127. if ( $request->has('published') )
  128. {
  129. $request->repalce(['published' => false]);
  130. } else {
  131. $request->merge(['published' => false]);
  132. }
  133. // Update the article in DB
  134. $article->update( $request->all() );
  135. // Sync up the tags
  136. $this->syncTags( $article, $request->input('tag_list') );
  137. // Reindex Tags
  138. Tag::reindex();
  139. // show the pending response
  140. return redirect()->action('ArticlesController@pending');
  141. // TODO:
  142. // - Show a message that it has been sent for review
  143. }
  144. /**
  145. * Remove the specified resource from storage.
  146. *
  147. * @param int $id
  148. * @return Response
  149. */
  150. public function destroy( Article $article, Request $request )
  151. {
  152. if ( Auth::user()->can('moderate-story') )
  153. {
  154. // Bye :(
  155. $article->delete();
  156. // Reindex Tags
  157. Tag::reindex();
  158. }
  159. if ( $request->ajax() )
  160. {
  161. return Response::json([
  162. 'url' => url('/approve')
  163. ], 200);
  164. } else {
  165. return redirec('/approve');
  166. }
  167. }
  168. /**
  169. * Approve and Publish an article
  170. */
  171. public function publish( $article )
  172. {
  173. // Get the user
  174. $user = Auth::user();
  175. // Only approve if you have the permissions
  176. if ( $user->can('moderate-story') )
  177. {
  178. $article->published = true;
  179. $article->save();
  180. // Send email to author
  181. // if user is not the author
  182. $author = $article->user;
  183. if ( $user->id !== $author->id ) {
  184. if ( $author->email ) {
  185. Mail::send('emails.published', compact('author', 'article'), function( $message ) use ( $author ) {
  186. $message->to($author->email, $author->name);
  187. $message->subject('Your article has been published');
  188. });
  189. }
  190. }
  191. // Reindex Tags
  192. Tag::reindex();
  193. }
  194. return redirect('/approve');
  195. }
  196. /**
  197. * Send the request from an ajax request
  198. * and return json response
  199. */
  200. public function sendRequest( Article $article, Request $request )
  201. {
  202. if ( Auth::user()->can('moderate-story') ) {
  203. // Get the body of the message
  204. $body = $request->get('message');
  205. // And the author
  206. $author = $article->user;
  207. // send mail to author
  208. if ( $author->email ) {
  209. Mail::send('emails.request-edits', compact('body','author', 'article'), function( $message ) use ( $author ) {
  210. $message->to($author->email, $author->name);
  211. $message->subject('A few things about your article...');
  212. });
  213. }
  214. // Flash the message
  215. // flash()->success('Your message has been sent!');
  216. // Success
  217. return Response::json( 'success', 200 );
  218. }
  219. // Return Error
  220. return Response::json( 'error', 400 );
  221. }
  222. /**
  223. * Show a 'Thanks' message to the user
  224. * after they have created or edited an article
  225. */
  226. public function pending()
  227. {
  228. return view('articles.pending');
  229. }
  230. /**
  231. * API request for liking an article.
  232. *
  233. * @param int $article
  234. */
  235. public function bump( $article )
  236. {
  237. // Like the Article
  238. // Uses currently logged in user.
  239. $article->like();
  240. // return proof
  241. if ( $article->liked() )
  242. {
  243. // Get author
  244. $author = $article->user;
  245. // Get the current user
  246. $user = Auth::user();
  247. // Send email to the author
  248. // if they are not the bumper
  249. // and only if they want emails
  250. if ( ($user->id !== $author->id) && ($author->email_notify) ) {
  251. if ( $author->email ) {
  252. Mail::send('emails.bump', compact('article'), function( $message ) use ( $author ) {
  253. $message->to($author->email, $author->name);
  254. $message->subject('You\'ve been bumped!');
  255. });
  256. }
  257. }
  258. return Response::json( [
  259. 'count' => $article->likeCount
  260. ], 200 );
  261. }
  262. // Error if not liked
  263. return Response::json('error', 400);
  264. }
  265. /**
  266. * API request for un-liking an article.
  267. *
  268. * @param int $article
  269. */
  270. public function unbump( $article )
  271. {
  272. // Like the Article
  273. // Uses currently logged in user.
  274. $article->unlike();
  275. // return proof
  276. if ( ! $article->liked() )
  277. {
  278. return Response::json( [
  279. 'count' => $article->likeCount
  280. ], 200 );
  281. }
  282. // Error if not liked
  283. return Response::json('error', 400);
  284. }
  285. /**
  286. * API request for featuring an article
  287. */
  288. public function toggleFeature( Request $request )
  289. {
  290. // Should you be here?
  291. if ( ! Auth::user()->can('set-featured-content') ) {
  292. return Response::json('error', 400);
  293. }
  294. // Find article and feature it
  295. // Article::find( Request::get('id') )->feature();
  296. $article = Article::find( $request->get('id') );
  297. $result = $article->toggleFeatured();
  298. $classes = $article->featureClasses;
  299. return Response::json([
  300. 'classes' => $classes
  301. ], 200 );
  302. }
  303. /**
  304. * Create and save an article object from a request
  305. *
  306. * @param ArticleRequest $request
  307. * @return Article
  308. */
  309. private function createArticle( ArticleRequest $request, $user )
  310. {
  311. // Create the article from the request input
  312. $article = $user->articles()->create( $request->all() );
  313. // Sync up tags too
  314. $this->syncTags( $article, $request->input('tag_list') );
  315. // Save the Image to the server
  316. $this->savePhoto( $request, $article );
  317. return $article;
  318. }
  319. /**
  320. * Perform sync an article's tags
  321. *
  322. * @param Article $article
  323. * @param array $tags
  324. * @return null
  325. */
  326. private function syncTags( Article $article, array $tags=null )
  327. {
  328. $tag_ids = array();
  329. // create any new tags if they don't exist
  330. if ( $tags ) {
  331. foreach ( $tags as $tag ) {
  332. if ( ! Tag::find( $tag ) ) {
  333. $new = Tag::create(['name' => $tag]);
  334. array_push( $tag_ids, strval($new->id) );
  335. } else {
  336. array_push( $tag_ids, $tag );
  337. }
  338. }
  339. }
  340. // Sync the tags
  341. $article->tags()->sync( $tag_ids );
  342. }
  343. /**
  344. * Save article feature photo
  345. */
  346. private function savePhoto( $request, $article )
  347. {
  348. // Save the new file and reference
  349. if ( $request->hasFile('photo') )
  350. {
  351. // Get the Photo
  352. $photo = $request->file('photo');
  353. // Get full filename, like 'name.jpg'
  354. $name = $photo->getClientOriginalName();
  355. // Add an ending id, like 'name_id14.jpg'
  356. $ending_id = '_id' . $article->id;
  357. $new_name = substr_replace($name, $ending_id, strrpos($name, '.'), 0);
  358. // Move Save the photo to 'img/articles/name_id14.jpg'
  359. $photo->move('img/articles', $new_name);
  360. // Remove the old photo file
  361. if ( $article->photo )
  362. {
  363. $this->deletePhoto( $article->photo );
  364. }
  365. // Store the reference to the image
  366. // with a full URL path
  367. $article->photo = url('img/articles/' . $new_name);
  368. $article->save();
  369. }
  370. }
  371. /**
  372. * Remove the URL from an image location
  373. */
  374. private static function removeUrlFromPath( $path )
  375. {
  376. return substr( $path, strpos( $path, 'img' ) );
  377. }
  378. /**
  379. * Delete a photo from the filesystem
  380. */
  381. public function deletePhoto( $path ) {
  382. $filePath = public_path() . '/' . $this->removeUrlFromPath( $path );
  383. if ( File::exists( $filePath ) ) {
  384. File::delete( $filePath );
  385. }
  386. }
  387. /**
  388. * Top Stories Page
  389. */
  390. public function topStories()
  391. {
  392. $articles = Article::getTopArticles()->take(20);
  393. return view('articles.top', compact('articles'));
  394. }
  395. }