How to define variable in controller in laravel - laravel

I have a URL used in blade template as:
href="{{ route('download', ['year' => $year, 'month' => $month, 'file' => $file_path]) }}"
when I am running my code then it is giving me an error as:
Undefined variable: year (View: C:\wamp64\www\Blog\employee-portal\resources\views\finance\invoice\edit.blade.php)
How can i define this $year variable in my controller?
In my controller the function is written as:
public function download($year, $month, $file, $inline = true)
{
$headers = [
'content-type' => 'application/pdf',
];
$file_path = FileHelper::getFilePath($year, $month, $file);
if (!$file_path) {
return false;
}
if ($inline) {
return Response::make(Storage::get($file_path), 200, $headers);
}
return Storage::download($file_path);
}
}
Edit function is written as:
public function edit(Invoice $invoice)
{
$projectStageBillings = $invoice->projectStageBillings;
$projectStageBilling = $projectStageBillings->first();
$client = $projectStageBilling->projectStage->project->client;
$client->load('projects', 'projects.stages', 'projects.stages.billings');
$billings = [];
foreach ($projectStageBillings as $key => $billing) {
$billing->load('projectStage', 'projectStage.project');
$billings[] = $billing;
}
return view('finance.invoice.edit')->with([
'invoice' => $invoice,
'clients' => Client::select('id', 'name')->get(),
'invoice_client' => $client,
'invoice_billings' => $billings,
]);
}

This error states that the view finance\invoice\edit.blade.php is missing the variable $year. And it is true, take a look at the return of your edit function:
return view('finance.invoice.edit')->with([
'invoice' => $invoice,
'clients' => Client::select('id', 'name')->get(),
'invoice_client' => $client,
'invoice_billings' => $billings,
]);
You are not sending any $year variable to the view here (the variables sent to the view are invoice,clients,invoice_client and invoice_billings.
To solve your problem, just send a $year variable to the view and you'll be ok :)

Related

Type error: Too few arguments to function Illuminate\Mail\Mailer::__construct(), 0 passed - Laravel 5.5

I keep getting while trying to use the mailer
FatalThrowableError in Mailer.php line 93:
Type error: Too few arguments to function Illuminate\Mail\Mailer::__construct(), 0 passed in /var/www/app/app/Services/SendOtpMail.php on line 42 and at least 2 expected
in Mailer.php line 93
at Mailer->__construct() in SendOtpMail.php line 42
at SendOtpMail->send('test#company.com', array('from' => 'no-reply#company.com', 'from_name' => 'Some Company', 'subject' => 'Login Verification', 'data' => array('token' => '3486', 'user' => object(User)), 'view' => 'emails.password')) in GetOtpForLoginService.php line 59
at GetOtpForLoginService->sendEmail('3486', object(User))
Send mail function
public function sendEmail($otp, $user)
{
$user = User::where('email', $user->email)->firstOrFail();
(new SendOtpMail())->send($user->email, [
'from' => env('MAIL_DEAFULT_SENDER'),
'from_name' => env('MAIL_DEAFULT_SENDER_ALIAS'),
'subject' => 'Login Verification',
'data' => [
'token' => $otp,
'user' => $user
],
'view' => 'emails.password'
]);
return true;
}
SendOtpMail.php
<?php
namespace App\Services;
use Illuminate\Mail\Mailer;
class SendOtpMail
{
public function send($to, array $options = array())
{
$callback = function($message) use ($options, $to) {
$message->from($options['from'], isset($options['from_name']) ? $options['from_name'] : null);
$message->to($to, isset($options['to_name']) ? $options['to_name'] : null);
if(isset($options['subject'])) $message->subject($options['subject']);
if(isset($options['priority'])) $message->priority($options['priority']);
if(isset($options['priority'])) $message->priority($options['priority']);
if(isset($options['files'])) {
if (is_array($options['files'])) {
foreach ($options['files'] as $file) {
$message->attach($options[$file]);
}
} else {
$message->attach($options['files']);
}
}
if(isset($options['cc'])) $message->subject($options['cc'], isset($options['cc_name']) ? $options['cc_name'] : null);
if(isset($options['bcc'])) $message->subject($options['bcc'], isset($options['bcc_name']) ? $options['bcc_name'] : null);
};
if(isset($options['view'])) {
$data = isset($options['data']) ? $options['data'] : array();
(new Mailer())->send($options['view'], $data, $callback);
} else {
(new Mailer())->raw($options['message'], $callback);
}
}
}
You are seeing that error because you are instantiating an Illuminate\Mail\Mailer object without specifying its required parameters in the constructor:
// from Laravel source code
public function __construct(string $name, Factory $views, TransportInterface $transport, Dispatcher $events = null)
{
$this->name = $name;
$this->views = $views;
$this->events = $events;
$this->transport = $transport;
}
I suggest you don't send emails this ways. Pls check the docs and follow the instructions.

Method not allowed exception while updating a record

Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpExceptionNomessage
I'm getting this error while trying to update a record in the database. Don't know what's the problem. This question might be a duplicate but I've checked all and couldn't find the answer. Please Help me with this.
Controller Update Method:
public function updateEvent(Request $request, $id=''){
$name = $request->name;
$startdate = date_create($request->start_date);
$start_date = $startdate;
$time = $request->start_time;
$start_time = $time;//date("G:i", strtotime($time));
$endDate = date_create($request->end_date);
$end_date =$endDate;
$time_e = $request->end_time;
$end_time = $time_e;//date("G:i", strtotime($time_e));
$location = $request->location;
$description = $request->description;
$calendar_type = $request->calendar_type;
$timezone = $request->timezone;
if ($request->has('isFullDay')) {
$isFullDay = 1;
}else{
$isFullDay = 0;
}
DB::table('events')->where('id', $id)->update(
array(
'name' => $name,
'start_date' => $start_date,
'end_date' => $end_date,
'start_time' => $start_time,
'end_time' => $end_time,
'isFullDay' =>$isFullDay,
'description' => $description,
'calendar_type' => $calendar_type,
'timezone' => $timezone,
'location' => $location,
));
// Event Created and saved to the database
//now we will fetch this events id and store its reminder(if set) to the event_reminder table.
if(!empty($id))
{
if (!empty($request->reminder_type && $request->reminder_number && $request->reminder_duration)) {
DB::table('event_reminders')->where('id', $id)->update([
'event_id' => $id,
'type' => $request->reminder_type,
'number'=> $request->reminder_number,
'duration' => $request->reminder_duration
]);
}
}
else{
DB::table('event_reminders')->insert([
'type' => $request->reminder_type,
'number'=> $request->reminder_number,
'duration' => $request->reminder_duration
]);
}
return redirect()->back();
}
Route:
Route::post('/event/update/{id}', 'EventTasksController#updateEvent');
Form attributes :
<form action="/event/update/{{$event->id}}" method="POST">
{{ method_field('PATCH')}}
i'm calling the same update function inside my calendar page and it working fine there. Don't know why it doesn't work here.
Check the routeing method.
Route::patch('/event/update/{id}', 'EventTasksController#updateEvent');
patch should be the method called on route facade.
Change your route to patch:
Route::patch('/event/update/{id}', 'EventTasksController#updateEvent');
For your comment:
You can send the method to the ajax call by something like data-method attribute on the element you click on,take the method and use it in your ajax call. see this question/answer for help. How to get the data-id attribute?

Extend Laravel package

I've searched around and couldn't find a definitive answer for this...
I have a package DevDojo Chatter and would like to extend it using my application. I understand I'd have to override the functions so that a composer update doesn't overwrite my changes.
How do I go about doing this?
UPDATE
public function store(Request $request)
{
$request->request->add(['body_content' => strip_tags($request->body)]);
$validator = Validator::make($request->all(), [
'title' => 'required|min:5|max:255',
'body_content' => 'required|min:10',
'chatter_category_id' => 'required',
]);
Event::fire(new ChatterBeforeNewDiscussion($request, $validator));
if (function_exists('chatter_before_new_discussion')) {
chatter_before_new_discussion($request, $validator);
}
if ($validator->fails()) {
return back()->withErrors($validator)->withInput();
}
$user_id = Auth::user()->id;
if (config('chatter.security.limit_time_between_posts')) {
if ($this->notEnoughTimeBetweenDiscussion()) {
$minute_copy = (config('chatter.security.time_between_posts') == 1) ? ' minute' : ' minutes';
$chatter_alert = [
'chatter_alert_type' => 'danger',
'chatter_alert' => 'In order to prevent spam, please allow at least '.config('chatter.security.time_between_posts').$minute_copy.' in between submitting content.',
];
return redirect('/'.config('chatter.routes.home'))->with($chatter_alert)->withInput();
}
}
// *** Let's gaurantee that we always have a generic slug *** //
$slug = str_slug($request->title, '-');
$discussion_exists = Models::discussion()->where('slug', '=', $slug)->first();
$incrementer = 1;
$new_slug = $slug;
while (isset($discussion_exists->id)) {
$new_slug = $slug.'-'.$incrementer;
$discussion_exists = Models::discussion()->where('slug', '=', $new_slug)->first();
$incrementer += 1;
}
if ($slug != $new_slug) {
$slug = $new_slug;
}
$new_discussion = [
'title' => $request->title,
'chatter_category_id' => $request->chatter_category_id,
'user_id' => $user_id,
'slug' => $slug,
'color' => $request->color,
];
$category = Models::category()->find($request->chatter_category_id);
if (!isset($category->slug)) {
$category = Models::category()->first();
}
$discussion = Models::discussion()->create($new_discussion);
$new_post = [
'chatter_discussion_id' => $discussion->id,
'user_id' => $user_id,
'body' => $request->body,
];
if (config('chatter.editor') == 'simplemde'):
$new_post['markdown'] = 1;
endif;
// add the user to automatically be notified when new posts are submitted
$discussion->users()->attach($user_id);
$post = Models::post()->create($new_post);
if ($post->id) {
Event::fire(new ChatterAfterNewDiscussion($request));
if (function_exists('chatter_after_new_discussion')) {
chatter_after_new_discussion($request);
}
if($discussion->status === 1) {
$chatter_alert = [
'chatter_alert_type' => 'success',
'chatter_alert' => 'Successfully created a new '.config('chatter.titles.discussion').'.',
];
return redirect('/'.config('chatter.routes.home').'/'.config('chatter.routes.discussion').'/'.$category->slug.'/'.$slug)->with($chatter_alert);
} else {
$chatter_alert = [
'chatter_alert_type' => 'info',
'chatter_alert' => 'You post has been submitted for approval.',
];
return redirect()->back()->with($chatter_alert);
}
} else {
$chatter_alert = [
'chatter_alert_type' => 'danger',
'chatter_alert' => 'Whoops :( There seems to be a problem creating your '.config('chatter.titles.discussion').'.',
];
return redirect('/'.config('chatter.routes.home').'/'.config('chatter.routes.discussion').'/'.$category->slug.'/'.$slug)->with($chatter_alert);
}
}
There's a store function within the vendor package that i'd like to modify/override. I want to be able to modify some of the function or perhaps part of it if needed. Please someone point me in the right direction.
If you mean modify class implementation in your application you can change the way class is resolved:
app()->bind(PackageClass:class, YourCustomClass::class);
and now you can create this custom class like so:
class YourCustomClass extends PackageClass
{
public function packageClassYouWantToChange()
{
// here you can modify behavior
}
}
I would advise you to read more about binding.
Of course a lot depends on how class is created, if it is created using new operator you might need to change multiple classes but if it's injected it should be enough to change this single class.

Laravel putting the return of a trait array into the controller

I'm currently struggling with how to return a variables from a trait and it should be returned in the array to be used in the controller:
Trait:
public function getAllData($search)
{
if ($search->search == null) {
$search->search = '#technology';
}
$cb = new Codebird();
$cb->setConsumerKey(env('TwitterKey'), env('TwitterSecret'));
$cb->setToken(env('AccessToken'), env('AccessTokenSecret'));
//https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
//https://dev.twitter.com/docs/api/1.1/get/search/tweets
$params = [
'q' => $search->search,
'lang' => 'en',
'count' => '5',
];
$reply = (array)$cb->search_tweets($params);
$data = (array)$reply['statuses'];
$s = count($reply['statuses']);
return [
'data' => $data,
's' => $s,
];
Controller:
public function TwitterData(Request $search) {
$data = $this->getAllData($search);
return view('front.search', compact('data'));
}
It currently gives me an error saying about using the object however I can't access the 'data' in the array
Error:
Trying to get property of non-object (View: C:\xampp\htdocs\TwitterProject\resources\views\front\search.blade.php)
You are returning an array on your getAllData method, but you are probably trying to access it as an object on your View:
WRONG:
{!! $data->data !!}
RIGHT:
{!! $data['data'] !!}

Difference between Redirect::to() and View::make()

I have a blade form that posts to Controller, the controller then will redirect to the same URL after performing some operations.
Before redirecting to the user, two variables will be passed. My problem is that when using Redirect::to() only the ->with('item_list',$item_list) is made available for the view, while ->with('added_items',$added_items) when using the $added_items variable in the view gives me the error:
ErrorException
Undefined variable: added_items (View: /var/www/mw/app/views/delivery->
requests/create.blade.php)
Controller
if (Input::has('addItem'))
{
if (Session::has('added-items'))
{
$id = Input::get('item_id');
$new_item = Item::find($id);
Session::push('added-items', [
'item_id' => $id,
'item_name' => $new_item->item_name,
'item_quantity' => Input::get('item_quantity')
]);
$array = Session::get('added-items');
//move outside foreach loop because we don't want to reset it
$total = array();
foreach ($array as $key => $value)
{
$id = $value['item_id'];
$quantity = $value['item_quantity'];
if (!isset($total[$id]))
{
$total[$id] = 0;
}
$total[$id] += $quantity;
}
$items = array();
foreach($total as $item_id => $item_quantity)
{
$new_item = Item::find($item_id);
$items[] = array(
'item_id' => $item_id,
'item_name' => $new_item->item_name,
'item_quantity' => $item_quantity
);
}
Session::put('added-items', $items);
}
else
{
$id = Input::get('item_id');
$new_item = Item::find($id);
Session::put('added-items', [
0 => [
'item_id' => $id,
'item_name' => $new_item->item_name,
'item_quantity' => Input::get('item_quantity')
]
]);
}
// pass the items again to the page
$item_list = Item::lists('item_name', 'id');
$added_items = Session::get('added-items');
return View::make('delivery-requests/create')
->with('added_items',$added_items)
->with('item_list', $item_list);
}
The reason I used Redirect::to() is that it maintains the same URL which is /delivery-requests/create
But when I use View::make() I can access the $added_items variable just fine, but the URL now becomes /delivery-requests , even if I explicitly put it like this:
return View::make('delivery-requests/create')
->with('added_items',$added_items)
->with('item_list', $item_list);
My question is why can't Redirect::to() read the $added_items variable on the view
Instead of redirecting to the route, return the method which is at the end of that route with any additional variables you need.
return $this->create()->with('added_items', $added_items)->with('item_list', $item_list) where create() is the method which is being used on the route delivery-requests/create.
Redirect is probably what you are actually after then,
Redirect::to()->with('item_list', $item_list);

Resources