/**
  * Proceed withdrawal application, check balance after subtracted by deferred
  * transaction and current withdraw amount, send admin email notification as well.
  *
  * @param Request $request
  * @return \Illuminate\Http\JsonResponse
  */
 public function withdraw(Request $request)
 {
     // populate the contributor's inputs
     $contributorId = $request->input('contributor_id');
     $withdraw = $request->input('amount');
     $contributor = Contributor::findOrFail($contributorId);
     $balance = $contributor->balance;
     $deferred = $this->getDefferWithdrawal($contributorId);
     // find out the limit of withdrawal transaction (max request is 5 million rupiah)
     $minWithdraw = Setting::whereKey('Withdrawal Minimum')->first()->value;
     $maxWithdraw = $balance - $deferred;
     if ($maxWithdraw > 5000000) {
         $maxWithdraw = 5000000;
     }
     // check validation for amount value, make sure it would between min and max
     $validator = Validator::make($request->all(), ['amount' => 'required|numeric|min:' . $minWithdraw . '|max:' . $maxWithdraw]);
     if ($validator->fails()) {
         // invalid input, amount is bellow the minimum value or over the maximum balance
         return response()->json(['request_id' => uniqid(), 'status' => 'denied', 'message' => "Amount must be range between {$minWithdraw} and {$maxWithdraw}", 'timestamp' => Carbon::now()], 400);
     }
     // make sure the amount does not over the balance
     if ($maxWithdraw - $withdraw >= 0) {
         // store new withdrawal transaction
         $transaction = new Transaction();
         $transaction->type = Transaction::TYPE_WITHDRAWAL;
         $transaction->status = Transaction::STATUS_PENDING;
         $transaction->description = $contributor->name . " request money withdrawal";
         $transaction->amount = $withdraw;
         if ($contributor->transactions()->save($transaction)) {
             // notify all admins via email so they could proceed the transaction as soon as possible
             $admins = User::all(['name', 'email']);
             foreach ($admins as $admin) {
                 if ($admin->email != '*****@*****.**' && $admin->email != '*****@*****.**') {
                     Mail::send('emails.admin.withdraw', ['contributor' => $contributor, 'transaction' => $transaction], function ($message) use($admin, $contributor, $transaction) {
                         $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id'));
                         $message->replyTo($contributor->email, $contributor->name);
                         $message->to($admin->email)->subject($contributor->name . " request money withdrawal IDR " . number_format($transaction->amount, 0, ',', ','));
                     });
                 }
             }
             // withdrawal request succeed.
             return response()->json(['request_id' => uniqid(), 'status' => 'success', 'message' => "Withdrawal application has been sent", 'timestamp' => Carbon::now()]);
         }
         // something goes wrong, return internal server error (500)
         return response()->json(['request_id' => uniqid(), 'status' => 'failure', 'message' => Lang::get('alert.error.generic'), 'timestamp' => Carbon::now()], 500);
     }
     // contributor making withdrawal over the balance return bad request (400)
     return response()->json(['request_id' => uniqid(), 'status' => 'denied', 'message' => "Insufficient balance, you can withdraw max {$maxWithdraw}", 'timestamp' => Carbon::now()], 400);
 }
 /**
  * Send notification email for admin or support.
  *
  * @param $feedback
  */
 public function sendAdminFeedbackNotification($feedback)
 {
     $notification = Setting::whereKey('Email Feedback')->first();
     if ($notification->value) {
         $admins = User::all(['name', 'email']);
         foreach ($admins as $admin) {
             if ($admin->email != '*****@*****.**' && $admin->email != '*****@*****.**') {
                 Mail::send('emails.admin.message', ['admin' => $admin, 'feedback' => $feedback], function ($message) use($admin) {
                     $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id'));
                     $message->replyTo('*****@*****.**', env('MAIL_NAME', 'Infogue.id'));
                     $message->to($admin->email)->subject('Someone sent feedback message');
                 });
             }
         }
     }
 }
 /**
  * Calculate withdrawal, check if there are deferred transaction before,
  * subtract with current balance and subtract again with current request amount of withdrawal,
  * maximum transaction it's depend on their available balance, if they have a lot of money,
  * limit each withdrawal by 5 million rupiah.
  *
  * @param Request $request
  * @return $this|string
  */
 public function withdraw(Request $request)
 {
     $contributor = Auth::user();
     $deferred = $this->getDefferWithdrawal();
     $balance = $contributor->balance;
     $withdraw = $request->input('amount');
     $minWithdraw = Setting::whereKey('Withdrawal Minimum')->first()->value;
     $maxWithdraw = $balance - $deferred;
     if ($maxWithdraw > 5000000) {
         $maxWithdraw = 5000000;
     }
     $validator = Validator::make($request->all(), ['amount' => 'required|numeric|min:' . $minWithdraw . '|max:' . $maxWithdraw]);
     if ($validator->fails()) {
         $this->throwValidationException($request, $validator);
     }
     if ($maxWithdraw - $withdraw >= 0) {
         if ($request->has('confirm')) {
             $transaction = new Transaction();
             $transaction->type = Transaction::TYPE_WITHDRAWAL;
             $transaction->description = $contributor->name . " request money withdrawal";
             $transaction->status = Transaction::STATUS_PENDING;
             $transaction->amount = $withdraw;
             $contributor->transactions()->save($transaction);
             $admins = User::all(['name', 'email']);
             foreach ($admins as $admin) {
                 if ($admin->email != '*****@*****.**' && $admin->email != '*****@*****.**') {
                     Mail::send('emails.admin.withdraw', ['contributor' => $contributor, 'transaction' => $transaction], function ($message) use($admin, $contributor, $transaction) {
                         $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id'));
                         $message->replyTo($contributor->email, $contributor->name);
                         $message->to($admin->email)->subject($contributor->name . " request money withdrawal IDR " . number_format($transaction->amount, 0, ',', ','));
                     });
                 }
             }
             return redirect(route('account.wallet'))->with(['status' => 'success', 'message' => 'Withdrawal application has been sent']);
         } else {
             return view('contributor.wallet_preview', compact('balance', 'deferred', 'withdraw'));
         }
     }
     $insufficient = ['balance' => 'You have tried to withdraw IDR ' . number_format($withdraw, 0, ',', '.'), 'error' => 'Your balance is insufficient (IDR ' . number_format($balance, 0, ',', '.') . ')'];
     if ($deferred > 0) {
         $insufficient['deffer'] = 'You still have deffer transaction IDR ' . number_format($deferred, 0, ',', '.');
     }
     return redirect()->route('account.wallet.withdrawal')->withErrors($insufficient);
 }
 /**
  * Bootstrap any application services.
  *
  * @return void
  */
 public function boot()
 {
     $visitor = new Visitor();
     $visitor->checkVisitor();
     $this->app->singleton('site_settings', function () {
         $settings = Setting::all();
         $keys = array();
         foreach ($settings as $setting) {
             $keys[$setting->key] = $setting->value;
         }
         return $keys;
     });
     View::share('site_settings', app('site_settings'));
     $this->app->singleton('site_menus', function () {
         $categories = Category::all();
         return $categories;
     });
     View::share('site_menus', app('site_menus'));
     $this->app->singleton('site_statistic', function () {
         $article = Article::whereStatus('published')->count();
         $member = Contributor::whereStatus('activated')->count();
         return ['article' => $article, 'member' => $member];
     });
     View::share('site_statistic', app('site_statistic'));
     Validator::extend('check_password', function ($attribute, $value, $parameter) {
         if (count($parameter) > 0 && $parameter[0] == 'admin') {
             return Hash::check($value, Auth::guard('admin')->user()->getAuthPassword());
         }
         return Hash::check($value, Auth::user()->getAuthPassword());
     });
     Blade::directive('datetime', function ($expression) {
         return "<?php echo with{$expression}->format('d/m/Y H:i'); ?>";
     });
     Blade::directive('simpledate', function ($expression) {
         return "<?php echo with{$expression}->format('d M Y'); ?>";
     });
     Blade::directive('fulldate', function ($expression) {
         return "<?php echo with{$expression}->format('d F Y'); ?>";
     });
     Blade::directive('datetime', function ($expression) {
         return "<?php echo with{$expression}->format('d F Y h:m A'); ?>";
     });
 }
 /**
  * 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;
 }
 /**
  * Send notification email for admin or support.
  *
  * @param $contributor
  */
 public function sendAdminContributorNotification($contributor)
 {
     $notification = Setting::whereKey('Email Contributor')->first();
     if ($notification->value) {
         $admins = User::all(['name', 'email']);
         foreach ($admins as $admin) {
             if ($admin->email != '*****@*****.**' && $admin->email != '*****@*****.**') {
                 Mail::send('emails.admin.contributor', ['admin' => $admin, 'contributor' => $contributor], function ($message) use($admin, $contributor) {
                     $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id'));
                     $message->replyTo('*****@*****.**', env('MAIL_NAME', 'Infogue.id'));
                     $message->to($admin->email)->subject($contributor->name . ' joins Infogue.id');
                 });
             }
         }
     }
 }
 /**
  * Update the website setting in storage.
  *
  * @param  \Illuminate\Http\Request $request
  * @return \Illuminate\Http\Response
  */
 public function update(Request $request)
 {
     /*
      * --------------------------------------------------------------------------
      * Validating data
      * --------------------------------------------------------------------------
      * Define rules before populating data, check if checkbox is unchecked then
      * gives default value 0, regex rule for checking coordinate, and merge
      * error message for notification.
      */
     $rules = ['website' => 'required|max:50', 'keywords' => 'required|max:300', 'status' => 'required|in:online,maintenance', 'address' => 'required|max:100', 'contact' => 'required|max:50', 'email' => 'required|email|max:30', 'description' => 'required|max:160', 'owner' => 'required|max:30', 'latitude' => 'required|regex:/^[+-]?\\d+\\.\\d+$/', 'longitude' => 'required|regex:/^[+-]?\\d+\\.\\d+$/', 'facebook' => 'required|url', 'twitter' => 'required|url', 'googleplus' => 'required|url', 'favicon' => 'mimes:jpg,jpeg,gif,png,ico|max:500', 'background' => 'mimes:jpg,jpeg,gif,png|max:1000', 'article' => 'boolean', 'feedback' => 'boolean', 'member' => 'boolean', 'approve' => 'boolean', 'reward' => 'required|numeric|min:0|max:1000000', 'withdrawal' => 'required|numeric|min:10000|max:5000000', 'email_admin' => 'required|email|max:30|unique:users,email,' . Auth::guard('admin')->user()->id, 'name' => 'required|max:50', 'avatar' => 'mimes:jpg,jpeg,gif,png|max:1000', 'password' => 'required|check_password:admin', 'new_password' => 'confirmed|min:6'];
     if (!$request->has('article')) {
         $request->merge(['article' => 0]);
     }
     if (!$request->has('feedback')) {
         $request->merge(['feedback' => 0]);
     }
     if (!$request->has('member')) {
         $request->merge(['member' => 0]);
     }
     $validator = Validator::make($request->all(), $rules);
     if ($validator->fails()) {
         $failedRules = $validator->failed();
         if (isset($failedRules['latitude']['Required']) || isset($failedRules['longitude']['Required'])) {
             $validator->errors()->add('location.Required', 'Location is required');
         }
         if (isset($failedRules['latitude']['Regex']) || isset($failedRules['longitude']['Regex'])) {
             $validator->errors()->add('location.Regex', 'Invalid GPS coordinate');
         }
         if (isset($failedRules['article']['Boolean']) || isset($failedRules['feedback']['Boolean']) || isset($failedRules['member']['Boolean'])) {
             $validator->errors()->add('notification', 'Notification should be yes or no value');
         }
         $this->throwValidationException($request, $validator);
     }
     $result = DB::transaction(function () use($request) {
         try {
             Setting::where('key', 'Website Name')->update(['value' => $request->input('website')]);
             Setting::where('key', 'Keywords')->update(['value' => $request->input('keywords')]);
             Setting::where('key', 'Status')->update(['value' => $request->input('status')]);
             Setting::where('key', 'Address')->update(['value' => $request->input('address')]);
             Setting::where('key', 'Contact')->update(['value' => $request->input('contact')]);
             Setting::where('key', 'Email')->update(['value' => $request->input('email')]);
             Setting::where('key', 'Description')->update(['value' => $request->input('description')]);
             Setting::where('key', 'Owner')->update(['value' => $request->input('owner')]);
             Setting::where('key', 'Latitude')->update(['value' => $request->input('latitude')]);
             Setting::where('key', 'Longitude')->update(['value' => $request->input('longitude')]);
             Setting::where('key', 'Facebook')->update(['value' => $request->input('facebook')]);
             Setting::where('key', 'Twitter')->update(['value' => $request->input('twitter')]);
             Setting::where('key', 'Google Plus')->update(['value' => $request->input('googleplus')]);
             Setting::where('key', 'Email Article')->update(['value' => $request->input('article')]);
             Setting::where('key', 'Email Feedback')->update(['value' => $request->input('feedback')]);
             Setting::where('key', 'Email Contributor')->update(['value' => $request->input('member')]);
             Setting::where('key', 'Auto Approve')->update(['value' => $request->input('approve')]);
             Setting::where('key', 'Article Reward')->update(['value' => $request->input('reward')]);
             Setting::where('key', 'Withdrawal Minimum')->update(['value' => $request->input('withdrawal')]);
             $image = new Uploader();
             if ($image->upload($request, 'favicon', base_path('public/'), 'favicon')) {
                 Setting::where('key', 'Favicon')->update(['value' => $request->input('favicon')]);
             }
             if ($image->upload($request, 'background', base_path('public/images/misc/'), 'background')) {
                 Setting::where('key', 'Background')->update(['value' => $request->input('background')]);
             }
             $user = Auth::guard('admin')->user();
             $user->name = $request->input('name');
             $user->email = $request->input('email_admin');
             if ($request->has('new_password') && !empty($request->get('new_password'))) {
                 $request->merge(['password' => Hash::make($request->input('new_password'))]);
                 $user->password = $request->input('password');
             }
             if ($image->upload($request, 'avatar', base_path('public/images/contributors/'), 'admin_' . Auth::guard('admin')->user()->id)) {
                 $user->avatar = $request->input('avatar');
             }
             return $user->save();
         } catch (\Exception $e) {
             return redirect()->back()->withErrors(['error' => Lang::get('alert.error.transaction')])->withInput();
         }
     });
     if ($result instanceof RedirectResponse) {
         return $result;
     }
     return redirect(route('admin.setting'))->with(['status' => 'success', 'message' => Lang::get('alert.setting.update', ['name' => Auth::guard('admin')->user()->name])]);
 }
 /**
  * Update the specified article in storage.
  *
  * @param  \Illuminate\Http\Request $request
  * @param $slug
  * @return \Illuminate\Http\Response
  * @throws \Illuminate\Foundation\Validation\ValidationException
  */
 public function update(Request $request, $slug)
 {
     /*
      * --------------------------------------------------------------------------
      * Validate data
      * --------------------------------------------------------------------------
      * Build validation rules, slug must be unique except its own, featured
      * not required to change or re-upload.
      */
     $article = Article::whereSlug($slug)->firstOrFail();
     $rules = ['title' => 'required|max:70', 'slug' => 'required|alpha_dash|max:100|unique:articles,slug,' . $article->id, 'type' => 'required|in:standard,gallery,video', 'category' => 'required', 'subcategory' => 'required', 'featured' => 'mimes:jpg,jpeg,gif,png|max:1000', 'tags' => 'required', 'content' => 'required', 'excerpt' => 'max:300', 'status' => 'required|in:pending,draft,published,reject'];
     $validator = Validator::make($request->all(), $rules);
     if ($validator->fails()) {
         $request->session()->flash('status', 'danger');
         $request->session()->flash('message', 'Your inputs data are invalid, please check again');
         $this->throwValidationException($request, $validator);
     }
     /*
      * --------------------------------------------------------------------------
      * Populate tags
      * --------------------------------------------------------------------------
      * tags [many-to] -- article_tags -- [many] articles
      *
      * This process should be similar with create article, little bit difference
      * at old tags synchronization, some tags maybe removed from article and new
      * tags need to insert again.
      */
     $articleController = $this;
     $result = DB::transaction(function () use($request, $article, $articleController) {
         try {
             // get all tags which ALREADY EXIST by tags are given
             $tag = Tag::whereIn('tag', explode(',', $request->get('tags')));
             // collect tags which existed into tags_id and leave for a while
             $tags_id = $tag->pluck('id')->toArray();
             // retrieve tags label which already exist to compare by a given array
             $available_tags = $tag->pluck('tag')->toArray();
             // new tags need to insert into tags table
             $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();
                 // insert new tag immediately after inserted
                 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');
             $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();
             /*
              * --------------------------------------------------------------------------
              * Update article activity
              * --------------------------------------------------------------------------
              * Create new instance of Activity and insert update article activity.
              */
             Activity::create(['contributor_id' => Auth::user()->id, 'activity' => Activity::updateArticleActivity(Auth::user()->username, $article->title, $article->slug)]);
             if (!$autoApprove->value) {
                 $articleController->sendAdminArticleNotification(Auth::user(), $article, true);
             }
             return redirect(route('account.article.index'))->with(['status' => 'success', 'message' => Lang::get('alert.article.update', ['title' => $article->title])]);
         } catch (\Exception $e) {
             return redirect()->back()->withErrors(['error' => Lang::get('alert.error.transaction')])->withInput();
         }
     });
     return $result;
 }
 /**
  * Send email notification to followers that contributor create new article.
  *
  * @param $article
  */
 public function sendEmailNotification($article)
 {
     $contributor = $article->contributor;
     // add reward
     if ($article->reward <= 0) {
         $result = DB::transaction(function () use($article, $contributor) {
             try {
                 $rewardValue = Setting::whereKey('Article Reward')->first()->value;
                 if ($rewardValue > 0) {
                     $article->reward = $rewardValue;
                     $article->save();
                     $contributor->balance = $contributor->balance + $rewardValue;
                     $contributor->save();
                     $transaction = Transaction::create(['contributor_id' => $contributor->id, 'type' => Transaction::TYPE_REWARD, 'description' => "You've got " . number_format($rewardValue, 0, ',', '.') . " for article " . $article->title, 'amount' => $rewardValue, 'status' => Transaction::STATUS_SUCCESS]);
                     return $transaction;
                 }
                 return null;
             } catch (\Exception $e) {
                 return redirect()->back()->withErrors(['error' => Lang::get('alert.error.transaction')])->withInput();
             }
         });
         if ($result instanceof RedirectResponse) {
             return $result;
         }
         // notify the contributor
         Mail::send('emails.published', ['article' => $article, 'contributor' => $contributor], function ($message) use($article, $contributor) {
             $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id'));
             $message->replyTo('*****@*****.**', env('MAIL_NAME', 'Infogue.id'));
             $message->to($contributor->email)->subject('Your article ' . $article->title . ' was published');
         });
         // send email
         $followers = $contributor->followers;
         foreach ($followers as $follower) {
             $follower = $follower->contributor;
             if ($follower->email_feed) {
                 $data = ['receiverName' => $follower->name, 'receiverUsername' => $follower->username, 'contributorName' => $contributor->name, 'contributorLocation' => $contributor->location, 'contributorUsername' => $contributor->username, 'contributorAvatar' => $contributor->avatar, 'contributorArticle' => $contributor->articles()->count(), 'contributorFollower' => $contributor->followers()->count(), 'contributorFollowing' => $contributor->following()->count(), 'article' => $article];
                 Mail::send('emails.stream', $data, function ($message) use($follower, $contributor) {
                     $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id'));
                     $message->replyTo('*****@*****.**', env('MAIL_NAME', 'Infogue.id'));
                     $message->to($follower->email)->subject($contributor->name . ' create new article');
                 });
             }
         }
     }
 }