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, ...));
Related
how can I implement polymorphism using an abstract class for handling product saving, deleting, and showing for three different product types?
there are three product types: DVD, Furniture, and Book
The below code is my product model:
class Product
{
private $db;
public function __construct()
{
$this->db = new Database;
}
public function getProducts()
{
$this->db->query("SELECT * FROM products ORDER BY ID ASC");
return $this->db->__get('resultSet');
}
public function findProductsBysku($data)
{
$this->db->query('SELECT * FROM products WHERE sku = :sku');
//Bind values
$this->db->bind(':sku', $data['sku']);
//get products
return $this->db->__get('resultSet');
}
public function insertProducts($data)
{
$this->db->query('INSERT INTO products (sku, name, price, size, height, width, length, weight) VALUES (:sku, :name, :price, :size, :height, :width, :length, :weight)');
// Bind values
$this->db->__set(':sku', $data['sku']);
$this->db->__set(':name', $data['name']);
$this->db->__set(':price', $data['price']);
$this->db->__set(':size', $data['size']);
$this->db->__set(':height', $data['height']);
$this->db->__set(':width', $data['width']);
$this->db->__set(':length', $data['length']);
$this->db->__set(':weight', $data['weight']);
// execute
if ($this->db->execute()) {
$response = array("message" => "The product added", "ResultStatus" => 200);
return json_encode($response);
}
}
public function deleteProduct($id)
{
$this->db->query('DELETE FROM products WHERE id = :id');
// Bind values
$this->db->bind(':id', $id);
// Execute
if ($this->db->execute()) {
return true;
} else {
return false;
}
}
}
I use it inside my two controllers called AddProduct and Products:
Addproduct:
class Addproduct extends Controller
{
public $productModel;
public function __construct()
{
$this->productModel = $this->model('Product');
}
public function index()
{
/* Allow cors */
header('Access-Control-Allow-Origin: *');
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$data = [
'sku' => $_POST['sku'],
'name' => $_POST['name'],
'price' => $_POST['price'],
'size' => $_POST['size'],
'height' => $_POST['height'],
'width' => $_POST['width'],
'length' => $_POST['length'],
'weight' => $_POST['weight']
];
/* Find product by sku */
$productsBysku = $this->productModel->findProductsBysku($data);
/* Check if product already exist */
if (count($productsBysku) > 0) {
$response = array("message" => "The product already exist", "ResultStatus" => 500);
echo json_encode($response);
} else {
/* insert product */
$res = $this->productModel->insertProducts($data);
echo $res;
}
}
}
}
Products:
class Products extends Controller
{
public $productModel;
public function __construct()
{
$this->productModel = $this->model('Product');
}
public function index($id)
{
/* Allow cors */
header('Access-Control-Allow-Origin: *');
//load products
$products = $this->productModel->getProducts();
$this->view('pages/index', ['Products' => $products]);
}
public function MassDelete() {
/* Allow cors */
header('Access-Control-Allow-Origin: *');
//handle mass delete request
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$ids = $_POST['id'];
foreach ($ids as $id) {
$this->productModel->deleteProduct($id);
}
}
//load products
$products = $this->productModel->getProducts();
$this->view('pages/index', ['Products' => $products]);
}
}
I have to break down Product model into different classes per type with product model being their base class and one other important note is I should not use any conditional statement for handling product types
Just create an abstract class, and extend from it. Then in your controller class, simply operatate on that class, instead of its children.
abstract class Product {
public function __construct(
private string $sku,
private string $name
) {}
public function getSku(): string
{
return $this->sku;
}
}
class DVDProduct extends Product {
public function __construct(
private string $sku,
private string $name,
private float $rottenTomatosRating
) {
parent::__construct($sku, $name);
}
public function getRottenTomatosRating(): float
{
return $this->rottenTomatosRating;
}
}
I am getting this error while the controller run -'Invalid value of "491" provided for the regionId field.'. I want to transfer the telephone number from the billing address to the customer mobile number field and for that I have built this controller
My controller code is :
<?php
namespace [Vendor]\[Extension]\Controller\Adminhtml\Index;
use [Vendor]\[Extension]\Helper\Data;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\Result\JsonFactory;
class Update extends Action
{
protected $_customerRepoInterface;
protected $_customerFactory;
public function __construct(
Context $context,
Data $helper,
JsonFactory $resultJsonFactory,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepoInterface,
\Magento\Customer\Model\CustomerFactory $customerFactory
)
{
$this->resultJsonFactory = $resultJsonFactory;
$this->helper = $helper;
$this->_customerRepoInterface = $customerRepoInterface;
$this->_customerFactory = $customerFactory;
parent::__construct($context);
}
public function execute()
{
$result = $this->resultJsonFactory->create();
$customerCollectoin = $this->_customerFactory->create()->getCollection()
->addAttributeToSelect("*")
->load();
foreach ($customerCollectoin as $customer){
if($customer->getPrimaryBillingAddress()) {
if ($customer->getPrimaryBillingAddress()->getTelephone()) {
$telephone = $customer->getPrimaryBillingAddress()->getTelephone();
$customerObj = $this->_customerRepoInterface->getById($customer->getId());
$customerObj->setCustomAttribute('mobilenumber', $telephone);
$this->_customerRepoInterface->save($customerObj);
}
}
}
return $result->setData( count($customerCollectoin));
}
protected function _isAllowed()
{
return true;
}
}
~~Thank you in advance!
enter code here
I have a class social which has:
protected $id;
public function __construct($request, $id)
{
Log::info('Processing...', ['request' => $request, 'id' => $id]);
try {
$client = new Client();
$url = sprintf($request);
$response = $client->get($url);
$json = json_decode((string) $response->getBody(), true);
return $json;
} catch (ClientException $exception) {
$responseBody = $exception->getResponse()->getBody(true);
Log::error($responseBody, ['entity_id' => $id]);
}
}
public function wikipedia($wikipedia_url, $id)
{
dd($json);
try {
$wikipedia_array = $json['parse']['text'];
$wikipedia_array = array_slice($wikipedia_array, 0, 9);
$wikipedia_array = implode($wikipedia_array, ',');
Log::info('Processed Wikipedia for', ['entity_id' => $id]);
return $wikipedia_array;
} catch (Exception $e) {
Log::error('Wikipedia:', ['message' => $e->getMessage(), 'entity_id' => $id]);
}
}
In another function I am calling a facade like this:
$id = $entity->id;
$wikipedia_id = $entity->wikipedia;
if (!empty($wikipedia_id)) {
$wikipedia_url = 'http://en.wikipedia.org/w/api.php?action=parse&prop=text§ion=0&disablelimitreport=1&format=json&page='.$wikipedia_id;
$wikipedia_html = Social::wikipedia($wikipedia_url, $id);
Log::info('Wikipedia ok for', ['entity_id' => $id]);
}
However I get this:
Type error: Too few arguments to function App\Helpers\Social::__construct(), 0 passed in /home/vagrant/liveandnow/app/Providers/SocialServiceProvider.php on line 35 and exactly 2 expected
Can anyone explain to me how to call a method, pass parameters to it but also pass them along to construct?
Here's my facade:
<?php
namespace App\Facade;
use Illuminate\Support\Facades\Facade;
class Social extends Facade
{
/**
* Get the registered name of the component.
*
* #return string
*/
protected static function getFacadeAccessor()
{
return 'social';
}
}
and service provider:
public function register()
{
$this->app->bind('social', function ($app) {
return new Social;
});
}
the error lies in the service provider.
You define a constructor with 2 parameters,
public function __construct($request, $id)
but in your service provider you call it like this:
public function register()
{
$this->app->bind('social', function ($app) {
return new Social;
});
}
You need to add both arguments when instantiating the Social class, for example like
return new Social("http://xyz.de", 1);
Hope this helps.
I have few queries which I would like to use it to few methods in the same controller.for example below code:
$lastlogin = User::select('lastlogin')->where('id',Auth::user()->id)->get()->pluck('lastlogin');
$bio = User::where('id',Auth::user()->id)->value('bio');
$photo = User::where('id',Auth::user()->id)->value('photo');
$notifications = Notification::where('created_at','>',$lastlogin)->get();
$status = User::where('id',Auth::user()->id)->value('search_status');
I need to call above query in 4 methods in UserController.
I thought of doing something like:
public function john_doe()
{
$lastlogin = User::select('lastlogin')->where('id',Auth::user()->id)->get()->pluck('lastlogin');
$bio = User::where('id',Auth::user()->id)->value('bio');
$photo = User::where('id',Auth::user()->id)->value('photo');
$notifications = Notification::where('created_at','>',$lastlogin)->get();
$status = User::where('id',Auth::user()->id)->value('search_status');
}
Then
UserController
public abc (){john_doe();}
public def (){john_doe();}
public ghi (){john_doe();}
public jkl (){john_doe();}
But I get an error. How do I do this so when I change the code in one place it reflects everywhere?
Updated question
public function notify()
{
$bio = User::where('id',Auth::user()->id)->value('bio');
$photo = User::where('id',Auth::user()->id)->value('photo');
$friends = Friend::where('user_id',Auth::user()->id)->where('reqs_status',2)->get();
$notifications = Notification::where('created_at','>',Auth::user()->lastlogin)->get();
$status = User::where('id',Auth::user()->id)->value('search_status');
}
public function index()
{
$this->notify();
return view('/users/index',compact('send_requests','accept_rejects','sent_requests','users','bio','photo','friends','status','seeks','filters','notifications'));
}
That is a poorly written code. You get everything except notifications from the logged in user model.
public function fetchData()
{
$user = auth()->user();
$notifications = Notification::where('created_at', '>' , $user->lastlogin)->get();
$data = [
'lastlogin' => $user->lastlogin,
'bio' => $user->bio,
'photo' => $user->photo,
'search_status' => $user->search_status,
'notifications' => $notifications,
];
return (Object)$data;
}
public function test()
{
$data = $this->fetchData();
// $data->lastlogin;
// $data->bio;
// $data->photo;
// $data->search_status;
// $data->notifications;
}
Your UserController could looks like this
class UserController extends BaseController {
public function notify()
{
$array['bio'] = User::where('id',Auth::user()->id)->value('bio');
$array['photo'] = User::where('id',Auth::user()->id)->value('photo');
$array['friends'] = Friend::where('user_id',Auth::user()->id)->where('reqs_status',2)->get();
$array['notifications'] = Notification::where('created_at','>',Auth::user()->lastlogin)->get();
$array['status'] = User::where('id',Auth::user()->id)->value('search_status');
return $array;
}
public function index()
{
return view('/users/index', $this->notify());
}
}
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) {
}
}
}