Laravel one to many relationship insert data - php

I have two tables notification and alerFrequency. they have a one to many relationships respectively. the notification_id is a foreign key in the alerFrequency table. Both tables have models. now what I am trying to do is, to automatically insert data into the alertFrequency table if website is add in the notification table. this is the notification table
<?php
namespace App;
use App\Status;
use App\Notification;
use App\AlertFrequency;
use Illuminate\Database\Eloquent\Model;
class Notification extends Model
{
protected $fillable = ['id','website_url','email','slack_channel','check_frequency','alert_frequency','speed_frequency','active'];
public function statuses(){
return $this->belongsToMany('App\Status')->withPivot('values')->withTimestamps();
}
public function alertFrequencies(){
return $this->hasMany('App\AlertFrequency');
}
public function alert(){
$alert_timestamp = AlertFrequency::with('notification')->orderBy('created_at','desc')->select('created_at')->first();
$alert_timestamp=$alert_timestamp->created_at->toDateTimeString();
if($alert_timestamp==null){
return false;
}
return $alert_timestamp; }
and in the guzzle controller, I am using 3 functions: the add function to add a new alertFrequency into the table (which is not working at all) and the I called it in the sendnotification function, so that if it is time to send notification, it will add a new created_at in the alerFrequency table. Here is the guzzle controller
<?php
namespace App\Http\Controllers;
use \GuzzleHttp\Client;
use App\Utilities\Reporter;
use GuzzleHttp\Exception\ClientException;
use App\Notification;
use App\Status;
use App\Setting;
use Carbon;
use App\AlertFrequency;
class GuzzleController extends Controller
{
private $default_check_frequency;
protected $client;
protected $reporter;
public function __construct()
{
$this->client = new Client();
$this->reporter = new Reporter;
$this->default_check_frequency = Setting::defaultCheckFrequency();
}
private function addStatusToNotification(Notification $notification, Status $status, $resCode)
{
$notification->statuses()->attach($status, [
'values' => strval($resCode)
]);
}
/*function to add new time stamp into the alertFrequency table*/
private function add(Notification $notification, AlertFrequency $alert){
$notification->alertFrequency()->save();
}
private function report(Notification $notification, $resCode)
{
if(empty($resCode)){
$resCode = "no response found";
}
$status = Notification::health($resCode);
$this->reporter->slack($notification->website_url . ':' . ' is '. $status . ' this is the status code!' . ' #- ' .$resCode, $notification->slack_channel);
$this->reporter->mail($notification->email,$notification->website_url.' is '. $status . ' this is the status Code: '. $resCode);
}
private function sendNotification(Notification $notification, $status_health, $alert_frequency, $resCode,$alert)
{
echo "elpse time alert";
var_dump(\Carbon\Carbon::parse($alert)->diffInMinutes());
// If this is the first time we check, OR if the status changed from up to down and vice versa, notify!!!
if (empty($status_health['timestamp']) || Notification::health($resCode) <> Notification::health($status_health['value'])){
$this->report($notification,$resCode);
return;
}
// If the website is (still) down and the alert frequency is exceeded, notify!!!
if(Notification::health($resCode) === 'down' && \Carbon\Carbon::parse($alert)->diffInMinutes() >= $alert_frequency){
$this->report($notification,$resCode);
$this->add($notification,$alert);
}
}
public function status()
{
$notifications = Notification::where('active', 1)->get();
//$alert = AlertFrequency::
$status = Status::where('name', 'health')->first();
foreach ($notifications as $notification) {
$frequency = $this->updateStatus($notification, $status);
if (!empty($frequency)) {
$notification->alertFrequencies()->create([
'notification_id' => $frequency
]);
}
}
}
private function updateStatus(Notification $notification, Status $status)
{
$status_health = $notification->status('health');
$check = empty($status_health['timestamp']);
$elapsed_time = $check ? 10000 : \Carbon\Carbon::parse($status_health['timestamp'])->diffInMinutes();
$check_frequency = $this->getCheckFrequency($notification);
/* create an attachemtn in to the alerFrequenct table*/
$alert = $notification->alert();
var_dump($alert);
if ($check || $elapsed_time >= $check_frequency) {
$resCode = $this->getStatusCode($notification->website_url);
$this->addStatusToNotification($notification, $status, $resCode);
$this->sendNotification(
$notification,
$status_health,
$this->getAlertFrequency($notification),
$resCode,
$alert
);
}
}
private function getCheckFrequency(Notification $notification)
{
return isset($notification->check_frequency)
? intval($notification->check_frequency)
: $this->default_check_frequency;
}
private function getAlertFrequency(Notification $notification)
{
return isset($notification->alert_frequency)
? intval($notification->alert_frequency)
: $this->default_check_frequency;
}
private function getStatusCode($url)
{
try {
$response = $this->client->get($url, [
'http_errors' => false
]);
return $response->getStatusCode();
} catch (\GuzzleHttp\Exception\ConnectException $e) {
}
}
}

Related

Laravel send mail on each Orderplaced

I have below Order Controller and have created Mailable as well. I am stuck at point what argument should be passed so I can pass data on shipped.blade file. I have gone through few examples but couldn't get it working.
Also, where should I use foreach function to attach all items for which order is placed.
class Order extends Controller
{
public function addOrder(Request $req)
{
// User detail
$results = DB::table('users')->get()->where('id' , $req->input('user_id'));
foreach($results as $userrow) {
$address_id = $userrow->address;
}
// Address
$address_query = DB::table('shippings')->get()->where('id' , $address_id);
foreach($address_query as $ad_row) {
$address = $ad_row->address;
$name = $ad_row->name;
}
// Generate Orderid
$order_id = mt_rand();
// Bag total
$amount = DB::table('bag')->where('user_id' , $req->input('user_id'))->where('order_id', 0)->sum('bag.sale_price');
// add order
// get user email
$emailId = DB::table('users')->where('id' , $req->input('user_id'))->value('email');
$addAddress = DB::table('orders')->insert([
'email' => $emailId,
'user_id' => $req->input('user_id'),
'name' => $req->input('name'),
'order_id' => $order_id,
'payment_method'=> $req->input('payment_method'),
'mobile_number'=> $req->input('mobile_number'),
'pincode'=> $req->input('pincode'),
'city'=> $req->input('city'),
'state'=> $req->input('state'),
'house_number'=> $req->input('house_number'),
'address_area'=> $req->input('address_area'),
'landmark'=> $req->input('landmark'),
'amount'=> $amount
]);
if ($addAddress ==1) {
$response = array('message'=>"Order Added" , 'result'=>1);
//update bag items
$affected = DB::table('bag')->where('user_id', $req->input('user_id'))->where('order_id', 0)->update(['order_id' => $order_id]);
Mail::to($emailId)->send(new OrderShipped());
} else {
$response = array('message'=>"Problem in adding order" , 'result'=>0);
}
return $response;
}
}
OrderShipped Mailable
public function __construct()
{
//
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from('orders#factory2homes.com', 'Factory2Homes')
->subject('New Order Received')
->bcc('mail#androidapp.factory2homes.com')
->markdown('emails.orders.shipped');
}
You create public properties on your mailable and then inject them via the constructor
public $prop1;
public $prop2;
...
public function __construct($arg1, $arg2, ...)
{
$this->prop1 = $arg1;
$this->prop2 = $arg2;
...
}
public function build()
{
return $this->from('orders#factory2homes.com', 'Factory2Homes')
->subject('New Order Received')
->bcc('mail#androidapp.factory2homes.com')
->markdown('emails.orders.shipped', ['arg1' => $this->prop1, 'arg2' => $this->prop2, ...]);
}
Mail::to($emailId)->send(new OrderShipped($arg1, $arg2, ...));

how can i get auth user or any session in the my custom class and provider?

i have to get the company which user chooses but i can't get user data in my class and provider boot function .
user can have more than one company so user have to choose a company for some operations. But as i said , i can't get the company which user chooses.
Like this :
public function boot()
{
$user = Auth::user();
dd( $user ); // return null;
$bid = new Bid();
$show = $bid->check();
Blade::directive('bid',function() use($show){
return "<?php if( $show ) { ?>";
});
Blade::directive('endbid',function(){
return '<?php } ?>';
});
}
My other class :
<?php
namespace App\Services\Buying\Package;
use App\Services\Buying\Package\PackageInterface;
use App\Models\Company\Company;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use App\User;
class PackageBuying extends PackageQuery implements PackageInterface
{
private $company_id;
public function __construct()
{
$user = Auth::user();
dd( $user ); // return null
$this->setCompanyId($this->company_id);
}
public function setSession( Request $request )
{
$request->session()->get('selected-company');
}
public function company()
{
return $this->company_id;
}
public function package()
{
if ( $this->check() ) {
return $this->getPackage($this->company())->first();
}
return [];
}
public function features()
{
return (object)json_decode( $this->package()->features );
}
public function importantFeatures()
{
return (object)json_decode( $this->package()->important_features );
}
public function active()
{
return (bool) $this->getPackage()->firstOrFail()->active;
}
}
Actually if i got user data in the provider boot function , i could send data to my class .
May you please help me ?
Thanks in advance.
Put the code inside your construct function to calMethod function like this
public function callAction( $method, $parameters ) {
$user = Auth::user();
dd( $user ); // return null
$this->setCompanyId($this->company_id);
return parent::callAction( $method, $parameters );
}

Sending notification toDatabase Laravel 5.7

I'm trying to send notification to database but having some trouble. In my notifications table, DATA row is null {"estate":null}. it should retrieve title and body though.
my controller is:
use Illuminate\Http\Request;
use App\Notifications\NewEstateNotification;
use App\Estate;
use App\User;
public function __construct()
{
$this->middleware('auth');
}
public function newEstate()
{
$estate = new Estate;
$estate->user_id = auth()->user()->id;
$estate->title = 'Laravel Notification';
$estate->body = 'This is the new Estate';
$estate->save;
$user = User::where('id', '!=', auth()->user()->id)->get();
if (\Notification::send($user, new NewEstateNotification(Estate::latest('id')->first())))
{
return back();
}
}
NewEstateNotification class:
use Queueable;
protected $estate;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($estate)
{
$this->estate = $estate;
}
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return [
'estate' => $this->estate,
];
}
Any idea where am I doing wrong?
try to used like that
public function newEstate()
{
$estate = new Estate();
$estate->user_id = auth()->user()->id;
$estate->title = 'Laravel Notification';
$estate->body = 'This is the new Estate';
$estate->save();
$users = User::where('id', '!=', auth()->user()->id)->get();
//used like that
foreach($users as $user) {
$user->notify(new NewEstateNotification($estate));
}
return back();
}
in NewEstateNotification add toArray() method
public function toDatabase($notifiable)
{
return [
'estate' => $this->estate->toArray(),
];
}
it's also working fine if you want to used
\Notification::send($user, new NewEstateNotification($estate))

Changing alert frequencies based on the http response

My code is working prefectly on sending http request and in case a website is down or a response code is not 200, it sends a slack notification. What I am trying to figure out now is, in the notifications table I have check_frequency and alert_frequence. If a website is down, instead of using check frequency to calculate the elapse time, it should use alert_frequence.
namespace App\Http\Controllers;
use GuzzleHttp\Client;
use App\Utilities\Reporter;
use GuzzleHttp\Exception\ClientException;
use App\Notification;
use App\Status;
use App\Setting;
class GuzzleController extends Controller
{
private $default_check_frequency;
protected $client;
protected $reporter;
public function __construct()
{
$this->client = new Client;
$this->reporter = new Reporter;
$this->default_check_frequency = Setting::defaultCheckFrequency();
}
public function status()
{
$notifications = Notification::where('active', 1)->get();
$status = Status::where('name', 'health')->first();
foreach ($notifications as $notification) {
$this->updateStatus($notification, $status);
}
}
private function updateStatus(Notification $notification, Status $status)
{
$status_health = $notification->status('health');
$frequency = $this->getFrequency($notification);
$elapsed_time = \Carbon\Carbon::parse($status_health['timestamp'])->diffInMinutes();
if($elapsed_time >= $frequency) {
$response = $this->client->get($notification->website_url, [
'http_errors' => false
]);
$resCode = $response->getStatusCode();
$notification->statuses()->attach($status, [
'values' => $resCode === 200 ? 'up' : 'down'
]);
if($resCode != 200){
/* how to send slack to different slach channels, now it is sending only to one channel!*/
$this->reporter->slack($notification->website_url.':'.' is down'. ' please check your email for the status code!'.' #- '.$notification->email,
$notification->slack_channel);
$this->reporter->mail($notification->email,$resCode );
}
}
}
private function getFrequency(Notification $notification)
{
return isset($notification->check_frequency)
? intval($notification->check_frequency)
: $this->default_check_frequency;
}
}
I'm not sure this is what you need, but here's what you can do to select a different column from your table, depending on the status:
<?php
class GuzzleController extends Controller
{
private $default_check_frequency;
protected $client;
protected $reporter;
public function __construct()
{
$this->client = new Client;
$this->reporter = new Reporter;
$this->default_check_frequency = Setting::defaultCheckFrequency();
}
public function status()
{
$notifications = Notification::where('active', 1)->get();
$status = Status::where('name', 'health')->first();
foreach ($notifications as $notification) {
$this->updateStatus($notification, $status);
}
}
private function updateStatus(Notification $notification, Status $status)
{
$status_health = $notification->status('health');
/// move it here
$response = $this->client->get($notification->website_url, [
'http_errors' => false
]);
$resCode = $response->getStatusCode();
/// --- end
$frequency = $this->getFrequency($notification, $resCode);
$elapsed_time = \Carbon\Carbon::parse($status_health['timestamp'])->diffInMinutes();
if($elapsed_time >= $frequency) {
$notification->statuses()->attach($status, [
'values' => $resCode === 200 ? 'up' : 'down'
]);
if($resCode != 200){
/* how to send slack to different slach channels, now it is sending only to one channel!*/
$this->reporter->slack($notification->website_url.':'.' is down'. ' please check your email for the status code!'.' #- '.$notification->email,
$notification->slack_channel);
$this->reporter->mail($notification->email,$resCode );
}
}
}
private function getFrequency(Notification $notification, $resCode)
{
/// -- select your column here
$column = $resCode == '200' ? 'check_frequency' : 'alert_frequence';
return isset($notification->{$column})
? intval($notification->{$column})
: $this->default_check_frequency;
}
}
And I took the liberty to refactor it, separating method concerns:
<?php
use Carbon\Carbon;
class GuzzleController extends Controller
{
private $default_check_frequency;
protected $client;
protected $reporter;
public function __construct()
{
$this->client = new Client;
$this->reporter = new Reporter;
$this->default_check_frequency = Setting::defaultCheckFrequency();
}
private function addStatusToNotification(Notification $notification, Status $status, $resCode)
{
$notification->statuses()->attach($status, [
'values' => $resCode === 200
? 'up'
: 'down'
]);
}
private function report(Notification $notification, $resCode)
{
/* how to send slack to different slach channels, now it is sending only to one channel!*/
$this->reporter->slack($notification->website_url . ':' . ' is down' . ' please check your email for the status code!' . ' #- ' . $notification->email,
$notification->slack_channel);
$this->reporter->mail($notification->email, $resCode);
}
private function sendNotification(Notification $notification, Status $status, $status_health, $frequency, $resCode)
{
$elapsed_time = Carbon::parse($status_health['timestamp'])->diffInMinutes();
if ($elapsed_time >= $frequency) {
$this->addStatusToNotification($notification, $status, $resCode);
if ($resCode != 200) {
$this->report($notification, $resCode);
}
}
}
public function status()
{
$notifications = Notification::where('active', 1)->get();
$status = Status::where('name', 'health')->first();
foreach ($notifications as $notification) {
$this->updateStatus($notification, $status);
}
}
private function updateStatus(Notification $notification, Status $status)
{
$resCode = $this->getStatusCode($notification->website_url);
$this->sendNotification(
$notification,
$status,
$notification->status('health'),
$this->getFrequency($notification, $resCode),
$resCode
);
}
private function getFrequency(Notification $notification, $resCode)
{
$column = $resCode == '200' ? 'check_frequency' : 'alert_frequence';
return isset($notification->{$column})
? intval($notification->{$column})
: $this->default_check_frequency;
}
private function getStatusCode($url)
{
$response = $this->client->get($url, [
'http_errors' => false
]);
return $response->getStatusCode();
}
}

Laravel Form Request : bad method be called

When I use a Form Request with a Post method the response is the "index()" method response. But it's have to be the "store(myRequest $request)" method.
If I remove myRequest $request method from "store()" it's works. I'm lost.Please help me.
My controller :
<?php namespace App\Http\Controllers\Ressource;
use App\Http\Requests\CreateCollectionRequest;
use App\Repositories\CollectionRepository;
class CollectionController extends RessourceController {
private $collectionRepository;
public function __construct(CollectionRepository $collectionRepository)
{
parent::__construct();
$this->collectionRepository = $collectionRepository;
}
public function index()
{
return $this->run( function()
{
return $this->collectionRepository->all()->get();
});
}
public function store(CreateCollectionRequest $request)
{
return $this->run( function() use ($request) {
return $this->collectionRepository->create($request->all());
});
}
}
RessourceController :
<?php namespace App\Http\Controllers\Ressource;
use Illuminate\Support\Facades\Response;
use App\Http\Controllers\Controller;
abstract class RessourceController extends Controller
{
protected $result = null;
public function __construct()
{
$this->result = new \stdClass();
$this->result->error = 0;
$this->result->message = '';
$this->result->service = $this->getService();
$this->result->data = null;
}
abstract public function getService();
protected function render()
{
return Response::json($this->result);
}
public function missingMethod($parameters = [])
{
$this->result->err = 404;
$this->result->message = 'Service ' . $this->getService() . ' : ' . $parameters . ' non disponible';
return $this->render();
}
protected function run($function)
{
try {
$this->result->data = call_user_func($function);
} catch (\Exception $e) {
$this->result->err = ($e->getCode() > 0) ? $e->getCode() : -1;
$this->result->message = $e->getMessage();
}
return $this->render();
}
}
Custom Form Request :
namespace App\Http\Requests;
use App\Http\Requests\Request;
class CreateCollectionRequest extends Request
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'label' => 'required|alpha_num|min:3|max:32',
'description' => 'alpha_dash|max:65000',
'parent_collection_id' => 'exists:collections,id'
];
}
}
Extract from routes.php :
Route::group(array('namespace' => 'Ressource', 'prefix' => 'ressource'), function () {
Route::resource('collection', 'CollectionController', ['only' => ['index', 'show', 'store', 'update', 'destroy']]);
});
Postman request :
Postman reponse :
You should make your function become Clouse function.
My controller :
use App\Http\Requests\CreateCollectionRequest;
use App\Repositories\CollectionRepository;
use SuperClosure\Serializer;
use Illuminate\Support\Str;
use Closure;
class CollectionController extends RessourceController {
private $collectionRepository;
public function __construct(CollectionRepository $collectionRepository)
{
parent::__construct();
$this->collectionRepository = $collectionRepository;
}
public function index()
{
return $this->run( function()
{
return $this->collectionRepository->all()->get();
});
}
protected function buildCallable($callback) {
if (! $callback instanceof Closure) {
return $callback;
}
return (new Serializer)->serialize($callback);
}
public function store(CreateCollectionRequest $request)
{
$callback = function() use ($request) {
return $this->collectionRepository->create($request->all());
}
return $this->run($this->buildCallable($callback));
}
}
RessourceController :
<?php namespace App\Http\Controllers\Ressource;
use Illuminate\Support\Facades\Response;
use App\Http\Controllers\Controller;
use SuperClosure\Serializer;
use Illuminate\Support\Str;
use Closure;
abstract class RessourceController extends Controller
{
protected $result = null;
public function __construct()
{
$this->result = new \stdClass();
$this->result->error = 0;
$this->result->message = '';
$this->result->service = $this->getService();
$this->result->data = null;
}
abstract public function getService();
protected function render()
{
return Response::json($this->result);
}
public function missingMethod($parameters = [])
{
$this->result->err = 404;
$this->result->message = 'Service ' . $this->getService() . ' : ' . $parameters . ' non disponible';
return $this->render();
}
protected function getCallable($callback)
{
if (Str::contains($callback, 'SerializableClosure')) {
return unserialize($callback)->getClosure();
}
return $callback;
}
protected function run($function)
{
try {
$this->result->data = call_user_func($this->getCallable($function));
} catch (\Exception $e) {
$this->result->err = ($e->getCode() > 0) ? $e->getCode() : -1;
$this->result->message = $e->getMessage();
}
return $this->render();
}
}

Categories