Laravel mailable passing array to blade - laravel

On my project i made a contact form. It was store details on databse and shows admin panel and sends it to via mail so i cant pass array variables to mailable view.
My controller;
$iletisim = new Contact();
$iletisim->ad = $request->input('ad');
$iletisim->soyad =$request->input('soyad');
$iletisim->email = $request->input('email');
$iletisim->mesaj = $request->input('mesaj');
$iletisim->save();
$gonder = array( 'gonderen'=>$request->input('ad'),
'email'=>$request->input('email'),
'mesaj'=>$request->input('mesaj')
);
Mail::send(new ContactMail($gonder));
Session::flash('success', 'Mesajınız Gönderilmiştir. En kısa sürede dönüş sağlanacaktır.');
return back();
}
My Contact.php
public $bilgiler;
public function __construct($gonder)
{
$this->bilgiler = $gonder;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('homepage.emails.contact')->with(['bilgiler'=>$this->bilgiler]);
}
and my blade file
#component('mail::message')
# New Contact Form
{{$bilgiler->ad}}
Thanks,<br>
{{ config('app.name') }}
#endcomponent
Where is my mistake can you help.
Thanks

First of all, you don't need to add ->with(['bilgiler'=>$this->bilgiler]); since $bilgiger is public property. All public properties of Mailable are available in Blade
Also, since it's an array, you need to access it with:
$bilgiger['gonderen']
The $bilgiler->gonderen syntax is for objects, not for arrays. Also, you don't have id in the array.
And the last thing is you're using markdown email, so use the markdown() method:
return $this->markdown('homepage.emails.contact');

Related

How do I remove the one "like" from that particular user?

Trying do create a "like system" for a simple application with Laravel and Livewire. I have managed to add likes, but I only want the user to be able to add one (1) like to a post. At the moment a user can add as many likes as he or she wants.
This is my current function to store likes:
public function storeLike()
{
// Check if the user already has liked the post
if($this->collection->likes()->exists()){
return $this->collection->likes()->delete();
}
// If not, add one like to the db
$like = $this->collection->likes()->make();
$like->user()->associate(auth()->user());
// Save the like
$like->save();
}
And the part that im struggling with is:
if($this->collection->likes()->exists()){
return $this->collection->likes()->delete();
}
It deletes all the likes for that post. So how can a disassociate, detach that like if it exists?
This is how I have made the collection:
$collection = collect();
$posts = Post::search('topic', $this->search)->with(['user'])->latest()->get();
$urls = Urls::search('topic', $this->search)->with(['user'])->latest()->get();
$news = News::search('topic', $this->search)->latest()->get();
/** Push posts to the collection */
foreach ($posts as $post) $collection->push($post);
/** Push urls to the collection */
foreach ($urls as $item) $collection->push($item);
/** Push news to the collection */
foreach ($news as $item) $collection->push($item);
I think the toggle (see docs) method could be very handy.
Let's assume we're building a component for a model called Post.
Livewire
public function clickedLike() {
$this->post->likes()->toggle(Auth::user());
}
Template
<button wire:click="clickedLike">
<3
</button>
Model
class Post extends Model {
public function likes() {
return $this->hasMany(User::class, 'likes')
}
}

How to send data in the mailgun header with LARAVEL?

I am working with webhooks for the first time, in which I have to pass some 3 variables defined for later when Laravel takes it again I can update an action of the email sent for some reports.
The problem is that I can't pass data in the header of the email.
This is the structure that commonly sent the email to the users:
public $data;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($view, $subject, $data)
{
$this->view = $view;
$this->subject = $subject;
$this->data = $data;
}
public function build()
{
$message = $this->data;
// print_r($variables);
// exit;
return $this->from(config('mail.from.address'), config('mail.from.name'))
->view($this->view)
->subject($this->subject); //WORKED
/**NO WORKED*/
->withSwiftMessage(function ($message) use ($v){
$v->getHeaders()
->addTextHeader('Custom-Header', 'HeaderValue1')
->addTextHeader('Custom-Header2', 'HeaderValue2');
});
}
The emails if sent in that there is no problem, with the view and the data that is filled in the mail, but in the header the data is not filled in at least in this case, the 2 variables set ['Custom-Header', 'HeaderValue1', 'Custom-Header', 'HeaderValue2].
I had the same problem too and it took me quite a bit of research and testing. It seems that it needs to be in json format and you need to use 'X-Mailgun-Variables' instead of 'Custom-Header'. It should look like this
->addTextHeader('X-Mailgun-Variables', '{"variable1": "1", "variable2": "2"}')
the webhook should give you this result
"user-variables":{
"variable1":"1",
"variable2":"2"
},

laravel 5.7 how to pass request of controller to model and save

I am trying to pass $request from a function in controller to a function in model.
THis is my controller function:
PostController.php
public function store(Request $request, post $post)
{
$post->title = $request->title;
$post->description = $request->description;
$post->save();
return redirect(route('post.index'));
}
how save data in model Post.php?
I want the controller to only be in the role of sending information. Information is sent to the model. All calculations and storage are performed in the model
Thanks
You can make it even easier. Laravel has it's own helper "request()", which can be called anywhere in your code.
So, generally, you can do this:
PostController.php
public function store()
{
$post_model = new Post;
// for queries it's better to use transactions to handle errors
\DB::beginTransaction();
try {
$post_model->postStore();
\DB::commit(); // if there was no errors, your query will be executed
} catch (\Exception $e) {
\DB::rollback(); // either it won't execute any statements and rollback your database to previous state
abort(500);
}
// you don't need any if statements anymore. If you're here, it means all data has been saved successfully
return redirect(route('post.index'));
}
Post.php
public function postStore()
{
$request = request(); //save helper result to variable, so it can be reused
$this->title = $request->title;
$this->description = $request->description;
$this->save();
}
I'll show you full best practice example for update and create:
web.php
Route::post('store/post/{post?}', 'PostController#post')->name('post.store');
yourform.blade.php - can be used for update and create
<form action='{{ route('post.store', ['post' => $post->id ?? null]))'>
<!-- some inputs here -->
<!-- some inputs here -->
</form>
PostController.php
public function update(Post $post) {
// $post - if you sent null, in this variable will be 'new Post' result
// either laravel will try to find id you provided in your view, like Post::findOrFail(1). Of course, if it can't, it'll abort(404)
// then you can call your method postStore and it'll update or create for your new post.
// anyway, I'd recommend you to do next
\DB::beginTransaction();
try {
$post->fill(request()->all())->save();
\DB::commit();
} catch (\Exception $e) {
\DB::rollback();
abort(500);
}
return redirect(route('post.index'));
}
Based on description, not sure what you want exactly but assuming you want a clean controller and model . Here is one way
Model - Post
class Post {
$fillable = array(
'title', 'description'
);
}
PostController
class PostController extend Controller {
// store function normally don't get Casted Objects as `Post`
function store(\Request $request) {
$parameters = $request->all(); // get all your request data as an array
$post = \Post::create($parameters); // create method expect an array of fields mentioned in $fillable and returns a save dinstance
// OR
$post = new \Post();
$post->fill($parameters);
}
}
I hope it helps
You need to create new model simply by instantiating it:
$post = new Post; //Post is your model
then put content in record
$post->title = $request->title;
$post->description = $request->description;
and finally save it to db later:
$post->save();
To save all data in model using create method.You need to setup Mass Assignments when using create and set columns in fillable property in model.
protected $fillable = [ 'title', 'description' ];
and then call this with input
$post = Post::create([ 'parametername' => 'parametervalue' ]);
and if request has unwanted entries like token then us except on request before passing.
$post = Post::create([ $request->except(['_token']) ]);
Hope this helps.
I find to answer my question :
pass $request to my_method in model Post.php :
PostController.php:
public function store(Request $request)
{
$post_model = new Post;
$saved = $post_model->postStore($request);
//$saved = response of my_method in model
if($saved){
return redirect(route('post.index'));
}
}
and save data in the model :
Post.php
we can return instance or boolean to the controller .
I returned bool (save method response) to controller :
public function postStore($request)
{
$this->title = $request->title;
$this->description = $request->description;
$saved = $this->save();
//save method response bool
return $saved;
}
in this way, all calculations and storage are performed in the model (best way to save data in MVC)
public function store(Request $request)
{
$book = new Song();
$book->title = $request['title'];
$book->artist = $request['artist'];
$book->rating = $request['rating'];
$book->album_id = $request['album_id'];
$result= $book->save();
}

Laravel form select poulated by eloquent model

I am currently making an edit page for some data in my database, and on the edit page I am trying to make a Form::select which lists the people in my users table.
controller-which-makes-the-edit-view.php
<?php
class AdminController extends BaseController
{
public $restful = true;
public function getUpdatePage($id)
{
return View::make('data_edit')
->with('title', 'Rediger måling/oppgave')
->with('data', Routine::find($id))
->with('emp', Emp::lists('user_name', 'id'));
}
data_edit.blade.php
{{ Form::label('emp', 'Ansatt') }}
{{ Form::select('emp', $emp, $data->emps->user_name) }}
Now my question is how would I go about making the default value for the select the person that saved the row which is currently being edited?
I do apologize if this already is answered, I couldn't seem to find it (neither here nor google).
This is Form::select() definition:
public function select($name, $list = array(), $selected = null, $options = array())
{
}
The third parameter is the item to be selected. You are currently passing
$data->emps->user_name
To it, but it depends on the data you have on $emp, because you must pass to it the array key, not the value.
Note that for now (Laravel 5.3+), ::lists is obsolete, use ::pluck instead.

laravel validate multiple models

I would like a best practice for this kind of problem
I have items, categories and category_item table for a many to many relationship
I have 2 models with these validations rules
class Category extends Basemodel {
public static $rules = array(
'name' => 'required|min:2|max:255'
);
....
class Item extends BaseModel {
public static $rules = array(
'title' => 'required|min:5|max:255',
'content' => 'required'
);
....
class Basemodel extends Eloquent{
public static function validate($data){
return Validator::make($data, static::$rules);
}
}
I don't know how to validate these 2 sets of rules from only one form with category, title and content fields.
For the moment I just have a validation for the item but I don't know what's the best to do:
create a new set of rules in my controller -> but it seems redundant
sequentially validate Item then category -> but I don't know how to handle validations errors, do I have to merges them? and how?
a 3rd solution I'm unaware of
here is my ItemsController#store method
/**
* Store a newly created item in storage.
*
* #return Redirect
*/
public function store()
{
$validation= Item::validate(Input::all());
if($validation->passes()){
$new_recipe = new Item();
$new_recipe->title = Input::get('title');
$new_recipe->content = Input::get('content');
$new_recipe->creator_id = Auth::user()->id;
$new_recipe->save();
return Redirect::route('home')
->with('message','your item has been added');
}
else{
return Redirect::route('items.create')->withErrors($validation)->withInput();
}
}
I am very interested on some clue about this subject
thanks
One way, as you pointed yourself, is to validate it sequentially:
/**
* Store a newly created item in storage.
*
* #return Redirect
*/
public function store()
{
$itemValidation = Item::validate(Input::all());
$categoryValidation = Category::validate(Input::all());
if($itemValidation->passes() and $categoryValidation->passes()){
$new_recipe = new Item();
$new_recipe->title = Input::get('title');
$new_recipe->content = Input::get('content');
$new_recipe->creator_id = Auth::user()->id;
$new_recipe->save();
return Redirect::route('home')
->with('message','your item has been added');
}
else{
return Redirect::route('items.create')
->with('errors', array_merge_recursive(
$itemValidation->messages()->toArray(),
$categoryValidation->messages()->toArray()
)
)
->withInput();
}
}
The other way would be to create something like an Item Repository (domain) to orchestrate your items and categories (models) and use a Validation Service (that you'll need to create too) to validate your forms.
Chris Fidao book, Implementing Laravel, explains that wonderfully.
You can also use this:
$validationMessages =
array_merge_recursive(
$itemValidation->messages()->toArray(),
$categoryValidation->messages()->toArray());
return Redirect::back()->withErrors($validationMessages)->withInput();
and call it in the same way.
$validateUser = Validator::make(Input::all(), User::$rules);
$validateRole = Validator::make(Input::all(), Role::$rules);
if ($validateUser->fails() OR $validateRole->fails()) :
$validationMessages = array_merge_recursive($validateUser->messages()->toArray(), $validateRole->messages()->toArray());
return Redirect::back()->withErrors($validationMessages)->withInput();
endif;

Resources