How to query two more input in laravel 3's validation? - php

For example, the user pass the userName, email to me, and I would like to have a custom validation for check the DB's user table have a column with the both userName equal and email equal and status equal 1 or not? How the customised validation implements?
For example:
User input:
userName: Peter
email: peter#email.com
In case 1, in the DB's user table:
Success: userName: Peter , email: peter#email.com, status: 1
Fail: userName: Peter , email: peter#email.com, status: 0
Fail: userName: Mary , email: peter#email.com, status: 1
Fail: userName: Peter , email: mary#email.com, status: 1

You can create a custom validation method as a catch all. The major problem here is that the validation extension will only ever pass the single attribute to the method rather than the values of all three. This will require you to hack up the validation. This method will be very bespoke to your particular application due to the hard coded nature of the table, column names and input. It also does not give you any way of telling which field the issue is with and would require some additional rule. Another suggestion would be to actually extend the validator class as a library to provide you with a much finer tuned validation engine for this circumstance.
Validator::register('usercheck', function($attribute, $value, $parameters)
{
$count = DB::table('user')
->where('userName', '=', Input::get('userName'))
->where('email', '=', Input::get('email'))
->where('status', '=', Input::get('status'))
->count();
return $count > 0;
});
To use it just add it as a rule... bear in mind this feels a bit hacky and there ARE better ways of doing this, most notably the method I suggested in the opening paragraph.
$rules = array(
'userName' => 'usercheck'
);

You can use this validation.
'userName' => 'unique:user,username',
'email' => 'unique:user,email'
See the docs about this http://laravel.com/docs/validation#rule-unique (Laravel 3) or the Laravel 4 docs at http://four.laravel.com/docs/validation#rule-unique

Related

Spatie Laravel 9: send email notification to Users with roles

I got everything working in terms of sending emails and templating. Now I want to replace the static to: email#test.com with users' email with specific roles.
I have this code written:
public function envelope()
{
return new Envelope(
from: 'amushref#hsse.co',
to: [
User::with("roles")->whereHas("roles", function($q) {
$q->whereIn("id", [
1, // Super Admin
6, // Admin
2, // Security Supervisor
5, // Security Manager
]);
})->get('email')
],
subject: 'New Incident: ' . str_pad($this->record->ir_number, 4, '0', STR_PAD_LEFT) .
' - ' .
$this->record->caseTypeRelationship->name .
' - ' . $this->record->locationRelationship->name,
);
}
I've made to: as an array to include emails of the provided roles (id). I get an error saying that the address are not correct/doesn't exist. What is the proper way to fetch emails of users of the selected roles?
First of all, you do not need to include roles if you don't need them. It's introducing an additional query which you should avoid.
Secondly, your ->get('email') is returning a Collection of users with only the email field. You probably want to convert that to an array to pass it on to the Envelope.
Thirdly, you have wrapped the output of your ->get('email') which in itself is already a collection in an array of its own, making your email sit a level too deep.
Something like this should do the trick:
to: User::whereHas("roles", function($q) {
$q->whereIn("id", [1, 6, 2, 5]);
})->pluck('email')->toArray(),
You can get the list of emails with the following and assign it to an array:
$emails = User::role(['Super Admin', 'Admin', 'Security Supervisor', 'Security Manager'])
->pluck('email')->toArray();
then change your to: $emails

Laravel Unique Validation for each user

I am running into an issue which I assume is simple, but it has me stumpted and I would appreciate any help.
The issue is I want each user to be able to create ads, User 1 can have one ad called "Test Ad" and user two can have one ad called "Test Ad" What is happening right now is the user can only have one ad called "Test Ad" but if user one has created "Test Ad" then user 2 is not able to because validation is returning that it already exists, but it doesn't exist for that user.
Here is my validation code:
'ad_title' => 'unique:ads,ad_title,user_id|required|min:3|max:128,' . Auth::user()->id,
Thanks for your time!
You can use closure function to apply your custom validation requirement.
Try
[
'ad_title' => [
'required',
'min:3',
'max:128',
function ($attribute, $value, $fail) {
return !! (\DB::table('ads')
->where('user_id', auth()->id())
->get()
->contains('ad_title', $value);
);
},
]
However the logic for this validation is likely to be required at multiple places then it's better to define a custom rule class https://laravel.com/docs/8.x/validation#using-rule-objects
Laravel 5.3 and above
use Illuminate\Validation\Rule;
'email' => Rule::unique('ads')->where(function ($query) {
$query->where('user_id', Auth::id());
})
Laravel 9
use Illuminate\Validation\Rule;
Rule::unique('ads')->where(fn ($query) => $query->where('user_id', Auth::id()))

Laravel validate unique if id is the same

I have a table/model that contains multiple albums per user.
Is there a way to say that the column title should be unique, but only for the rows that have the same user_id?
Example: http://pastebin.com/8dvM4a1T
As you can see in the example, the user with the id of 2 has created 2 albums, with the same title. I don't want that to be allowed, that's why I'm wondering if there's a way to deny that with the validator from Laravel?
I tried this, but that did not work.
// Validator
$validator = Validator::make($input, [
'title' => 'required|min:1|max:255|unique:galleries,title,'. Auth::user() -> id .',user_id',
'description' => 'min:1|max:255'
]);
Any help appreciated, thanks.
Your code should be something like:
'title' => 'unique:galleries,title,NULL,id,user_id,'.Auth::user() -> id.'',
Or, you can write a custom rule
Reference here
The approach with the default unique rule does not work because the rule expects the column value to be passed as the third parameter, so in your case it would check if the title column is equal to the Auth::user()->id value which is not what you want.
You can create you own custom validation rule by adding the following code to the boot method of the App\Providers\AppServiceProvider class:
Validator::extend('unique_custom', function ($attribute, $value, $parameters)
{
// Get the parameters passed to the rule
list($table, $field, $field2, $field2Value) = $parameters;
// Check the table and return true only if there are no entries matching
// both the first field name and the user input value as well as
// the second field name and the second field value
return DB::table($table)->where($field, $value)->where($field2, $field2Value)->count() == 0;
});
Now you can use the unique_custom (or you can name it whatever you like) rule like so:
$validator = Validator::make($input, [
'title' => 'required|min:1|max:255|unique_custom:galleries,title,user_id,' . Auth::id(),
'description' => 'min:1|max:255'
]);
The rule expects the parameters to be the following:
the 1st parameter to be the table name, which in this case is galleries
the 2nd parameter to be the field name that is supposed to be unique and for which the value comes from the user input, which in this case is title
the 3rd parameter to be the second field name that will be added to the query conditions, which in this case is user_id
the 4th parameter to be the value of the field name passed as the third parameter
Also you can use Auth::id() since that is the short form of Auth::user()->id.
You can read more about Custom Validation rules in the Laravel Documentation.
Laravel 5.3 and above
use Illuminate\Validation\Rule;
'email' => Rule::unique('galleries')->where(function ($query) {
$query->where('user_id', Auth::id());
})
Laravel 9
use Illuminate\Validation\Rule;
Rule::unique('galleries')->where(fn ($query) => $query->where('user_id', Auth::id()))

Phalcon form sanitize

Is there a way in which one can filter data that is auto-completed in a form generated by VOLT.
Consider the login form: Email/password.
When I edit the HTML (in the broser) and send the email as an array ('name="email[]") I can sanitize it in PHP and 'cast' as en email:
$loginEmail = $this->request->getPost("email",'string');
$loginEmail = $this->filter->sanitize($loginEmail, "email");
in order to prevent other attacks.
But when making the email field an array VOLT generates an error:
"Notice: Array to string conversion in ..."
VOLT form values are populated automatically...
I know I should disable NOTICES in production but still...
How can I treat this by using VOLT?
EDIT
Template sample:
{{ text_field('id':"email","class":"form-control", "size": 32,"placeholder":'Email address') }}
After a var_dump and setting the email string through validation I get at a certain point:
protected '_viewParams' =>
array (size=5)
'title' => string 'Test' (length=5)
'showSlider' => boolean true
'hideUnlogged' => boolean true
'user' => null
'email' => boolean false
BUT the variables are sent to VOLT in an upper layer because it is still set as an ARRAY.
The only viable solution is to make an object or something and get from a config what validation rules to apply to forms (by name) and rewrite the post variable in public/index.php something like this:
if(isset($_POST['email']))
{
$_POST['email'] = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
}
If anyone has a better solution in which this can be done in a controller rather that this or in a service with event handlers...
You can do anything you wish by implementing a custom filter and doing a proper conversion from array to string.
$filter = new \Phalcon\Filter();
//Using an anonymous function
$filter->add('superSanitisedString', function($value) {
if (is_array($value)) {
$value = empty($value) ? '' : reset($value);
}
return (string) $value;
});
//Sanitize with the "superSanitisedString" filter
$filtered = $filter->sanitize($possibleArray, "superSanitisedString");
But… don't bend the stick too much – this is a clear validation job and then sanitisation. Check that the value is a string, if not – ask to provide one. It's easier and smarter to protect your app from invalid inputs than from idiots who provide that input :)
Edit:
You can use a custom volt filter which can be added as a service, implement a class with a static method to return the sanitized value and use it in the template.

Changing filters from Select to simple input

in my filter forms I want to change the default sfWidgetDoctrineChoice to a simple sfWidgetFormFilterInput.
For the relational fields (e.g. UserForm has a field PhoneNumberListId).
What's the purpose?
=> When you have a lot of relational data symfony (to be exactly the DoctrineFormChoice widget) will render a select element containing all(!) possible relations, causing the website to crash.
An example to light things up:
Tables: User, PhonenumberList
Form: UserFilterForm
Basically we would have this code in the UserFilterForm:
$this->setWidgets(array(
'phonenumber_list_id' => new sfWidgetFormDoctrineChoice(array('model' => $this->getRelatedModelName('PhonenumberList'), 'add_empty' => true))));
I change this to:
$this->setWidget('phonenumber_list_id', new sfWidgetFormFilterInput(array('with_empty' => false)));
$this->setValidator('phonenumber_list_id', new sfValidatorSchemaFilter('text', new sfValidatorNumber(array('required' => false))));
What effect does this have on the form rendering?
The formerly select:
<select name="user_filters[phonenumber_list_id]">
Will change to:
<input name="user_filters[phonenumber_list_id][text]" >
Which I causing the following (to me unexplainable) error/exception:
SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
at Doctrine_Connection->execute('SELECT COUNT(*) AS num_results FROM receipt r WHERE r.partner_id IN (?) AND (r.deleted_at IS NULL)', array('text' => 1))
Notice: receipt≘user, partner_id≘phonenumber_list
*the sign "≘" explained over here http://en.wikipedia.org/wiki/Equals_sign (Example "A ≘ B", in words "A is like/is a synonym for B")

Categories