when I want to change the current language for user I'm using:
App::setLocale($requestData['language']);
but when I'm trying to get current language in other functions it always returns the default language and it doesn't change, I'm using to get it:
$lang = App::currentLocale();
where is the problem? did I miss something?
edit: the full code
public function update_profile(Request $request)
{
$user = auth()->user()->details;
$requestData = $request->all();
$details = UserDetail::where('id', $user->id)->update($requestData);
$profile_progress = ListHelper::profile_progress();
App::setLocale($requestData['language']);
return response()->json([
'message' => trans('messages.updated_successfully')
]);
}
and the other function:
public function onboarding()
{
$locale= App::currentLocale();
return $locale;
}
Related
I was trying to add categories to products. I want to do it with a couple table between items and categories. I made a function in my controller to send it to the database. However, when I want to send it, I get the following error, and I don't know I can fix it. Method Illuminate\Database\Eloquent\Collection::attach does not exist.
Controller:
public function store(ItemsValidatorRequest $request)
{
if ($files = $request->image) {
$destinationPath = 'images';
$profileImage = date('YmdHis') . "." . $files->getClientOriginalExtension();
$files->move($destinationPath, $profileImage);
}
else {
return redirect()->back()->with('warning', 'Mislukt');
}
$user = Auth::user()->id;
Item::create([
'user_id' => $user,
'item_title' => $request->titel,
'item_img' => $profileImage,
'item_description' => $request->beschrijving,
'item_price' => $request->prijs,
'item_slug' => $this->slugify($request->titel)
]);
$items = Item::latest()->get();
// line where it goes wrong
$items->each->categories()->attach($request->categories);
return redirect()
->route('admin.items.index')
->with('success', 'Het item is toegevoegd aan je verlanglijst');
}
My model :
public function categories()
{
return $this->belongsToMany('App\Models\Category');
}
Laravels higher order function calls, take a single method call, not multiple. Therefor if you create an helper method on the Item class, it will solve your problem.
class Item {
public function attachCategories($categories) {
$this->categories()->attach($categories);
}
}
Which will make it possible to assign categories like so.
$items->each->attachCategories($request->categories);
I am trying to write a test that checks that a date is formatted correctly. Looking at the docs it seems pretty straight-forward.
Here is my test. I am submitting an invalid date format to my controller:
MyTest.php
/** #test */
public function a_date_must_be_formatted_correctly()
{
$foo = factory(Foo::class)->raw([
'date' => date('d/m/Y'),
]);
$response = $this->postJson('api/v1/foo', $foo)
->assertStatus(422)
->assertJsonValidationErrors('date');
}
Here is my controller method:
public function store(Request $request)
{
$attributes = $request->validate([
'date' => 'required|date_format:Y-m-d',
]);
...
}
I get a passing test each time.
I have also tried wrapping the format in quotes: 'date' => 'required|date_format:"Y-m-d"',
I'm expecting to get a 422 back saying my date is invalid. What am I doing wrong?
Well, I ended up writing a custom rule. I don't think this is the correct solution though given that Laravel has the handy built-in stuff. I feel like I should be leveraging that instead. In my case I am working with Blackout date(s).
Hers is what I ended up with. If there is a way to make the built-in methods work, please let me know so I can update the answer.
MyTest.php
/** #test */
public function a_blackout_date_must_be_formatted_correctly()
{
$blackout = factory(Blackout::class)->raw([
'date' => date('d/m/Y'),
]);
$response = $this->postJson('api/v1/blackouts', $blackout)
->assertStatus(422)
->assertJsonValidationErrors('date');
}
MyController.php
public function store(Request $request)
{
$attributes = $request->validate([
'date' => ['required', new DateFormatRule],
...
]);
$blackout = new Blackout($attributes);
...
}
DateFormatRule.php
public function passes($attribute, $value)
{
// The format we're looking for.
$format = 'Y-m-d';
// Create a new DateTime object.
$date = DateTime::createFromFormat($format, $value);
// Verify that the date provided is formatted correctly.
return $date && $date->format($format) === $value;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'Invalid date format.';
}
In my test I am getting a 422 response as expected. I can verify things are working by changing the name of the expected error from date to date123 and I'll get an error -- saying It was expecting date not date123.
Hope this helps someone!
enter code hereMy question about the combination filters in laravel by using eloquent.
I am trying to filter with a combination of the following:
username
Category
Sub_category
started_at
created_at
status
I use where conditions but it not working as required.
public function filter(Request $request, User $user)
{
$user = $user->newQuery();
// Search for a user based on their name.
if ($request->has('username')) {
$user->where('name', $request->input('username'));
}
// Search for a user based on their Category.
if ($request->has('Category')) {
$user->where('Category', $request->input('Category'));
}
// Search for a user based on their Sub_category.
if ($request->has('Sub_category')) {
$user->where('Sub_category', $request->input('Sub_category'));
}
// Search for a user based on their started_at.
if ($request->has('started_at')) {
$user->where('started_at', $request->input('started_at'));
}
// Search for a user based on their status.
if ($request->has('status')) {
$user->where('status', $request->input('status'));
}
// Continue for all of the filters.
// Get the results and return them.
return $user->get();
}
You should save your where conditions to the $user variable.
$user = $user->where($dbField, $request->input($requestParam));
For improved readability, I'd suggest using a loop with all of your filtering cases.
public function filter(Request $request)
{
$users = User::query();
$filters = [
'username' => 'name',
'Category' => 'Category',
'Sub_category' => 'Sub_category',
'started_at' => 'started_at',
'status' => 'status'
];
foreach ($filters as $requestParam => $dbField){
if ($request->has($requestParam)) {
$users = $users->where($dbField, $request->input($requestParam));
}
}
return $users->get();
}
Bear in mind $request->has does not check whether the parameter value is empty, use $request->filled if you wish so.
This is My examle refer this
public function filter(Request $request)
{
$q = User::query();
$email = $request->input('email');
$username= $request->input('username');
$q->when($email,function ($query) use ($email){
$query->where('email',$email);
});
$q->when($username,function ($query) use ($username){
$query->where('username',$username);
});
$results = $q->get();
//code
}
I have a model that has a one to many relationship to the versions of the description.
In my Controller
$tag = Tags::create([
'name' => $request->get('name'),
'user_id' => \Auth::id(),
]);
$tag->update([
'content' => $request->get('description')
]);
In my Model:
public function setContentAttribute(string $value)
{
$this->versions()->create([
'user_id' => \Auth::id(),
'value' => $value
]);
}
So I can't put content directly as an attribute in the create method because there is no Model right now.
But is it possible to overwrite the create Method?
When I try to overwrite something like this in my Model it will do an infinity loop
public static function create($attr) {
return parent::create($attr);
}
So my question is if it is possible to have something like this:
$tag = Tags::create([
'name' => $request->get('name'),
'user_id' => \Auth::id(),
'content' => $request->get('content')
]);
and in the Model:
public static function create($attr) {
$value = $attr['content'];
$attr['content'] = null;
$object = parent::create($attr);
$object->content = $value;
$object->save();
return $object;
}
Update
I didn't overwrite the create method but called it customCreate. So there is no infinity loop anymore and I can pass all variables to the customCreate function that handles the relationships for me.
Solution
After reading the changes from 5.3 to 5.4 it turns out that the create method was moved so you don't have to call parent::create() anymore.
The final solution is:
public static function create($attr) {
$content = $attr['content'];
unset($attr['content']);
$element = static::query()->create($attr);
$element->content = $content;
$element->save();
return $element;
}
I don't see why not and you could probably implement a more general approach? Eg. checking if set{property}Attribute() method exists, if it does - use it to assign a value, if it doesn't - use mass assigning.
Something like:
public static function create($attr) {
$indirect = collect($attr)->filter(function($value, $property) {
return method_exists(self::class, 'set' . camel_case($property) . 'Attribute');
});
$entity = parent::create(array_diff_key($attr, $indirect->toArray()));
$indirect->each(function($value, $property) use ($entity) {
$entity->{$property} = $value;
});
$entity->save();
return $entity;
}
I haven't really tested it but it should work. I use something like this in one of my Symfony apps.
So I have a create function in my controller as shown below and my routes is as such, my question is is there a way for me to put a condition to different create and edit in the same function as both have quite similar coding. Can someone enlighten me pls?
class ManageAccountsController extends Controller
{
public function index() {
$users = User::orderBy('name')->get();
$roles = Role::all();
return view('manage_accounts', compact('users', 'roles'));
}
public function update()
{
// process the form here
// create the validation rules ------------------------
$rules = array(
'name' => 'required', // just a normal required validation
'email' => 'required|email|unique:users', // required and must be unique in the user table
'password' => 'required|min:8|alpha_num',
'password_confirm' => 'required|same:password', // required and has to match the password field
'mobile' => 'required',
'role_id' => 'required'
);
// do the validation ----------------------------------
// validate against the inputs from our form
$validator = Validator::make(Input::all(), $rules);
// check if the validator failed -----------------------
if ($validator->fails()) {
// redirect our user back to the form with the errors from the validator
$input = Input::except('password', 'password_confirm');
$input['autoOpenModal'] = 'true'; //Add the auto open indicator flag as an input.
return redirect()
->back()
->withInput($input)
->withErrors($validator);
} else {
// validation successful ---------------------------
// user has passed all tests!
// let user enter the database
// create the data for our user
$user = new User;
$user->name = Input::get('name');
$user->email = Input::get('email');
$user->password = Hash::make(Input::get('password'));
$user->mobile = Input::get('mobile');
$user->role_id = Input::get('role_id');
// save our user
$user->save();
// redirect ----------------------------------------
// redirect our user back to the form so they can do it all over again
Session::flash('flash_message', 'User successfully added!');
return redirect()->back();
}
}
}
routes.php
Route::get('manage_accounts', 'ManageAccountsController#index');
Route::post('manage_accounts', 'ManageAccountsController#update');
UPDATE OR CREATE
Try the updateOrCreate() in Eloquent to create or update a record matching the attributes.
Read API docs udateOrCreate()
Your code will be like:
Model::updateOrCreate( ['id' => $id], ['firstField' => 'value', 'secondField' => 'value'] );
Note: first parameter is the match to be found and second the data's to be saved.
Hope this is helpful.
Why don't you try moving some of this code out of your controller. If you were to use Repositories, then you would be able to encapsulate some of your logic in order to use it for both functions.
Also you can handle all this validation without writing all the extra code into your controller - see http://laravel.com/docs/5.0/validation#form-request-validation.
This may all seem a bit overkill at first, but once you get the hang of it, your code will be much more manageable and extendable.
(for more on these I would thoroughly recommend Jeffery Way's Laracasts https://laracasts.com/ - this helped me a lot when I was learning Laravel)
// routes.php
// http://laravel.com/docs/5.0/controllers#restful-resource-controllers
Route::resource('manage_accounts', 'ManageAccountsController');
// ManageAccountsController.php
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class ManageAccountsController extends Controller
{
public $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function index() {
$users = User::orderBy('name')->get();
$roles = Role::all();
return view('manage_accounts', compact('users', 'roles'));
}
public function store(StoreUserRequest $request)
{
// validation already handled using this: http://laravel.com/docs/5.0/validation#form-request-validation
$this->userRepository->upsert($request)
Session::flash('flash_message', 'User successfully added!');
return redirect()->back();
}
public function update(StoreUserRequest $request, $id)
{
// validation already handled using this: http://laravel.com/docs/5.0/validation#form-request-validation
$this->userRepository->upsert($request, $id)
Session::flash('flash_message', 'User successfully updated!');
return redirect()->back();
}
}
// UserRepository.php
class UserRepository {
public function upsert($data, $id = null)
{
// You will also need something like this
if(isset($data['id']))
{
$user = $this->user->find($data['id']);
}
else {
$user = new User;
}
$user->name = $data['name'];
$user->email = $data['email'];
$user->password = Hash::make($data['password']);
$user->mobile = $data['mobile'];
$user->role_id = $data['role_id'];
// save our user
$user->save();
return $user;
}
}
}
Please use the code here as a guide (I have written this in a hurry and it will certainly contain errors). Have a quick read up on repositories and I think it should all make sense.
The basic premise here is to separate out code that you want to re-use rather than squashing it all into the same function.
Hope this helps!