How can I catch Notification::send exception? This notification works fine, but I want to add some admin page for watching status. Notification::send method always return null regardless success or not.
Full code now:
namespace App\Listeners;
use App\Events\SendUserNotification;
use Illuminate\Support\Facades\Notification;
use App\Models\LogNotification;
class SendUserNotificationListener
{
public function handle(SendUserNotification $event)
{
$users = $event->users;
$notification = $event->notification;
$logData = [];
try {
$send = Notification::send($users, $notification); // returned null
$status = "success";
} catch (\Exception $exception) {
$status = "error";
}
foreach ($users as $user) {
$logData[] = [
"user_id" => $user->id,
"type" => $notification->getType(),
"status" => $status,
"created_at" => now(),
"updated_at" => now(),
];
}
LogNotification::insert($logData);
}
}
This code cant catch any exceptions in Notification::send method.
Related
I cannot get a URL varible in my stripe checkout PHP slim app.
I need to be able to get a price varible from the URL to echo out into the session for the price of stripe payment. However it is just not working, I can use $_GET['price']; to echo out before it becomes a SLIM APP however when it becomes a SLIM APP it just wont work...
use Slim\Http\Request;
use Slim\Http\Response;
use Stripe\Stripe;
require 'vendor/autoload.php';
$dotenv = Dotenv\Dotenv::create(realpath('../../'));
$dotenv->load();
Stripe::setApiKey(getenv('STRIPE_SECRET_KEY'));
$db = new SQLite3('./store.db');
$db->exec("CREATE TABLE IF NOT EXISTS sessions(id INTEGER PRIMARY KEY, stripe_id TEXT, status TEXT)");
// createSession
function createSession($sessionId) {
global $db;
$stmt = $db->prepare("INSERT INTO sessions(stripe_id, status) VALUES (:id, 'pending')");
$stmt->bindValue(':id', $sessionId, SQLITE3_TEXT);
return $stmt->execute();
}
// markSessionPaid
function markSessionPaid($sessionId) {
global $db;
$stmt = $db->prepare("UPDATE sessions SET status='paid' WHERE :id = stripe_id");
$stmt->bindValue(':id', $sessionId, SQLITE3_TEXT);
return $stmt->execute();
}
// getSessionStatus
function getSessionStatus($sessionId) {
global $db;
$stmt = $db->prepare("SELECT status FROM sessions WHERE :id = stripe_id");
$stmt->bindValue(':id', $sessionId, SQLITE3_TEXT);
$result = $stmt->execute();
return $result->fetchArray()[0];
}
$app = new Slim\App;
$app->get('/', function (Request $request, Response $response, $args) {
$response->getBody()->write(file_get_contents("../../client/index.html"));
return $response;
});
$app->get('/success', function (Request $request, Response $response, $args) {
$response->getBody()->write(file_get_contents("../../client/success.html"));
return $response;
});
$app->get('/cancel', function (Request $request, Response $response, $args) {
$response->getBody()->write(file_get_contents("../../client/cancel.html"));
return $response;
});
function middleware1() {
$price = $app->request()->get('price');
};
$app->post('/create-session', 'middleware1', function(Request $request, Response $response) use ($app) {
try {
// One time payments
$session = \Stripe\Checkout\Session::create([
'payment_method_types' => ['card'],
'line_items' => [[
'name' => 'Order',
'description' => 'ORDER ID: 123456789A',
'images' => ['testimage'],
'amount' => $price,
'currency' => 'aud',
'quantity' => 1,
]],
'success_url' => 'http://localhost:4242/success?session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => 'http://localhost:4242/cancel',
]);
// Subscription recurring payments
// $session = \Stripe\Checkout\Session::create([
// // 'customer' => 'cus_123',
// 'payment_method_types' => ['card'],
// 'subscription_data' => [
// 'items' => [[
// 'plan' => 'starter',
// 'quantity' => 1,
// ]],
// ],
// 'success_url' => 'http://localhost:4242/success?session_id={CHECKOUT_SESSION_ID}',
// 'cancel_url' => 'http://localhost:4242/cancel',
// ]);
createSession($session->id);
} catch (Exception $e) {
return $response->withJson($e->getJsonBody(), 400);
}
return $response->withJson($session);
});
$app->post('/webhook', function(Request $request, Response $response) use ($app) {
// You can find your endpoint's secret in your webhook settings
$endpoint_secret = getenv('STRIPE_WEBHOOK_SECRET');
$payload = $request->getBody();
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;
try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400);
exit();
} catch(\Stripe\Exception\SignatureVerificationException $e) {
// Invalid signature
http_response_code(400);
exit();
}
// Handle the checkout.session.completed event
if ($event->type == 'checkout.session.completed') {
$session = $event->data->object;
// Fulfill the purchase...
handle_checkout_session($session);
}
return $response->withJson(['message' => 'success']);
});
$app->get('/session-status', function (Request $request, Response $response, array $args) {
$status = getSessionStatus($request->getQueryParam('session_id'));
return $response->withJson($status);
});
function handle_checkout_session($session) {
// Call out to inventory management system
// Ding in Slack
// send an email
markSessionPaid($session->id);
}
$app->run();
I've tried everything
$app->request()->get('price');
And more!
The URL looks like this www.example.com/server/php/?price=5770&orderid=y2INOqCUrEzrua1XwBMg
Any help would be greatly appreciated!
You cannot use $_GET in Slim since it wont work. One way to do it is since the parameters are passed in query I think you mean it like this checkout/?price=200. If so, then you can access it using this:
$queryParams = $app->request()->getQueryParams();
$price = $queryParams["price"];
This would probably work
I created a new project in Laravel that consumes all data from an API. For private data like a user profile, I need an access token to get the data.
Once I have an access token, how do I set the token as Auth::id() in Laravel? Or perhaps I can store the user profile as Auth::user() so that I can use #auth in a frontend blade file?
class CustomAuthController extends Controller
{
public function index()
{
return view('login');
}
public function store(Request $request)
{
$request->validate([
'phone' => 'required|numeric'
]);
$data = [
'phone' => $request->phone
];
$codeSent = GeneralFunction::WebRequestPublicApi('first-login', $data, null, null, null, true);
if($codeSent->status == "success")
{
return redirect('verify');
} else {
$errors = new MessageBag();
$errors->add("phone", "Invalid phone number");
return view('login')->withErrors($errors);
}
}
public function showVerify()
{
return view('verify');
}
public function verify(Request $request)
{
try {
$request->validate([
'verify' => 'required|size:6'
]);
$data = [
'token_code' => $request->verify,
'source' => 'web'
];
$token = GeneralFunction::WebRequestPublicApi('verify-login', $data, null, null, null, true);
if($token->status === "success")
{
$userData = GeneralFunction::WebRequestPublicApi('membership', null, 'GET', null, null, true, $token->results->access_token);
if($userData->status !== "error")
{
$user = (array) $userData->results[0];
$request->session()->put('token', $token->results->access_token);
Auth::attempt($user, false, false);
return redirect('/');
}
} else {
$errors = new MessageBag();
$errors->add("verify", "Invalid Token");
return view('verify')->withErrors($errors);
}
} catch (Exception $e) {
$errors = new MessageBag();
$errors->add("verify", $e->getMessage());
return view('verify')->withErrors($errors);
}
}
}
I tried using Auth::attempt, Auth::login(), and the other method, but all of these required a user table. My project does not have a database.
You can do something like following.
In the controller
if($auth_ok)
{
session(['user' => ['key' => 'value', 'key2' => 'value2'] ]); // set session data
return view('frontend');
}
In the view
$user = session('user', false);
#if(!$user) // if not logged in
do something
#else // logged in successfully
Welcome my user
#endif
Hope this helps.
i guess the best thing you need to do is to use sqlite and once you got login from your api create a new user from it or find if there is existing already and Auth::login($newUser);
I have a function
public function getCandidates($candidateEmail)
{
try {
$moduleIns = ZCRMRestClient::getInstance()->getModuleInstance('Candidats');
$response = $moduleIns->searchRecordsByEmail($candidateEmail, 1, 1);
$candidates = $response->getResponseJSON();
return $candidates;
} catch (ZCRMException $e) {
echo $e->getMessage();
echo $e->getExceptionCode();
echo $e->getCode();
}
}
And I use this function like that :
$obj = new ZohoV2();
$response = $obj->getCandidates($request->email);
$candidate = $response['data'][0];
return response()->json([ 'status' => 'success', 'candidate' => $candidate ], 200);
Theses functions allows me to retrieve a user from a database of a CRM.
But when the user does not exist, he sends me a 500 error.
{message: "No Content", exception: "zcrmsdk\crm\exception\ZCRMException",…}
exception: "zcrmsdk\crm\exception\ZCRMException"
file: "/home/vagrant/CloudStation/knok/myath/myath-app/vendor/zohocrm/php-sdk/src/crm/api/response/BulkAPIResponse.php"
line: 61
message: "No Content"
trace: [{,…}, {,…}, {,…}, {,…}, {,…}, {,…},…]
How to intercept this error so that I can process it as I want and send an error message ?
Thank you
Remove the try/catch from your first code block
public function getCandidates($candidateEmail)
{
$moduleIns = ZCRMRestClient::getInstance()->getModuleInstance('Candidats');
$response = $moduleIns->searchRecordsByEmail($candidateEmail, 1, 1);
$candidates = $response->getResponseJSON();
return $candidates;
}
And move it to the second code block (I assume it's the controller)
$obj = new ZohoV2();
try {
$response = $obj->getCandidates($request->email);
} catch (ZCRMException $e) {
return response()->json(['status' => 'failed', 'error' => $e->getMessage()], 404);
}
$candidate = $response['data'][0];
return response()->json([ 'status' => 'success', 'candidate' => $candidate ], 200);
I have 'sendsms' function which i used it in one of my controllers and worked fine. now what i need to know how i can make class reference of this code to use it in other controllers, instead of copy/paste whole code in all controllers.
In other Q/A they mentioned about only creating reference but i wanted to do it properly like using constructor or etc, not just doing things work, i want to do it like real-world project.
Here's the code in controller :
public function store(Request $request)
{
$this->validate($request,[
'title' => 'required|string|min:6',
'gametype' => 'required|string|min:3',
'description' => 'required|string|min:1|max:180',
'price' => 'required|numeric|min:4',
'buyyer_id' => 'required|numeric|min:1'
// 'seller_id' => 'required|numeric|min:1'
]);
// return RequestModel::create([
// 'title' => $request['title'],
// 'description' => $request['description'],
// 'gametype' => $request['gametype'],
// 'price' => $request['price'],
// 'buyyer_id' => $request['buyyer_id'],
// 'seller_id' => Auth::user()->id,
// ]);
//
$requestModel = new RequestModel;
// store
$requestModel->title = $request['title'];
$requestModel->description = $request['description'];
$requestModel->gametype = $request['gametype'];
$requestModel->price = $request['price'];
$requestModel->buyyer_id = $request['buyyer_id'];
$requestModel->seller_id = Auth::user()->id;
$requestModel->save();
return $this->sendSms($request['title'], $request['gametype']);
}
// I want to use this code in another class to use it in all controllers without copy/paste it.
function sendSms($reqid, $recgametype) {
//Send sms to getway
//implement later.
$otp_prefix = ':';
$response_type = 'json';
$textMSGATLAS = iconv("UTF-8", 'UTF-8//TRANSLIT',"req : ( " .$reqid. " ) for ( " .$recgametype. " ) submitted ");
ini_set("soap.wsdl_cache_enabled", "0");
try {
$client = new SoapClient("http://xxxx");
$user = "user";
$pass = "pass";
$fromNum = "+xxx";
$toNum = "+xxxx";
$messageContent = $textMSGATLAS;
$op = "send";
$client->SendSMS($fromNum,$toNum,$messageContent,$user,$pass,$op);
} catch (SoapFault $ex) {
echo $ex->faultstring;
}
}
I'm right now learning and I'm beginner at this so help to understand how to make it work properly. Thanks.
You can create a separate SMS class like :
<?php
namespace App;
class SMS {
private $reqid;
private $recgametype;
public function __construct($reqid, $recgametype)
{
$this->reqid = $reqid;
$this->recgametype = $recgametype;
}
public function send()
{
$otp_prefix = ':';
$response_type = 'json';
$textMSGATLAS = iconv("UTF-8", 'UTF-8//TRANSLIT',"req : ( " .$this->reqid. " ) for ( " .$this->recgametype. " ) submitted ");
ini_set("soap.wsdl_cache_enabled", "0");
try {
$client = new SoapClient("http://xxxx");
$user = "user";
$pass = "pass";
$fromNum = "+xxx";
$toNum = "+xxxx";
$messageContent = $textMSGATLAS;
$op = "send";
return $client->SendSMS($fromNum,$toNum,$messageContent,$user,$pass,$op);
} catch (SoapFault $ex) {
throw new \Exception('SMS sending failed')
}
}
}
And then inside controller or wherever you would need :
public function sendSms($reqid, $recgametype) {
$sms = new \App\SMS($reqid, $recgametype);
$sms->send();
}
You can also create custom exception like SMSSendingFailedException and throw it instead of standard \Exception inside send() function.
That will help you to send appropriate response in controller like :
public function sendSms($reqid, $recgametype) {
try{
$sms = new \App\SMS($reqid, $recgametype);
$sms->send();
return response()->json('message' => 'SMS sent successfully', 200);
}
catch(SMSSendingFailedException $e){
return response()->json('message' => 'SMS sending failed', 500);
}
}
Then to go one step further, you can use concept of laravel facade if you need it all over the project with a quick class alias.
I'm so concern about my operation to used Mysql statement like update, delete, insert and within Laravel Eloquent or Query builder because I've create more Mysql statement with more conditional inside of my method in Controller so if one of that conditional or something occurs or meet any problem during I'm processing my method in controller Method I will lost my information or data my data which I want to insert or update to my database.
As below function I used setNotification() which I create in Notification Model and I have method inside that Model which I want to call it to post_data is a method in Controller so if I do so does DB::beginTransaction() will work or not because I prefer to keep all Mysql statement inside all method in Model.
now I currently using Laravel Transaction with Try catch
public function post_data() {
if (Request::ajax() && $this->CheckPermId_from_session(90)) {
$res = null;
$data = Request::except(['_token']);
$rules = [//rules varray];
$data = [//Input data];
$data['tranx_time'] = date("y-m-d H:m:s", time());
$val = Validator::make($data, $rules);
if ($val->fails()) {
$res = ['res' => false, 'form' => false, 'data', $data];
} else {
DB::beginTransaction();
try {
//$update = Teller::where('id', '=', Request::input('teller_till_id'))->update(array('balance' => Request::input('tell_balance')));
$updateTeller = Teller::where('id', '=', Request::input('chief_till_id'))->update(array('balance' => Request::input('last_chief_balance')));
$insertId = DB::table('till_transaction')->insertGetId($data);
if ($insertId && $updateTeller) {
$this->notification->setNotification([$data['to_account'], json_encode($this->group_code), $insertId, Request::input('chief_till_id'), $data['type'], date("Y-m-d H:m:s", time()), $data['type']]);
$res = ['res' => true, 'data', $data];
} else {
$res = ['res' => false, 'data', $data];
}
DB::commit();
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
return $res;
}
}