/**
  * Store a relation between 2 contributors.
  *
  * @param  \Illuminate\Http\Request $request
  * @return \Illuminate\Http\Response
  */
 public function follow(Request $request)
 {
     $contributor_id = $request->input('contributor_id');
     $following_id = $request->input('following_id');
     if ($contributor_id == $following_id) {
         return response()->json(['request_id' => uniqid(), 'status' => 'denied', 'message' => 'You cannot follow yourself', 'timestamp' => Carbon::now()], 400);
     }
     $isFollowing = Follower::whereContributorId($contributor_id)->whereFollowing($following_id)->count();
     if (!$isFollowing) {
         $follower = new Follower();
         $follower->contributor_id = $contributor_id;
         $follower->following = $following_id;
         if ($follower->save()) {
             $contributor = Contributor::findOrFail($contributor_id);
             $following = Contributor::findOrFail($following_id);
             Activity::create(['contributor_id' => $contributor_id, 'activity' => Activity::followActivity($contributor->username, $following->username)]);
             if ($following->email_follow) {
                 $follower->sendEmailNotification($contributor, $following);
             }
             return response()->json(['request_id' => uniqid(), 'status' => 'success', 'message' => $contributor->name . ' now is following ' . $following->name, 'timestamp' => Carbon::now()]);
         }
         return response()->json(['request_id' => uniqid(), 'status' => 'failure', 'message' => Lang::get('alert.database.generic'), 'timestamp' => Carbon::now()], 500);
     }
     return response()->json(['request_id' => uniqid(), 'status' => 'denied', 'message' => 'You already follow this contributor', 'timestamp' => Carbon::now()], 400);
 }
 /**
  * Store a relation between 2 contributors.
  *
  * @param  \Illuminate\Http\Request $request
  * @return \Illuminate\Http\Response
  */
 public function follow(Request $request)
 {
     /*
      * --------------------------------------------------------------------------
      * Perform follow request
      * --------------------------------------------------------------------------
      * This operation only for authenticate user, a contributor follow another
      * contributor, populate the data and make sure there is no record following
      * from contributor A to B before then perform insert data.
      */
     if (Auth::check() && $request->ajax()) {
         $contributor_id = Auth::user()->id;
         $following_id = $request->input('id');
         $isFollowing = Follower::whereContributorId($contributor_id)->whereFollowing($following_id)->count();
         if (!$isFollowing) {
             $follower = new Follower();
             $follower->contributor_id = $contributor_id;
             $follower->following = $following_id;
             if ($follower->save()) {
                 $following = Contributor::findOrFail($following_id);
                 /*
                  * --------------------------------------------------------------------------
                  * Create following activity
                  * --------------------------------------------------------------------------
                  * Create new instance of Activity and insert following activity.
                  */
                 Activity::create(['contributor_id' => $contributor_id, 'activity' => Activity::followActivity(Auth::user()->username, $following->username)]);
                 if ($following->email_follow) {
                     $follower->sendEmailNotification(Auth::user(), $following);
                 }
                 return response('success');
             }
             return response('failed', 500);
         }
         return response('success');
     } else {
         return response('restrict', 401);
     }
 }
 /**
  * Update the specified article in storage.
  *
  * @param  \Illuminate\Http\Request $request
  * @param param int $slug
  * @return \Illuminate\Http\Response
  */
 public function update(Request $request, $slug)
 {
     $validator = Validator::make($request->all(), ['featured' => 'mimes:jpg,jpeg,gif,png|max:1000']);
     if ($validator->fails()) {
         return response()->json(['request_id' => uniqid(), 'status' => 'denied', 'message' => "Featured must image and less than 1MB", 'timestamp' => Carbon::now()], 400);
     }
     $articleController = $this;
     $article = Article::whereSlug($slug)->firstOrFail();
     $exist = Article::whereSlug($request->input('slug'))->where('id', '!=', $article->id)->count();
     if ($exist) {
         return response()->json(['request_id' => uniqid(), 'status' => 'denied', 'message' => 'Unique slug has taken', 'timestamp' => Carbon::now()], 400);
     }
     $result = DB::transaction(function () use($request, $article, $articleController) {
         try {
             /*
              * --------------------------------------------------------------------------
              * Populate tags
              * --------------------------------------------------------------------------
              * Sync last tags and new article, extract tags from request, break down 
              * between new tags and tags that available in database, merge new inserted 
              * tag id with available tags id and remove the old which is removed.
              */
             $tag = Tag::whereIn('tag', explode(',', $request->get('tags')));
             $tags_id = $tag->pluck('id')->toArray();
             $available_tags = $tag->pluck('tag')->toArray();
             $new_tags = array_diff(explode(',', $request->get('tags')), $available_tags);
             $article->tags()->sync($tags_id);
             foreach ($new_tags as $tag_label) {
                 $newTag = new Tag();
                 $newTag->tag = $tag_label;
                 $newTag->save();
                 if (!$article->tags->contains($newTag->id)) {
                     $article->tags()->save($newTag);
                 }
             }
             /*
              * --------------------------------------------------------------------------
              * Update the article
              * --------------------------------------------------------------------------
              * Finally populate article data like create process and check if featured
              * need to change and upload the image then update the changes.
              */
             $autoApprove = Setting::whereKey('Auto Approve')->first();
             $content = $article->content;
             $content_update = $request->input('content');
             $status = $request->input('status');
             if ($autoApprove->value) {
                 $content = $request->input('content');
                 $content_update = '';
                 if ($status == 'pending') {
                     $status = 'published';
                 }
             }
             $article->subcategory_id = $request->input('subcategory_id');
             $article->title = $request->input('title');
             $article->slug = $request->input('slug');
             $article->type = $request->input('type');
             $article->content = $content;
             $article->content_update = $content_update;
             $article->excerpt = $request->input('excerpt');
             $article->status = $status;
             $image = new Uploader();
             if ($image->upload($request, 'featured', base_path('public/images/featured/'), 'featured_' . uniqid())) {
                 $article->featured = $request->input('featured');
             }
             $article->save();
             $contributor = Contributor::findOrFail($request->input('contributor_id'));
             Activity::create(['contributor_id' => $contributor->id, 'activity' => Activity::updateArticleActivity($contributor->username, $article->title, $article->slug)]);
             if (!$autoApprove->value) {
                 $articleController->sendAdminArticleNotification($contributor, $article, true);
             }
             return response()->json(['request_id' => uniqid(), 'status' => 'success', 'message' => 'Article was updated', 'auto_approve' => $autoApprove->value, 'timestamp' => Carbon::now()]);
         } catch (\Exception $e) {
             return response()->json(['request_id' => uniqid(), 'status' => 'failure', 'message' => Lang::get('alert.error.transaction'), 'timestamp' => Carbon::now()], 500);
         }
     });
     return $result;
 }
 /**
  * Obtain the user information from Twitter.
  *
  * @return Response
  */
 public function handleTwitterProviderCallback()
 {
     /*
      * --------------------------------------------------------------------------
      * Login with twitter
      * --------------------------------------------------------------------------
      * Initiating twitter driver and retrieve authenticate twitter login,
      * check if the user has been registered before, if they doesn't exist
      * create the new one then authenticating them and redirect.
      */
     $user = Socialite::driver('twitter')->user();
     $contributor = Contributor::whereVendor('twitter')->whereToken($user->id);
     if ($contributor->count() == 0) {
         /*
          * --------------------------------------------------------------------------
          * Populate twitter data
          * --------------------------------------------------------------------------
          * Collect the twitter basic data and create new contributor,
          * the data including banner as contributor cover, twitter avatar
          * as contributor avatar and twitter profile.
          */
         $contributor = new Contributor();
         $avatar = file_get_contents($user->avatar_original);
         file_put_contents('images/contributors/twitter-' . $user->id . '.jpg', $avatar);
         $cover = file_get_contents($user->user['profile_banner_url']);
         file_put_contents('images/covers/twitter-' . $user->id . '.jpg', $cover);
         $contributor->token = $user->id;
         $contributor->api_token = str_random(60);
         $contributor->name = $user->name;
         $contributor->username = $user->nickname . '.twitter';
         $contributor->password = Hash::make(uniqid());
         $contributor->email = $user->nickname . '@domain.com';
         $contributor->vendor = 'twitter';
         $contributor->status = 'activated';
         $contributor->location = $user->user['location'];
         $contributor->about = $user->user['description'];
         $contributor->twitter = 'https://twitter.com/' . $user->nickname;
         $contributor->avatar = 'twitter-' . $user->id . '.jpg';
         $contributor->cover = 'twitter-' . $user->id . '.jpg';
         $contributor->save();
         /*
          * --------------------------------------------------------------------------
          * Create register activity
          * --------------------------------------------------------------------------
          * Create new instance of Activity and insert register activity.
          */
         Activity::create(['contributor_id' => $contributor->id, 'activity' => Activity::registerActivity($contributor->username, 'twitter')]);
         $this->sendAdminContributorNotification($contributor);
     }
     Auth::login($contributor->first());
     return redirect()->route('account.stream');
 }
 /**
  * Send message email notification.
  *
  * @param $sender
  * @param $receiver
  * @param $message
  */
 public function sendEmailNotification($sender, $receiver, $message)
 {
     /*
      * --------------------------------------------------------------------------
      * Create sending message activity
      * --------------------------------------------------------------------------
      * Create new instance of Activity and insert following activity.
      */
     Activity::create(['contributor_id' => $sender->id, 'activity' => Activity::sendingMessageActivity($sender->username, $receiver->username)]);
     $data = ['receiverName' => $receiver->name, 'receiverUsername' => $receiver->username, 'receiverMessage' => $message, 'senderName' => $sender->name, 'senderLocation' => $sender->location, 'senderUsername' => $sender->username, 'senderAvatar' => $sender->avatar, 'senderArticle' => $sender->articles()->count(), 'senderFollower' => $sender->followers()->count(), 'senderFollowing' => $sender->following()->count()];
     Mail::send('emails.message', $data, function ($message) use($sender, $receiver) {
         $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id'));
         $message->replyTo('*****@*****.**', env('MAIL_NAME', 'Infogue.id'));
         $message->to($receiver->email)->subject($sender->name . ' sent you a message');
     });
 }
 /**
  * Register via twitter.
  *
  * @param Request $request
  * @return mixed
  */
 public function registerTwitter(Request $request)
 {
     $twitterId = $request->input('id');
     $contributor = Contributor::whereVendor('twitter')->whereToken($twitterId)->first();
     if (empty($contributor)) {
         $isInvalid = Contributor::whereEmail($request->input('email'))->orWhere('username', '=', $request->input('username'))->first();
         if ($isInvalid) {
             return response()->json(['request_id' => uniqid(), 'status' => 'exist', 'login' => 'restrict', 'message' => 'Email is already exist, registered via ' . $isInvalid->vendor, 'timestamp' => Carbon::now()], 400);
         }
         $contributor = new Contributor();
         $cover = file_get_contents($request->input('cover'));
         file_put_contents('images/covers/twitter-' . $twitterId . '.jpg', $cover);
         $avatar = file_get_contents($request->input('avatar'));
         file_put_contents('images/contributors/twitter-' . $twitterId . '.jpg', $avatar);
         $contributor->token = $twitterId;
         $contributor->api_token = str_random(60);
         $contributor->name = $request->input('name');
         $contributor->username = $request->input('username');
         $contributor->password = Hash::make(uniqid());
         $contributor->email = $request->input('username') . '@twitter.com';
         $contributor->vendor = 'twitter';
         $contributor->status = 'activated';
         $contributor->location = $request->input('location');
         $contributor->about = $request->input('about');
         $contributor->twitter = 'https://www.twitter.com/' . $request->input('username');
         $contributor->avatar = 'twitter-' . $twitterId . '.jpg';
         $contributor->cover = 'twitter-' . $twitterId . '.jpg';
         if ($contributor->save()) {
             Activity::create(['contributor_id' => $contributor->id, 'activity' => Activity::registerActivity($contributor->username, 'twitter')]);
             $this->sendAdminContributorNotification($contributor);
             $facebookUser = Contributor::whereToken($twitterId)->firstOrFail();
             $user = $contributor->profile($facebookUser->username, true);
             $user->article_total = $user->articles()->where('status', 'published')->count();
             $user->followers_total = $user->followers()->count();
             $user->following_total = $user->following()->count();
             return response()->json(['request_id' => uniqid(), 'status' => $user->status, 'login' => 'granted', 'message' => 'Registering twitter is success', 'timestamp' => Carbon::now(), 'user' => $user], 200);
         } else {
             return response()->json(['request_id' => uniqid(), 'status' => 'failure', 'login' => 'restrict', 'message' => Lang::get('alert.database.generic'), 'timestamp' => Carbon::now()], 500);
         }
     } else {
         $user = $contributor->profile($contributor->username, true);
         $user->article_total = $user->articles()->where('status', 'published')->count();
         $user->followers_total = $user->followers()->count();
         $user->following_total = $user->following()->count();
         return response()->json(['request_id' => uniqid(), 'status' => $user->status, 'login' => 'granted', 'message' => 'Login twitter is success', 'timestamp' => Carbon::now(), 'user' => $user], 200);
     }
 }
 /**
  * Update the old password and authenticate.
  *
  * @param $user
  * @param $password
  */
 protected function resetPassword($user, $password)
 {
     /*
      * --------------------------------------------------------------------------
      * Update password
      * --------------------------------------------------------------------------
      * Hash new password and update database related the user. Create new
      * instance of Activity and insert reset password activity.
      */
     $user->password = bcrypt($password);
     $user->save();
     Activity::create(['contributor_id' => $user->id, 'activity' => Activity::resetPasswordActivity($user->username)]);
     /*
      * --------------------------------------------------------------------------
      * Send email notification
      * --------------------------------------------------------------------------
      * Make sure user is noticed by email information that they recently change
      * their password.
      */
     Mail::send('emails.reset', ['name' => $user->name], function ($message) use($user) {
         $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id'));
         $message->replyTo('*****@*****.**', env('MAIL_NAME', 'Infogue.id'));
         $message->to($user->email)->subject('Password has been reset');
     });
     Auth::guard($this->getGuard())->login($user);
 }
 /**
  * Remove the specified article from storage.
  *
  * @param  int $id
  * @return \Illuminate\Http\Response
  */
 public function destroy($id)
 {
     /*
      * --------------------------------------------------------------------------
      * Delete article activity
      * --------------------------------------------------------------------------
      * Find and destroy then create new instance of Activity and insert delete
      * article activity, finally redirect to list of articles.
      */
     $article = Article::findOrFail($id);
     if ($article->delete()) {
         Activity::create(['contributor_id' => Auth::user()->id, 'activity' => Activity::deleteArticleActivity(Auth::user()->username, $article->title, $article->slug)]);
         return redirect(route('account.article.index'))->with(['status' => 'warning', 'message' => Lang::get('alert.article.delete', ['title' => $article->title])]);
     }
     return redirect()->back()->withErrors(['error' => Lang::get('alert.error.database')]);
 }