Laravel 5 HTTP/Requests - pass url parameter to the rules() method - laravel-routing

I'm trying to create a set of rules under the new \HTTP\Requests\UpdateArticle class for the slug field, which needs to have unique filter applied, but only when the id is not equal the url parameter of the route name article/{article}.
What I got so far is:
public function rules()
{
return [
'title' => 'required|min:3',
'excerpt' => 'required',
'body' => 'required',
'slug' => 'required|unique:articles,slug,?',
'active' => 'required',
'published_at' => 'required|date'
];
}
I need to replace the question mark at the end of the unique filter for slug field with the id from the url, but don't know how to obtain it.

To get URL parameters from the URL:
$this->route('id');
A great discussion on this were also asked here.

You can retrieve route parameters by name with input():
$id = Route::input('id');
return [
// ...
'slug' => 'required|unique:articles,id,' . $id,
// ...
];
It's right there in the docs (scroll down to Accessing A Route Parameter Value)

Related

API post request not reaching the application

i'm new to laravel and i'm facing a painful problem.
I'm using Crinsane/LaravelShoppingcart in my ecommerce api and i'm trying to send a post request with axios in vuejs that adds a product to the cart by sending the product id and the quantity. The problem is the id and quantity are not reaching the application although i'm pretty sure i specified the correct route link in axios and i'm getting "No query results for model [App\Product]." which i assume means that the controller function that handles the request is working but the id is not being sent/transformed to the resource collection. I don't know if the problem is with the package i'm using or the code or something else.
this is axios request
addCart(item) {
axios
.post('/api/cart/add', item)
.then(response => (response.data.data))
.catch(error => console.log(error.response.data))
this is the route :
Route::post('cart/add', [
'uses' => 'ShoppingController#store',
'as' => 'cart.add'
]);
this is the cart collection
public function toArray($request)
{
return [
'id' => $this->id,
'qty' => $this->qty
];
}
this is the controller
public function store(){
$pdt = Product::findOrFail(request()->id);
$cart = Cart::add([
'id' => $pdt->id,
'name' => $pdt->name,
'qty' => request()->qty,
'price' => $pdt->price
]);
and this is the product model
class Product extends Model
{
protected $fillable = [
'name', 'description', 'image', 'category', 'quantity', 'price', 'sold','remaining','rating', 'bestSelling', 'featured'
];
}
Thank you in advance
The problem seems to be in your controller.
From the docs:
To obtain an instance of the current HTTP request via dependency injection, you should type-hint the Illuminate\Http\Request class on your controller method.
Try this:
public function store(Request, $request){
// Make sure the 'id' exists in the request
if ($request->get('id')) {
$pdt = Product::find($request->get('id'));
if ($request->get('qty')) {
$qty = $request->get('qty')
}
$cart = Cart::add([
'id' => $pdt->id,
'name' => $pdt->name,
'qty' => $qty,
'price' => $pdt->price
]);
}
Then, at the top of your controller, add:
use Illuminate\Http\Request;
So i found that it needed a json object to work and i had to put this code at the end of the store method :
return response()->json(['cart' => $cart], 201);

Laravel 5.6 - creation user not working

my application used to working well with registration user but now it dont.
here a portion of my model User
protected $fillable = [
'prenom', 'nom', 'email','photo_path','password',
];
here my validation function :
protected function validator(array $data)
{
return Validator::make($data, [
'prenom' => 'required|string|max:255',
'nom' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'photo_path' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:10000',
'password' => 'required|string|min:6|confirmed',
]);
}
here my create function :
protected function create(array $data)
{
dd($data);
$photoInput = request('photo_path');
$userPhotoPath='users';
$storagePhotoPath = Storage::disk('images')->put($userPhotoPath, $photoInput);
return User::create([
'prenom' => $data['prenom'],
'nom' => $data['nom'],
'email' => $data['email'],
'photo_path' => $storagePhotoPath,
'password' => Hash::make($data['password']),
]);
}
- POST request working ( return 302 ) but return back with input value
- Auth Route are declared in web.php
- Validation working well
but the php interpretor didnt get inside create function...
i just see in debugbar that information :
The given data was invalid./home/e7250/Laravel/ManageMyWorkLife/vendor/laravel/framework/src/Illuminate/Validation/Validator.php#306Illuminate\Validation\ValidationException
public function validate()
{
if ($this->fails()) {
throw new ValidationException($this);
}
$data = collect($this->getData())
but my validation working because i have error message near my InputTexte.
so i dont understand that error message ...
Do you have any clue ?
Well, you need to remove the dd(); function before you run something. Other wise it will end the execution of all other operations.
Check if your User Model has a constructor, if so remove it and check if the problem still accours. This fixed it for me.

rbac authorization check in Yii doesn't work (Getting unknown property: app\models\Post::createdBy)

I looked at the documentation for rbac in Yii and thought I understood how it worked until I actually tried it.
This is the rule for checking whether the author of the post is trying to get the authorization for an action:
class AuthorRule extends Rule
{
public $name = 'isAuthor';
/**
* #param string|integer $user the user ID.
* #param Item $item the role or permission that this rule is associated with
* #param array $params parameters passed to ManagerInterface::checkAccess().
* #return boolean a value indicating whether the rule permits the role or permission it is associated with.
*/
public function execute($user, $item, $params)
{
return isset($params['model']) ? $params['model']->createdBy == $user : false;
}
}
This is how I am trying to use the rule and Yii's rbac:
public function actionUpdate($id)
{
$model = $this->findModel($id);
if (\Yii::$app->user->can('update', ['model' => $model])) {
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
}
However, I get this when I try to edit a Post:
Getting unknown property: app\models\Post::createdBy
So I thought I had to replace createdBy with userId which is a column in the table Post and I am getting a blank page meaning it doesn't work. So I am trying to guess what $user is.
I also tried:
return isset($params['model']) ? $params['model']->userId == $user->id : false;
and I am getting: Trying to get property of non-object.
What should I do to make it work? The doc seemed to suggest you just had to plug the conditional inside the controller action to make it work, but it doesn't seem to be the case at all.
var dump:
object(app\models\Post)[75]
private '_attributes' (yii\db\BaseActiveRecord) =>
array (size=6)
'id' => int 1
'userId' => int 1
'title' => string 'test' (length=4)
'content' => string 'lol' (length=3)
'dateCreated' => null
'dateUpdated' => null
private '_oldAttributes' (yii\db\BaseActiveRecord) =>
array (size=6)
'id' => int 1
'userId' => int 1
'title' => string 'test' (length=4)
'content' => string 'lol' (length=3)
'dateCreated' => null
'dateUpdated' => null
private '_related' (yii\db\BaseActiveRecord) =>
array (size=0)
empty
private '_errors' (yii\base\Model) => null
private '_validators' (yii\base\Model) => null
private '_scenario' (yii\base\Model) => string 'default' (length=7)
private '_events' (yii\base\Component) =>
array (size=0)
empty
private '_behaviors' (yii\base\Component) =>
array (size=0)
empty
null
The first error says, that you don't have a createdBy property in your Post model. Do you?
The second error is about trying to get a property of non-object variable. Could you show var_dump($params['model']); var_dump($user); before the return?

how to add some variable data at middleware auth in register form?

I want to add some variable data to use at register form. something like option to select city. in normal controller i can do like this :
$data["city"] = City::selectOption();
return View('someView',$data);
How to add some variable data at miidleware auth in register form?
first, In the app\Http\Controllers\Auth\AuthController.php class, just add another variable.
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'variable' => 'value',
]);
}
the $data array on the create method is the $request variable from your get/post request.
second, in your App\User.php , add the variable to $fillable
protected $fillable = [
'name', 'email', 'password','variable',
];
for more info, take a look at
http://www.easylaravelbook.com/blog/2015/09/25/adding-custom-fields-to-a-laravel-5-registration-form/

Get the CSRF token in test

I'm writing functional test and i need to make ajax post request. "The CSRF token is invalid. Please try to resubmit the form". How can i get the token in my functional test ?
$crawler = $this->client->request(
'POST',
$url,
array(
'element_add' => array(
'_token' => '????',
'name' => 'bla',
)
),
array(),
array('HTTP_X-Requested-With' => 'XMLHttpRequest')
);
CSRF token generator is normal symfony 2 service. You can get service and generate token yourself. For example:
$csrfToken = $client->getContainer()->get('form.csrf_provider')->generateCsrfToken('registration');
$crawler = $client->request('POST', '/ajax/register', array(
'fos_user_registration_form' => array(
'_token' => $csrfToken,
'username' => 'samplelogin',
'email' => 'sample#fake.pl',
'plainPassword' => array(
'first' => 'somepass',
'second' => 'somepass',
),
'name' => 'sampleuser',
'type' => 'DSWP',
),
));
The generateCsrfToken gets one important parameter intention which should be the same in the test and in the form otherwise it fails.
After a long search (i've found nothing in doc and on the net about how to retrieve csrf token) i found a way:
$extract = $this->crawler->filter('input[name="element_add[_token]"]')
->extract(array('value'));
$csrf_token = $extract[0];
Extract the token from response before make the request.
In symfony 3, in your WebTestCase, you need to get the CSRF token:
$csrfToken = $client->getContainer()->get('security.csrf.token_manager')->getToken($csrfTokenId);
To get the $csrfTokenId, the best way would be to force it in the options of your FormType ():
class TaskType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'csrf_token_id' => 'task_item',
));
}
// ...
}
So in this case: $csrfTokenId = "task_item";. Or you you can try to use the default value, that would be the name of your form.
Then use it as a post parameter:
$client->request(
'POST',
'/url',
[
'formName' => [
'field' => 'value',
'field2' => 'value2',
'_token' => $csrfToken
]
]
);
Just in case someone stumble on this, in symfony 5 you get the token this way:
$client->getContainer()->get('security.csrf.token_manager')->getToken('token-id')->getValue();
where 'token-id' is the id that you used in the configureOptions method in your form type, which would look something like this:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
"data_class" => Foo::class,
"csrf_protection" => true,
"csrf_field_name" => "field_name", //form field name where token will be placed. If left empty, this will default to _token
"csrf_token_id" => "token-id", //This is the token id you must use to get the token value in your test
]);
}
Then you just put the token in the request as a normal field.