Validator, what's wrong? - php

I'm going a little be crazy with my simple validator.
$data = ['dam' => 1, 'sir' => 2];
$v = Validator::make(
$data,
['dam' => 'exists:individuals,id'],
['dam.exists' => 'Object not found']
);
$validateLab = $v->validate();
dd($validateLab);
In the table individuals, there is an entry for id=1, but not id=2. If I run the code as it is, I get "true". If I change 'dam' => 1 to 'dam' => 2, I get
"The given data was invalid." on line 306 of
/Applications/MAMP/htdocs/mysamples/vendor/laravel/framework/src/Illuminate/Validation/Validator.php :
...
/**
* Run the validator's rules against its data.
*
* #return void
*
* #throws \Illuminate\Validation\ValidationException
*/
public function validate()
{
if ($this->fails()) {
throw new ValidationException($this);
}
}
...
Why? Why it does not return "Object not found"?

Related

Validate a property with multiple conditions and multiple messages in Laravel/Livewire

i want to validate a property with two conditionals and custom theses messages. i don´t know how to separate the rules and the messages in this case
There are two condition to $licences_days. The first one, if licences_available is greater than 2, you only can take more than 3 licences_days. Else if licences_available is less or equal than 3, you only can take from 1 to 3 licences_days. But, there is an error. How i can resolve it?
public $licences_days;
public $licences_available;
protected $rules = [
'licences_days' => 'required_if:licences_available,gt,2|integer|min:3|licences_available', // the first condition
'licences_days' => 'required_if:licences_available,lte,3|integer|min:1|max:3', // second condition
];
protected $messages = [
'licences_days.required_if:licences_available,gt,3|integer|min:3|licences_available' => 'the licences available are greater than 3, you can´t take less than 3 licences', // custom message for the first condition
'licences_days.required_if:licences_available,lte,3|integer|min:1|max:3' => 'the licences available are less or equal than 3, you can´t take more than 3 licences', // custom message for the second condition
];
Thanks a lot!
public $licences_days;
public $licences_available;
protected $rules = [
'licences_days' => 'greater|lessEqual',
];
public function updated($propertyName)
{
if ($propertyName == 'licences_days.greater') {
$this->validateOnly('licences_days.greater', [
'licences_days.greater' => [
new LicencesRule,
'required_if:licences_available,gt,2|integer|min:3|max:licences_available'
]
]);
}
if ($propertyName == 'licences_days.lessEqual') {
$this->validateOnly('licences_days.lessEqual', [
'licences_days.lessEqual' => [
new LicencesRule,
'required_if:licences_available,lte,3|integer|min:1|max:3'
]
]);
}
Then i cerated a rule call LicencesRule
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\InvokableRule;
class LicencesRule implements InvokableRule
{
/**
* Run the validation rule.
*
* #param string $attribute
* #param mixed $value
* #param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
* #return void
*/
public function __invoke($attribute, $value, $fail)
{
if ($value < 3) {
$fail('you can´t take more than 3 licences days.');
}
}
}
So far, i wrote that code but this generate an error.

laravel validation rule does not accept first index of array

/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request) {
$rules = [
'translations' => 'required|array',
'translations.*.language_code' => 'required|exists:app_languages,code',
'translations.*.name' => 'required'
];
$this->validate($request, $rules);
dd("OK");
}
I am using PostMan to test it. Everything is ok for array's second parameter. But it does not accept name 0 index or array.
When i didn't send first index :
UPDATE
It is Postman's bug. I added same parameter then replace it, it works.
It is Postman's bug. I added same parameter then replace it, it works.
I do not know, why it didn't accept and now it accept lol.
I think this helps you .
$rules = [];
if($request->has('translations'))
{
$translations = $request->input('translations');
foreach($translations as $key => $value)
{
$rules["translations.$key.$value"] = 'required';
}
}

Laravel 5: Odd "Undefined Variable" error when returning a defined array to View

As the title states, I'm getting an odd error in Laravel 5. I'm new to Laravel, and this week I dived into Jobs/Queues. I've gotten an "Undefined Variable: $errors" error in the past, and that one I was able to understand and fix. But now, I can't seem to get past this one. To my knowledge, everything looks fine. The following breakdown will (hopefully) give you an idea of what I'm doing/where the error happens:
class PostFormFields extends Job implements SelfHandling
{
use InteractsWithQueue, SerializesModels;
/**
* The id (if any) of the Post row
*/
protected $id;
/**
* List of fields and default value for each field
*/
protected $fieldList = [
'title' => '',
'subtitle' => '',
'page_image' => '',
'content' => '',
'meta_description' => '',
'is_draft' => '8',
'publish_date' => '',
'publish_time' => '',
'layout' => 'blog.layouts.post',
'tags' => [],
];
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($id = null)
{
$this->id = $id;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$fields = $this->fieldList;
if($this->id)
{
$fields = $this->fieldsFromModel($this->id, $fields);
} else {
$when = Carbon::now()->addHour();
$fields['publish_date'] = $when->format('M-j-Y');
$fields['publish_time'] = $when->format('g:i A');
}
/**
* Populate with old values, if they exist
* #var [type]
*/
foreach ($fields as $fieldName => $fieldValue)
{
$fields[$fieldName] = old($fieldName, $fieldValue);
}
$fields = array_merge($fields, ['allTags' => Tag::lists('tag')->all()]);
return $fields;
}
Above is the code inside the handler function of my Job class, the file it sits in is called PostFormFields.php. It's job, essentially, is just to return an array filled with all the values pertaining to a post, based on the Post Model and what's in the database that pertains to that specific Post ('title','content',etc) if a user's entered them in the past
public function create()
{
$data = $this->dispatch(new PostFormFields());
$data['title'] = 'testing';
var_dump($data);
return view('admin.post.create', $data);
}
Above is the code inside my PostController class, in the create() method. As you can tell, I'm using a resource controller for my Post Controller. It dispatches the PostFormFields Job and stores all the returned data in an array $data. However, since the create() method will be used to create a new post, only the keys should be returned, with values set to their default value ''.
This works. As you can see, i run a 'var_dump()' on the variable $data to see what, if anything, is returned. I then pass the $data array to the create View. This is where the error comes up.
Laravel "Undefined Varieble" Error
Above is a picture of the error I get when I try to access the /create route. It's clear that the $data does have the $title variable defined, as well as all the other keys in the array. Why am I getting an "Undefined Variable" array when I clearly have it defined by the time it's sent to the create View?
The line of code is says the error is in is the following:
<input type="text" class="radius" name="title" id="title" value="{{ $title }}">
You have to pass that array to view via compact function of laravel. So that you can use it in view as you want.
Please check about compact here - https://laracasts.com/discuss/channels/general-discussion/phps-compact-pros-and-cons?page=1
public function create()
{
$data = $this->dispatch(new PostFormFields());
$data['title'] = 'testing';
var_dump($data);
return view('admin.post.create', compact('data'));
}

How to include fractal transformed objects directly to collection meta without data key

I'm using league/fractal with JsonApiSerializer,
I've got users collection for json output.
Now I want to add some filters data to this json response (like users count for current filters).
I got this:
$resource = new Collection($dataProvider->getData(), new UserTransformer());
//the only way to include some not directly linked data i found is using setMeta():
$resource->setMetaValue('projects', $dataProvider->getProjects());
$resource->setMetaValue('somes', $dataProvider->getTasks());
But! 'projects' & 'somes' collections (yes, they are collection too) also included with 'data' key in it.
So, I've got this structure:
{
'data' => [
{//user1},{//user2},...
],
'meta' => {
'projects' => {
'data' => {...}
},
'somes' => {
'data' => {...}
}
}
}
but I want something like:
{
'data' => [
{//user1},{//user2},...
],
'meta' => {
'projects' => {...}, //there is no 'data' key
'somes' => {...} //there is no 'data' key
}
}
What should I do?
This is kinda hack but works fine without refactor Scope class which hardcoded in fractal's League\Fractal\Manager::createData() and is only way to use your own Scope class realization is to overload this method in Manager's extension.
<?php
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class EmbedSerializer
*/
class EmbedSerializer extends JsonApiSerializer
{
const RESOURCE_EMBEDDED_KEY = 'embedded';
/**
* Serialize a collection.
*
* #param string $resourceKey
* #param array $data
* #return array
*/
public function collection($resourceKey, array $data)
{
return $resourceKey === self::RESOURCE_EMBEDDED_KEY ? $data : [$resourceKey ?: 'data' => $data];
}
/**
* Serialize an item.
*
* #param string $resourceKey
* #param array $data
* #return array
*/
public function item($resourceKey, array $data)
{
return $resourceKey === self::RESOURCE_EMBEDDED_KEY ? $data : [$resourceKey ?: 'data' => [$data]];
}
}
So, now i could use it like:
/** #var $this->fractal League\Fractal\Manager */
$this->fractal->setSerializer(new EmbedSerializer());
$projectsCollection = $this->fractal->createData(
new Collection($projects, new UserProjectTransformer(), 'embedded')
)->toArray();
$resource = new Collection($users, new UserTransformer());
$resource->setMetaValue('projects', $projectsCollection);
That's all u need. Hope this will be helpful.

Symfomy2 manual route definitions with FOSRestBundle

I am now using the FOSRestBundle in order to build a REST API within my Symfony application. The idea for now is to list some locations(hotels, restaurants...), I managed to configure the automatic routes with FOSRestBundle like:
/api/locations , /api/locations/{id} , /api/locations/{name}/detail
with this controller:
class LocationController extends FOSRestController implements ClassResourceInterface
{
/**
* GET /locations
*
* #return Array
*
*/
public function cgetAction()
{
$locations = $this->getDoctrine()
->getManager()
->getRepository('VisitBILocationsBundle:Location')
->findAll();
if (!$locations) {
return array(
'locations' => $locations,
'status' => 1
);
}
return array(
'locations' => $locations,
'status' => 0
);
}
/**
* GET /locations/{locationId}
*
* #return Array
*
*/
public function getAction($id)
{
$location = $this->getDoctrine()
->getManager()
->getRepository('VisitBILocationsBundle:Location')
->findBy(array('id' => $id));
if (!$location) {
return array(
'location' => $location,
'status' => 1
);
}
return array(
'location' => $location,
'status' => 0
);
}
/**
* GET /locations/{name}/detail
*
* #return Array
*/
public function getDetailAction($name)
{
$detail = $this->getDoctrine()
->getManager()
->getRepository('VisitBILocationsBundle:LocationDetail')
->findBy(array('name' => $name));
if (!$detail) {
return array(
'locationDetail' => $detail,
'status' => 1
);
}
return array(
'locationDetail' => $detail,
'status' => 0
);
}
}
I've been struggling with this, but would anyone know how should I proceed to generate one custom url like this:
/api/locations/nearby/{latitude}/{longitude}
The idea is that I would provide my own latitude and longitude, and the backend will calculate and provide the locations which are the closest to me.
Of course I've looked at the documentation of FOSRestBundle for manual route configuration, but since I spent some time trying to do it, I come here to ask for some help :)
If you want to manually define a route, it should just be as simple as adding the route to the existing routing configuration. How exactly you do it depends on how you're handling the routing configuration: annotation, yaml, or xml.
Option 1: YAML
In the routing.yml file (ex: src/Vendor/MyBundle/Resources/config/routing.yml) add something like:
location_nearby:
pattern: /api/locations/nearby/{latitude}/{longitude}
defaults: { _controller: "MyBundle:Location:nearby" }
requirements:
_method: GET
which would correspond to this method in LocationController:
public function nearbyAction($latitude, $longitude) { ... }
Option 2: Annotations
Add this use statement to the Controller file:
use FOS\RestBundle\Controller\Annotations\Get;
and then define the route above the controller method:
/**
* Return a nearby location
* #Get("/api/locations/nearby/{latitude}/{longitude}")
*/
public function nearbyAction($latitude, $longitude) { ... }
OK here is how to proceed, works fine for me:
I use the annotation system to route /locations/nearby/{latitude}/{longitude}
/**
* Return a nearby location
* #Get("/locations/nearby/{latitude}/{longitude}", requirements={"latitude" = "[-+]?(\d*[.])?\d+", "longitude" = "[-+]?(\d*[.])?\d+"})
*/
public function nearbyAction($latitude, $longitude) {...}
Then I have to specify float numbers with: requirements={"latitude" = "[-+]?(\d*[.])?\d+", "longitude" = "[-+]?(\d*[.])?\d+"}
Those will still be interpreted as string by the controller: "64.1333", I just have to use this in the controller:
floatval($latitude)
to get url parameters as float and then do my calculations!

Categories